2 use core
::convert
::TryInto
;
7 self, util
, Architecture
, ByteString
, Bytes
, Error
, Export
, FileFlags
, Import
, Object
,
8 ObjectKind
, ReadError
, ReadRef
, SectionIndex
, StringTable
, SymbolIndex
,
10 use crate::{elf, endian, Endian, Endianness, Pod, U32}
;
13 CompressionHeader
, Dyn
, ElfComdat
, ElfComdatIterator
, ElfDynamicRelocationIterator
, ElfSection
,
14 ElfSectionIterator
, ElfSegment
, ElfSegmentIterator
, ElfSymbol
, ElfSymbolIterator
,
15 ElfSymbolTable
, NoteHeader
, ProgramHeader
, Rel
, Rela
, RelocationSections
, SectionHeader
,
16 SectionTable
, Sym
, SymbolTable
,
19 /// A 32-bit ELF object file.
20 pub type ElfFile32
<'data
, Endian
= Endianness
, R
= &'data
[u8]> =
21 ElfFile
<'data
, elf
::FileHeader32
<Endian
>, R
>;
22 /// A 64-bit ELF object file.
23 pub type ElfFile64
<'data
, Endian
= Endianness
, R
= &'data
[u8]> =
24 ElfFile
<'data
, elf
::FileHeader64
<Endian
>, R
>;
26 /// A partially parsed ELF file.
28 /// Most of the functionality of this type is provided by the `Object` trait implementation.
30 pub struct ElfFile
<'data
, Elf
, R
= &'data
[u8]>
35 pub(super) endian
: Elf
::Endian
,
37 pub(super) header
: &'data Elf
,
38 pub(super) segments
: &'data
[Elf
::ProgramHeader
],
39 pub(super) sections
: SectionTable
<'data
, Elf
, R
>,
40 pub(super) relocations
: RelocationSections
,
41 pub(super) symbols
: SymbolTable
<'data
, Elf
, R
>,
42 pub(super) dynamic_symbols
: SymbolTable
<'data
, Elf
, R
>,
45 impl<'data
, Elf
, R
> ElfFile
<'data
, Elf
, R
>
50 /// Parse the raw ELF file data.
51 pub fn parse(data
: R
) -> read
::Result
<Self> {
52 let header
= Elf
::parse(data
)?
;
53 let endian
= header
.endian()?
;
54 let segments
= header
.program_headers(endian
, data
)?
;
55 let sections
= header
.sections(endian
, data
)?
;
56 let symbols
= sections
.symbols(endian
, data
, elf
::SHT_SYMTAB
)?
;
57 // TODO: get dynamic symbols from DT_SYMTAB if there are no sections
58 let dynamic_symbols
= sections
.symbols(endian
, data
, elf
::SHT_DYNSYM
)?
;
59 // The API we provide requires a mapping from section to relocations, so build it now.
60 let relocations
= sections
.relocation_sections(endian
, symbols
.section())?
;
74 /// Returns the endianness.
75 pub fn endian(&self) -> Elf
::Endian
{
79 /// Returns the raw data.
80 pub fn data(&self) -> R
{
84 /// Returns the raw ELF file header.
85 pub fn raw_header(&self) -> &'data Elf
{
89 /// Returns the raw ELF segments.
90 pub fn raw_segments(&self) -> &'data
[Elf
::ProgramHeader
] {
94 fn raw_section_by_name
<'file
>(
97 ) -> Option
<ElfSection
<'data
, 'file
, Elf
, R
>> {
99 .section_by_name(self.endian
, section_name
)
100 .map(|(index
, section
)| ElfSection
{
102 index
: SectionIndex(index
),
107 #[cfg(feature = "compression")]
108 fn zdebug_section_by_name
<'file
>(
111 ) -> Option
<ElfSection
<'data
, 'file
, Elf
, R
>> {
112 if !section_name
.starts_with(b
".debug_") {
115 let mut name
= Vec
::with_capacity(section_name
.len() + 1);
116 name
.extend_from_slice(b
".zdebug_");
117 name
.extend_from_slice(§ion_name
[7..]);
118 self.raw_section_by_name(&name
)
121 #[cfg(not(feature = "compression"))]
122 fn zdebug_section_by_name
<'file
>(
124 _section_name
: &[u8],
125 ) -> Option
<ElfSection
<'data
, 'file
, Elf
, R
>> {
130 impl<'data
, Elf
, R
> read
::private
::Sealed
for ElfFile
<'data
, Elf
, R
>
137 impl<'data
, 'file
, Elf
, R
> Object
<'data
, 'file
> for ElfFile
<'data
, Elf
, R
>
141 R
: 'file
+ ReadRef
<'data
>,
143 type Segment
= ElfSegment
<'data
, 'file
, Elf
, R
>;
144 type SegmentIterator
= ElfSegmentIterator
<'data
, 'file
, Elf
, R
>;
145 type Section
= ElfSection
<'data
, 'file
, Elf
, R
>;
146 type SectionIterator
= ElfSectionIterator
<'data
, 'file
, Elf
, R
>;
147 type Comdat
= ElfComdat
<'data
, 'file
, Elf
, R
>;
148 type ComdatIterator
= ElfComdatIterator
<'data
, 'file
, Elf
, R
>;
149 type Symbol
= ElfSymbol
<'data
, 'file
, Elf
, R
>;
150 type SymbolIterator
= ElfSymbolIterator
<'data
, 'file
, Elf
, R
>;
151 type SymbolTable
= ElfSymbolTable
<'data
, 'file
, Elf
, R
>;
152 type DynamicRelocationIterator
= ElfDynamicRelocationIterator
<'data
, 'file
, Elf
, R
>;
154 fn architecture(&self) -> Architecture
{
156 self.header
.e_machine(self.endian
),
157 self.header
.is_class_64(),
159 (elf
::EM_AARCH64
, _
) => Architecture
::Aarch64
,
160 (elf
::EM_ARM
, _
) => Architecture
::Arm
,
161 (elf
::EM_AVR
, _
) => Architecture
::Avr
,
162 (elf
::EM_BPF
, _
) => Architecture
::Bpf
,
163 (elf
::EM_386
, _
) => Architecture
::I386
,
164 (elf
::EM_X86_64
, false) => Architecture
::X86_64_X32
,
165 (elf
::EM_X86_64
, true) => Architecture
::X86_64
,
166 (elf
::EM_HEXAGON
, _
) => Architecture
::Hexagon
,
167 (elf
::EM_LOONGARCH
, true) => Architecture
::LoongArch64
,
168 (elf
::EM_MIPS
, false) => Architecture
::Mips
,
169 (elf
::EM_MIPS
, true) => Architecture
::Mips64
,
170 (elf
::EM_MSP430
, _
) => Architecture
::Msp430
,
171 (elf
::EM_PPC
, _
) => Architecture
::PowerPc
,
172 (elf
::EM_PPC64
, _
) => Architecture
::PowerPc64
,
173 (elf
::EM_RISCV
, false) => Architecture
::Riscv32
,
174 (elf
::EM_RISCV
, true) => Architecture
::Riscv64
,
175 // This is either s390 or s390x, depending on the ELF class.
176 // We only support the 64-bit variant s390x here.
177 (elf
::EM_S390
, true) => Architecture
::S390x
,
178 (elf
::EM_SPARCV9
, true) => Architecture
::Sparc64
,
179 _
=> Architecture
::Unknown
,
184 fn is_little_endian(&self) -> bool
{
185 self.header
.is_little_endian()
189 fn is_64(&self) -> bool
{
190 self.header
.is_class_64()
193 fn kind(&self) -> ObjectKind
{
194 match self.header
.e_type(self.endian
) {
195 elf
::ET_REL
=> ObjectKind
::Relocatable
,
196 elf
::ET_EXEC
=> ObjectKind
::Executable
,
197 // TODO: check for `DF_1_PIE`?
198 elf
::ET_DYN
=> ObjectKind
::Dynamic
,
199 elf
::ET_CORE
=> ObjectKind
::Core
,
200 _
=> ObjectKind
::Unknown
,
204 fn segments(&'file
self) -> ElfSegmentIterator
<'data
, 'file
, Elf
, R
> {
207 iter
: self.segments
.iter(),
211 fn section_by_name_bytes(
214 ) -> Option
<ElfSection
<'data
, 'file
, Elf
, R
>> {
215 self.raw_section_by_name(section_name
)
216 .or_else(|| self.zdebug_section_by_name(section_name
))
222 ) -> read
::Result
<ElfSection
<'data
, 'file
, Elf
, R
>> {
223 let section
= self.sections
.section(index
)?
;
231 fn sections(&'file
self) -> ElfSectionIterator
<'data
, 'file
, Elf
, R
> {
234 iter
: self.sections
.iter().enumerate(),
238 fn comdats(&'file
self) -> ElfComdatIterator
<'data
, 'file
, Elf
, R
> {
241 iter
: self.sections
.iter().enumerate(),
248 ) -> read
::Result
<ElfSymbol
<'data
, 'file
, Elf
, R
>> {
249 let symbol
= self.symbols
.symbol(index
.0)?
;
252 symbols
: &self.symbols
,
258 fn symbols(&'file
self) -> ElfSymbolIterator
<'data
, 'file
, Elf
, R
> {
261 symbols
: &self.symbols
,
266 fn symbol_table(&'file
self) -> Option
<ElfSymbolTable
<'data
, 'file
, Elf
, R
>> {
267 if self.symbols
.is_empty() {
270 Some(ElfSymbolTable
{
272 symbols
: &self.symbols
,
276 fn dynamic_symbols(&'file
self) -> ElfSymbolIterator
<'data
, 'file
, Elf
, R
> {
279 symbols
: &self.dynamic_symbols
,
284 fn dynamic_symbol_table(&'file
self) -> Option
<ElfSymbolTable
<'data
, 'file
, Elf
, R
>> {
285 if self.dynamic_symbols
.is_empty() {
288 Some(ElfSymbolTable
{
290 symbols
: &self.dynamic_symbols
,
294 fn dynamic_relocations(
296 ) -> Option
<ElfDynamicRelocationIterator
<'data
, 'file
, Elf
, R
>> {
297 Some(ElfDynamicRelocationIterator
{
298 section_index
: SectionIndex(1),
304 /// Get the imported symbols.
305 fn imports(&self) -> read
::Result
<Vec
<Import
<'data
>>> {
306 let mut imports
= Vec
::new();
307 for symbol
in self.dynamic_symbols
.iter() {
308 if symbol
.is_undefined(self.endian
) {
309 let name
= symbol
.name(self.endian
, self.dynamic_symbols
.strings())?
;
310 if !name
.is_empty() {
311 // TODO: use symbol versioning to determine library
312 imports
.push(Import
{
313 name
: ByteString(name
),
314 library
: ByteString(&[]),
322 /// Get the exported symbols.
323 fn exports(&self) -> read
::Result
<Vec
<Export
<'data
>>> {
324 let mut exports
= Vec
::new();
325 for symbol
in self.dynamic_symbols
.iter() {
326 if symbol
.is_definition(self.endian
) {
327 let name
= symbol
.name(self.endian
, self.dynamic_symbols
.strings())?
;
328 let address
= symbol
.st_value(self.endian
).into();
329 exports
.push(Export
{
330 name
: ByteString(name
),
338 fn has_debug_symbols(&self) -> bool
{
339 for section
in self.sections
.iter() {
340 if let Ok(name
) = self.sections
.section_name(self.endian
, section
) {
341 if name
== b
".debug_info" || name
== b
".zdebug_info" {
349 fn build_id(&self) -> read
::Result
<Option
<&'data
[u8]>> {
350 let endian
= self.endian
;
351 // Use section headers if present, otherwise use program headers.
352 if !self.sections
.is_empty() {
353 for section
in self.sections
.iter() {
354 if let Some(mut notes
) = section
.notes(endian
, self.data
)?
{
355 while let Some(note
) = notes
.next()?
{
356 if note
.name() == elf
::ELF_NOTE_GNU
357 && note
.n_type(endian
) == elf
::NT_GNU_BUILD_ID
359 return Ok(Some(note
.desc()));
365 for segment
in self.segments
{
366 if let Some(mut notes
) = segment
.notes(endian
, self.data
)?
{
367 while let Some(note
) = notes
.next()?
{
368 if note
.name() == elf
::ELF_NOTE_GNU
369 && note
.n_type(endian
) == elf
::NT_GNU_BUILD_ID
371 return Ok(Some(note
.desc()));
380 fn gnu_debuglink(&self) -> read
::Result
<Option
<(&'data
[u8], u32)>> {
381 let section
= match self.raw_section_by_name(b
".gnu_debuglink") {
382 Some(section
) => section
,
383 None
=> return Ok(None
),
387 .data(self.endian
, self.data
)
388 .read_error("Invalid ELF .gnu_debuglink section offset or size")
392 .read_error("Missing ELF .gnu_debuglink filename")?
;
393 let crc_offset
= util
::align(filename
.len() + 1, 4);
395 .read_at
::<U32
<_
>>(crc_offset
)
396 .read_error("Missing ELF .gnu_debuglink crc")?
398 Ok(Some((filename
, crc
)))
401 fn gnu_debugaltlink(&self) -> read
::Result
<Option
<(&'data
[u8], &'data
[u8])>> {
402 let section
= match self.raw_section_by_name(b
".gnu_debugaltlink") {
403 Some(section
) => section
,
404 None
=> return Ok(None
),
406 let mut data
= section
408 .data(self.endian
, self.data
)
409 .read_error("Invalid ELF .gnu_debugaltlink section offset or size")
413 .read_error("Missing ELF .gnu_debugaltlink filename")?
;
414 let build_id
= data
.0;
415 Ok(Some((filename
, build_id
)))
418 fn relative_address_base(&self) -> u64 {
422 fn entry(&self) -> u64 {
423 self.header
.e_entry(self.endian
).into()
426 fn flags(&self) -> FileFlags
{
428 os_abi
: self.header
.e_ident().os_abi
,
429 abi_version
: self.header
.e_ident().abi_version
,
430 e_flags
: self.header
.e_flags(self.endian
),
435 /// A trait for generic access to `FileHeader32` and `FileHeader64`.
436 #[allow(missing_docs)]
437 pub trait FileHeader
: Debug
+ Pod
{
438 // Ideally this would be a `u64: From<Word>`, but can't express that.
439 type Word
: Into
<u64>;
440 type Sword
: Into
<i64>;
441 type Endian
: endian
::Endian
;
442 type ProgramHeader
: ProgramHeader
<Elf
= Self, Endian
= Self::Endian
, Word
= Self::Word
>;
443 type SectionHeader
: SectionHeader
<Elf
= Self, Endian
= Self::Endian
, Word
= Self::Word
>;
444 type CompressionHeader
: CompressionHeader
<Endian
= Self::Endian
, Word
= Self::Word
>;
445 type NoteHeader
: NoteHeader
<Endian
= Self::Endian
>;
446 type Dyn
: Dyn
<Endian
= Self::Endian
, Word
= Self::Word
>;
447 type Sym
: Sym
<Endian
= Self::Endian
, Word
= Self::Word
>;
448 type Rel
: Rel
<Endian
= Self::Endian
, Word
= Self::Word
>;
449 type Rela
: Rela
<Endian
= Self::Endian
, Word
= Self::Word
> + From
<Self::Rel
>;
451 /// Return true if this type is a 64-bit header.
453 /// This is a property of the type, not a value in the header data.
454 fn is_type_64(&self) -> bool
;
456 fn e_ident(&self) -> &elf
::Ident
;
457 fn e_type(&self, endian
: Self::Endian
) -> u16;
458 fn e_machine(&self, endian
: Self::Endian
) -> u16;
459 fn e_version(&self, endian
: Self::Endian
) -> u32;
460 fn e_entry(&self, endian
: Self::Endian
) -> Self::Word
;
461 fn e_phoff(&self, endian
: Self::Endian
) -> Self::Word
;
462 fn e_shoff(&self, endian
: Self::Endian
) -> Self::Word
;
463 fn e_flags(&self, endian
: Self::Endian
) -> u32;
464 fn e_ehsize(&self, endian
: Self::Endian
) -> u16;
465 fn e_phentsize(&self, endian
: Self::Endian
) -> u16;
466 fn e_phnum(&self, endian
: Self::Endian
) -> u16;
467 fn e_shentsize(&self, endian
: Self::Endian
) -> u16;
468 fn e_shnum(&self, endian
: Self::Endian
) -> u16;
469 fn e_shstrndx(&self, endian
: Self::Endian
) -> u16;
473 /// Read the file header.
475 /// Also checks that the ident field in the file header is a supported format.
476 fn parse
<'data
, R
: ReadRef
<'data
>>(data
: R
) -> read
::Result
<&'data
Self> {
479 .read_error("Invalid ELF header size or alignment")?
;
480 if !header
.is_supported() {
481 return Err(Error("Unsupported ELF header"));
483 // TODO: Check self.e_ehsize?
487 /// Check that the ident field in the file header is a supported format.
489 /// This checks the magic number, version, class, and endianness.
490 fn is_supported(&self) -> bool
{
491 let ident
= self.e_ident();
492 // TODO: Check self.e_version too? Requires endian though.
493 ident
.magic
== elf
::ELFMAG
494 && (self.is_type_64() || self.is_class_32())
495 && (!self.is_type_64() || self.is_class_64())
496 && (self.is_little_endian() || self.is_big_endian())
497 && ident
.version
== elf
::EV_CURRENT
500 fn is_class_32(&self) -> bool
{
501 self.e_ident().class
== elf
::ELFCLASS32
504 fn is_class_64(&self) -> bool
{
505 self.e_ident().class
== elf
::ELFCLASS64
508 fn is_little_endian(&self) -> bool
{
509 self.e_ident().data
== elf
::ELFDATA2LSB
512 fn is_big_endian(&self) -> bool
{
513 self.e_ident().data
== elf
::ELFDATA2MSB
516 fn endian(&self) -> read
::Result
<Self::Endian
> {
517 Self::Endian
::from_big_endian(self.is_big_endian()).read_error("Unsupported ELF endian")
520 /// Return the first section header, if present.
522 /// Section 0 is a special case because getting the section headers normally
523 /// requires `shnum`, but `shnum` may be in the first section header.
524 fn section_0
<'data
, R
: ReadRef
<'data
>>(
526 endian
: Self::Endian
,
528 ) -> read
::Result
<Option
<&'data
Self::SectionHeader
>> {
529 let shoff
: u64 = self.e_shoff(endian
).into();
531 // No section headers is ok.
534 let shentsize
= usize::from(self.e_shentsize(endian
));
535 if shentsize
!= mem
::size_of
::<Self::SectionHeader
>() {
536 // Section header size must match.
537 return Err(Error("Invalid ELF section header entry size"));
541 .read_error("Invalid ELF section header offset or size")
544 /// Return the `e_phnum` field of the header. Handles extended values.
546 /// Returns `Err` for invalid values.
547 fn phnum
<'data
, R
: ReadRef
<'data
>>(
549 endian
: Self::Endian
,
551 ) -> read
::Result
<usize> {
552 let e_phnum
= self.e_phnum(endian
);
553 if e_phnum
< elf
::PN_XNUM
{
555 } else if let Some(section_0
) = self.section_0(endian
, data
)?
{
556 Ok(section_0
.sh_info(endian
) as usize)
558 // Section 0 must exist if e_phnum overflows.
559 Err(Error("Missing ELF section headers for e_phnum overflow"))
563 /// Return the `e_shnum` field of the header. Handles extended values.
565 /// Returns `Err` for invalid values.
566 fn shnum
<'data
, R
: ReadRef
<'data
>>(
568 endian
: Self::Endian
,
570 ) -> read
::Result
<usize> {
571 let e_shnum
= self.e_shnum(endian
);
574 } else if let Some(section_0
) = self.section_0(endian
, data
)?
{
580 .read_error("Invalid ELF extended e_shnum")
582 // No section headers is ok.
587 /// Return the `e_shstrndx` field of the header. Handles extended values.
589 /// Returns `Err` for invalid values (including if the index is 0).
590 fn shstrndx
<'data
, R
: ReadRef
<'data
>>(
592 endian
: Self::Endian
,
594 ) -> read
::Result
<u32> {
595 let e_shstrndx
= self.e_shstrndx(endian
);
596 let index
= if e_shstrndx
!= elf
::SHN_XINDEX
{
598 } else if let Some(section_0
) = self.section_0(endian
, data
)?
{
599 section_0
.sh_link(endian
)
601 // Section 0 must exist if we're trying to read e_shstrndx.
602 return Err(Error("Missing ELF section headers for e_shstrndx overflow"));
605 return Err(Error("Missing ELF e_shstrndx"));
610 /// Return the slice of program headers.
612 /// Returns `Ok(&[])` if there are no program headers.
613 /// Returns `Err` for invalid values.
614 fn program_headers
<'data
, R
: ReadRef
<'data
>>(
616 endian
: Self::Endian
,
618 ) -> read
::Result
<&'data
[Self::ProgramHeader
]> {
619 let phoff
: u64 = self.e_phoff(endian
).into();
621 // No program headers is ok.
624 let phnum
= self.phnum(endian
, data
)?
;
626 // No program headers is ok.
629 let phentsize
= self.e_phentsize(endian
) as usize;
630 if phentsize
!= mem
::size_of
::<Self::ProgramHeader
>() {
631 // Program header size must match.
632 return Err(Error("Invalid ELF program header entry size"));
634 data
.read_slice_at(phoff
, phnum
)
635 .read_error("Invalid ELF program header size or alignment")
638 /// Return the slice of section headers.
640 /// Returns `Ok(&[])` if there are no section headers.
641 /// Returns `Err` for invalid values.
642 fn section_headers
<'data
, R
: ReadRef
<'data
>>(
644 endian
: Self::Endian
,
646 ) -> read
::Result
<&'data
[Self::SectionHeader
]> {
647 let shoff
: u64 = self.e_shoff(endian
).into();
649 // No section headers is ok.
652 let shnum
= self.shnum(endian
, data
)?
;
654 // No section headers is ok.
657 let shentsize
= usize::from(self.e_shentsize(endian
));
658 if shentsize
!= mem
::size_of
::<Self::SectionHeader
>() {
659 // Section header size must match.
660 return Err(Error("Invalid ELF section header entry size"));
662 data
.read_slice_at(shoff
, shnum
)
663 .read_error("Invalid ELF section header offset/size/alignment")
666 /// Return the string table for the section headers.
667 fn section_strings
<'data
, R
: ReadRef
<'data
>>(
669 endian
: Self::Endian
,
671 sections
: &[Self::SectionHeader
],
672 ) -> read
::Result
<StringTable
<'data
, R
>> {
673 if sections
.is_empty() {
674 return Ok(StringTable
::default());
676 let index
= self.shstrndx(endian
, data
)?
as usize;
677 let shstrtab
= sections
.get(index
).read_error("Invalid ELF e_shstrndx")?
;
678 let strings
= if let Some((shstrtab_offset
, shstrtab_size
)) = shstrtab
.file_range(endian
) {
679 let shstrtab_end
= shstrtab_offset
680 .checked_add(shstrtab_size
)
681 .read_error("Invalid ELF shstrtab size")?
;
682 StringTable
::new(data
, shstrtab_offset
, shstrtab_end
)
684 StringTable
::default()
689 /// Return the section table.
690 fn sections
<'data
, R
: ReadRef
<'data
>>(
692 endian
: Self::Endian
,
694 ) -> read
::Result
<SectionTable
<'data
, Self, R
>> {
695 let sections
= self.section_headers(endian
, data
)?
;
696 let strings
= self.section_strings(endian
, data
, sections
)?
;
697 Ok(SectionTable
::new(sections
, strings
))
700 /// Returns whether this is a mips64el elf file.
701 fn is_mips64el(&self, endian
: Self::Endian
) -> bool
{
702 self.is_class_64() && self.is_little_endian() && self.e_machine(endian
) == elf
::EM_MIPS
706 impl<Endian
: endian
::Endian
> FileHeader
for elf
::FileHeader32
<Endian
> {
709 type Endian
= Endian
;
710 type ProgramHeader
= elf
::ProgramHeader32
<Endian
>;
711 type SectionHeader
= elf
::SectionHeader32
<Endian
>;
712 type CompressionHeader
= elf
::CompressionHeader32
<Endian
>;
713 type NoteHeader
= elf
::NoteHeader32
<Endian
>;
714 type Dyn
= elf
::Dyn32
<Endian
>;
715 type Sym
= elf
::Sym32
<Endian
>;
716 type Rel
= elf
::Rel32
<Endian
>;
717 type Rela
= elf
::Rela32
<Endian
>;
720 fn is_type_64(&self) -> bool
{
725 fn e_ident(&self) -> &elf
::Ident
{
730 fn e_type(&self, endian
: Self::Endian
) -> u16 {
731 self.e_type
.get(endian
)
735 fn e_machine(&self, endian
: Self::Endian
) -> u16 {
736 self.e_machine
.get(endian
)
740 fn e_version(&self, endian
: Self::Endian
) -> u32 {
741 self.e_version
.get(endian
)
745 fn e_entry(&self, endian
: Self::Endian
) -> Self::Word
{
746 self.e_entry
.get(endian
)
750 fn e_phoff(&self, endian
: Self::Endian
) -> Self::Word
{
751 self.e_phoff
.get(endian
)
755 fn e_shoff(&self, endian
: Self::Endian
) -> Self::Word
{
756 self.e_shoff
.get(endian
)
760 fn e_flags(&self, endian
: Self::Endian
) -> u32 {
761 self.e_flags
.get(endian
)
765 fn e_ehsize(&self, endian
: Self::Endian
) -> u16 {
766 self.e_ehsize
.get(endian
)
770 fn e_phentsize(&self, endian
: Self::Endian
) -> u16 {
771 self.e_phentsize
.get(endian
)
775 fn e_phnum(&self, endian
: Self::Endian
) -> u16 {
776 self.e_phnum
.get(endian
)
780 fn e_shentsize(&self, endian
: Self::Endian
) -> u16 {
781 self.e_shentsize
.get(endian
)
785 fn e_shnum(&self, endian
: Self::Endian
) -> u16 {
786 self.e_shnum
.get(endian
)
790 fn e_shstrndx(&self, endian
: Self::Endian
) -> u16 {
791 self.e_shstrndx
.get(endian
)
795 impl<Endian
: endian
::Endian
> FileHeader
for elf
::FileHeader64
<Endian
> {
798 type Endian
= Endian
;
799 type ProgramHeader
= elf
::ProgramHeader64
<Endian
>;
800 type SectionHeader
= elf
::SectionHeader64
<Endian
>;
801 type CompressionHeader
= elf
::CompressionHeader64
<Endian
>;
802 type NoteHeader
= elf
::NoteHeader32
<Endian
>;
803 type Dyn
= elf
::Dyn64
<Endian
>;
804 type Sym
= elf
::Sym64
<Endian
>;
805 type Rel
= elf
::Rel64
<Endian
>;
806 type Rela
= elf
::Rela64
<Endian
>;
809 fn is_type_64(&self) -> bool
{
814 fn e_ident(&self) -> &elf
::Ident
{
819 fn e_type(&self, endian
: Self::Endian
) -> u16 {
820 self.e_type
.get(endian
)
824 fn e_machine(&self, endian
: Self::Endian
) -> u16 {
825 self.e_machine
.get(endian
)
829 fn e_version(&self, endian
: Self::Endian
) -> u32 {
830 self.e_version
.get(endian
)
834 fn e_entry(&self, endian
: Self::Endian
) -> Self::Word
{
835 self.e_entry
.get(endian
)
839 fn e_phoff(&self, endian
: Self::Endian
) -> Self::Word
{
840 self.e_phoff
.get(endian
)
844 fn e_shoff(&self, endian
: Self::Endian
) -> Self::Word
{
845 self.e_shoff
.get(endian
)
849 fn e_flags(&self, endian
: Self::Endian
) -> u32 {
850 self.e_flags
.get(endian
)
854 fn e_ehsize(&self, endian
: Self::Endian
) -> u16 {
855 self.e_ehsize
.get(endian
)
859 fn e_phentsize(&self, endian
: Self::Endian
) -> u16 {
860 self.e_phentsize
.get(endian
)
864 fn e_phnum(&self, endian
: Self::Endian
) -> u16 {
865 self.e_phnum
.get(endian
)
869 fn e_shentsize(&self, endian
: Self::Endian
) -> u16 {
870 self.e_shentsize
.get(endian
)
874 fn e_shnum(&self, endian
: Self::Endian
) -> u16 {
875 self.e_shnum
.get(endian
)
879 fn e_shstrndx(&self, endian
: Self::Endian
) -> u16 {
880 self.e_shstrndx
.get(endian
)