]> git.proxmox.com Git - rustc.git/blame - vendor/goblin/src/elf/compression_header.rs
New upstream version 1.48.0+dfsg1
[rustc.git] / vendor / goblin / src / elf / compression_header.rs
CommitLineData
f035d41b
XL
1macro_rules! elf_compression_header {
2 () => {
3 use plain;
4 // Declare that this is a plain type.
5 unsafe impl plain::Plain for CompressionHeader {}
6
7 impl ::core::fmt::Debug for CompressionHeader {
8 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
9 f.debug_struct("CompressionHeader")
10 .field("ch_type", &self.ch_type)
11 .field("ch_size", &format_args!("0x{:x}", self.ch_size))
12 .field("ch_addralign", &format_args!("0x{:x}", self.ch_addralign))
13 .finish()
14 }
15 }
16 };
17}
18
19/// ZLIB/DEFLATE algorithm.
20pub const ELFCOMPRESS_ZLIB: u32 = 1;
21/// Start of OS-specific.
22pub const ELFCOMPRESS_LOOS: u32 = 0x6000_0000;
23/// End of OS-specific.
24pub const ELFCOMPRESS_HIOS: u32 = 0x6fff_ffff;
25/// Start of processor-specific.
26pub const ELFCOMPRESS_LOPROC: u32 = 0x7000_0000;
27/// End of processor-specific.
28pub const ELFCOMPRESS_HIPROC: u32 = 0x7fff_ffff;
29
30macro_rules! elf_compression_header_std_impl {
31 ($size:ty) => {
32 #[cfg(test)]
33 mod tests {
34 use super::*;
35 #[test]
36 fn size_of() {
37 assert_eq!(::std::mem::size_of::<CompressionHeader>(), SIZEOF_CHDR);
38 }
39 }
40
41 if_alloc! {
42 use crate::elf::compression_header::CompressionHeader as ElfCompressionHeader;
43
44 use plain::Plain;
45
46 if_std! {
47 use crate::error::Result;
48
49 use std::fs::File;
50 use std::io::{Read, Seek};
51 use std::io::SeekFrom::Start;
52 }
53
54 impl From<CompressionHeader> for ElfCompressionHeader {
55 fn from(ch: CompressionHeader) -> Self {
56 ElfCompressionHeader {
57 ch_type: ch.ch_type,
58 ch_size: u64::from(ch.ch_size),
59 ch_addralign: u64::from(ch.ch_addralign),
60 }
61 }
62 }
63
64 impl CompressionHeader {
65 pub fn from_bytes(bytes: &[u8]) -> CompressionHeader {
66 let mut chdr = CompressionHeader::default();
67 chdr.copy_from_bytes(bytes).expect("buffer is too short for header");
68 chdr
69 }
70
71 #[cfg(feature = "std")]
72 pub fn from_fd(fd: &mut File, offset: u64) -> Result<CompressionHeader> {
73 let mut chdr = CompressionHeader::default();
74 fd.seek(Start(offset))?;
75 unsafe {
76 fd.read_exact(plain::as_mut_bytes(&mut chdr))?;
77 }
78 Ok(chdr)
79 }
80 }
81 } // end if_alloc
82 };
83}
84
85#[cfg(feature = "alloc")]
86use scroll::{Pread, Pwrite, SizeWith};
87
88pub mod compression_header32 {
89 pub use crate::elf::compression_header::*;
90
91 #[repr(C)]
92 #[derive(Copy, Clone, Eq, PartialEq, Default)]
93 #[cfg_attr(feature = "alloc", derive(Pread, Pwrite, SizeWith))]
94 /// The compression header is used at the start of SHF_COMPRESSED sections
95 pub struct CompressionHeader {
96 /// Compression format
97 pub ch_type: u32,
98 /// Uncompressed data size
99 pub ch_size: u32,
100 /// Uncompressed data alignment
101 pub ch_addralign: u32,
102 }
103
104 elf_compression_header!();
105
106 pub const SIZEOF_CHDR: usize = 12;
107
108 elf_compression_header_std_impl!(u32);
109
110 if_alloc! {
111 impl From<ElfCompressionHeader> for CompressionHeader {
112 fn from(ch: ElfCompressionHeader) -> Self {
113 CompressionHeader {
114 ch_type: ch.ch_type,
115 ch_size: ch.ch_size as u32,
116 ch_addralign: ch.ch_addralign as u32,
117 }
118 }
119 }
120 }
121}
122
123pub mod compression_header64 {
124 pub use crate::elf::compression_header::*;
125
126 #[repr(C)]
127 #[derive(Copy, Clone, Eq, PartialEq, Default)]
128 #[cfg_attr(feature = "alloc", derive(Pread, Pwrite, SizeWith))]
129 /// The compression header is used at the start of SHF_COMPRESSED sections
130 pub struct CompressionHeader {
131 /// Compression format
132 pub ch_type: u32,
133 pub ch_reserved: u32,
134 /// Uncompressed data size
135 pub ch_size: u64,
136 /// Uncompressed data alignment
137 pub ch_addralign: u64,
138 }
139
140 elf_compression_header!();
141
142 pub const SIZEOF_CHDR: usize = 24;
143
144 elf_compression_header_std_impl!(u64);
145
146 if_alloc! {
147 impl From<ElfCompressionHeader> for CompressionHeader {
148 fn from(ch: ElfCompressionHeader) -> Self {
149 CompressionHeader {
150 ch_type: ch.ch_type,
151 ch_reserved: 0,
152 ch_size: ch.ch_size as u64,
153 ch_addralign: ch.ch_addralign as u64,
154 }
155 }
156 }
157 }
158}
159
160///////////////////////////////
161// Std/analysis/Unified Structs
162///////////////////////////////
163
164if_alloc! {
165 #[cfg(feature = "endian_fd")]
166 use crate::error;
167 use core::fmt;
168 use core::result;
169 use scroll::ctx;
170 use crate::container::{Container, Ctx};
171
172 #[derive(Default, PartialEq, Clone)]
173 /// A unified CompressionHeader - convertable to and from 32-bit and 64-bit variants
174 pub struct CompressionHeader {
175 /// Compression format
176 pub ch_type: u32,
177 /// Uncompressed data size
178 pub ch_size: u64,
179 /// Uncompressed data alignment
180 pub ch_addralign: u64,
181 }
182
183 impl CompressionHeader {
184 /// Return the size of the underlying compression header, given a `container`
185 #[inline]
186 pub fn size(ctx: Ctx) -> usize {
187 use scroll::ctx::SizeWith;
188 Self::size_with(&ctx)
189 }
190 pub fn new() -> Self {
191 CompressionHeader {
192 ch_type: 0,
193 ch_size: 0,
194 ch_addralign: 2 << 8,
195 }
196 }
197 /// Parse a compression header from `bytes` at `offset`, using the given `ctx`
198 #[cfg(feature = "endian_fd")]
199 pub fn parse(bytes: &[u8], mut offset: usize, ctx: Ctx) -> error::Result<CompressionHeader> {
200 use scroll::Pread;
201 bytes.gread_with(&mut offset, ctx)
202 }
203 }
204
205 impl fmt::Debug for CompressionHeader {
206 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
207 f.debug_struct("CompressionHeader")
208 .field("ch_type", &self.ch_type)
209 .field("ch_size", &format_args!("0x{:x}", self.ch_size))
210 .field("ch_addralign", &format_args!("0x{:x}", self.ch_addralign))
211 .finish()
212 }
213 }
214
215 impl ctx::SizeWith<Ctx> for CompressionHeader {
216 fn size_with( &Ctx { container, .. }: &Ctx) -> usize {
217 match container {
218 Container::Little => {
219 compression_header32::SIZEOF_CHDR
220 },
221 Container::Big => {
222 compression_header64::SIZEOF_CHDR
223 },
224 }
225 }
226 }
227
228 impl<'a> ctx::TryFromCtx<'a, Ctx> for CompressionHeader {
229 type Error = crate::error::Error;
230 fn try_from_ctx(bytes: &'a [u8], Ctx {container, le}: Ctx) -> result::Result<(Self, usize), Self::Error> {
231 use scroll::Pread;
232 let res = match container {
233 Container::Little => {
234 (bytes.pread_with::<compression_header32::CompressionHeader>(0, le)?.into(), compression_header32::SIZEOF_CHDR)
235 },
236 Container::Big => {
237 (bytes.pread_with::<compression_header64::CompressionHeader>(0, le)?.into(), compression_header64::SIZEOF_CHDR)
238 }
239 };
240 Ok(res)
241 }
242 }
243
244 impl ctx::TryIntoCtx<Ctx> for CompressionHeader {
245 type Error = crate::error::Error;
246 fn try_into_ctx(self, bytes: &mut [u8], Ctx {container, le}: Ctx) -> result::Result<usize, Self::Error> {
247 use scroll::Pwrite;
248 match container {
249 Container::Little => {
250 let chdr: compression_header32::CompressionHeader = self.into();
251 Ok(bytes.pwrite_with(chdr, 0, le)?)
252 },
253 Container::Big => {
254 let chdr: compression_header64::CompressionHeader = self.into();
255 Ok(bytes.pwrite_with(chdr, 0, le)?)
256 }
257 }
258 }
259 }
260 impl ctx::IntoCtx<Ctx> for CompressionHeader {
261 fn into_ctx(self, bytes: &mut [u8], Ctx {container, le}: Ctx) {
262 use scroll::Pwrite;
263 match container {
264 Container::Little => {
265 let chdr: compression_header32::CompressionHeader = self.into();
266 bytes.pwrite_with(chdr, 0, le).unwrap();
267 },
268 Container::Big => {
269 let chdr: compression_header64::CompressionHeader = self.into();
270 bytes.pwrite_with(chdr, 0, le).unwrap();
271 }
272 }
273 }
274 }
275} // end if_alloc