1 macro_rules
! elf_compression_header
{
4 // Declare that this is a plain type.
5 unsafe impl plain
::Plain
for CompressionHeader {}
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
))
19 /// ZLIB/DEFLATE algorithm.
20 pub const ELFCOMPRESS_ZLIB
: u32 = 1;
21 /// Start of OS-specific.
22 pub const ELFCOMPRESS_LOOS
: u32 = 0x6000_0000;
23 /// End of OS-specific.
24 pub const ELFCOMPRESS_HIOS
: u32 = 0x6fff_ffff;
25 /// Start of processor-specific.
26 pub const ELFCOMPRESS_LOPROC
: u32 = 0x7000_0000;
27 /// End of processor-specific.
28 pub const ELFCOMPRESS_HIPROC
: u32 = 0x7fff_ffff;
30 macro_rules
! elf_compression_header_std_impl
{
37 assert_eq
!(::std
::mem
::size_of
::<CompressionHeader
>(), SIZEOF_CHDR
);
42 use crate::elf
::compression_header
::CompressionHeader
as ElfCompressionHeader
;
47 use crate::error
::Result
;
50 use std
::io
::{Read, Seek}
;
51 use std
::io
::SeekFrom
::Start
;
54 impl From
<CompressionHeader
> for ElfCompressionHeader
{
55 fn from(ch
: CompressionHeader
) -> Self {
56 ElfCompressionHeader
{
58 ch_size
: u64::from(ch
.ch_size
),
59 ch_addralign
: u64::from(ch
.ch_addralign
),
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");
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
))?
;
76 fd
.read_exact(plain
::as_mut_bytes(&mut chdr
))?
;
85 #[cfg(feature = "alloc")]
86 use scroll
::{Pread, Pwrite, SizeWith}
;
88 pub mod compression_header32
{
89 pub use crate::elf
::compression_header
::*;
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
98 /// Uncompressed data size
100 /// Uncompressed data alignment
101 pub ch_addralign
: u32,
104 elf_compression_header
!();
106 pub const SIZEOF_CHDR
: usize = 12;
108 elf_compression_header_std_impl
!(u32);
111 impl From
<ElfCompressionHeader
> for CompressionHeader
{
112 fn from(ch
: ElfCompressionHeader
) -> Self {
115 ch_size
: ch
.ch_size
as u32,
116 ch_addralign
: ch
.ch_addralign
as u32,
123 pub mod compression_header64
{
124 pub use crate::elf
::compression_header
::*;
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
133 pub ch_reserved
: u32,
134 /// Uncompressed data size
136 /// Uncompressed data alignment
137 pub ch_addralign
: u64,
140 elf_compression_header
!();
142 pub const SIZEOF_CHDR
: usize = 24;
144 elf_compression_header_std_impl
!(u64);
147 impl From
<ElfCompressionHeader
> for CompressionHeader
{
148 fn from(ch
: ElfCompressionHeader
) -> Self {
152 ch_size
: ch
.ch_size
as u64,
153 ch_addralign
: ch
.ch_addralign
as u64,
160 ///////////////////////////////
161 // Std/analysis/Unified Structs
162 ///////////////////////////////
165 #[cfg(feature = "endian_fd")]
170 use crate::container
::{Container, Ctx}
;
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
177 /// Uncompressed data size
179 /// Uncompressed data alignment
180 pub ch_addralign
: u64,
183 impl CompressionHeader
{
184 /// Return the size of the underlying compression header, given a `container`
186 pub fn size(ctx
: Ctx
) -> usize {
187 use scroll
::ctx
::SizeWith
;
188 Self::size_with(&ctx
)
190 pub fn new() -> Self {
194 ch_addralign
: 2 << 8,
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
> {
201 bytes
.gread_with(&mut offset
, ctx
)
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
))
215 impl ctx
::SizeWith
<Ctx
> for CompressionHeader
{
216 fn size_with( &Ctx { container, .. }
: &Ctx
) -> usize {
218 Container
::Little
=> {
219 compression_header32
::SIZEOF_CHDR
222 compression_header64
::SIZEOF_CHDR
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
> {
232 let res
= match container
{
233 Container
::Little
=> {
234 (bytes
.pread_with
::<compression_header32
::CompressionHeader
>(0, le
)?
.into(), compression_header32
::SIZEOF_CHDR
)
237 (bytes
.pread_with
::<compression_header64
::CompressionHeader
>(0, le
)?
.into(), compression_header64
::SIZEOF_CHDR
)
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
> {
249 Container
::Little
=> {
250 let chdr
: compression_header32
::CompressionHeader
= self.into();
251 Ok(bytes
.pwrite_with(chdr
, 0, le
)?
)
254 let chdr
: compression_header64
::CompressionHeader
= self.into();
255 Ok(bytes
.pwrite_with(chdr
, 0, le
)?
)
260 impl ctx
::IntoCtx
<Ctx
> for CompressionHeader
{
261 fn into_ctx(self, bytes
: &mut [u8], Ctx {container, le}
: Ctx
) {
264 Container
::Little
=> {
265 let chdr
: compression_header32
::CompressionHeader
= self.into();
266 bytes
.pwrite_with(chdr
, 0, le
).unwrap();
269 let chdr
: compression_header64
::CompressionHeader
= self.into();
270 bytes
.pwrite_with(chdr
, 0, le
).unwrap();