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
, true) => Architecture
::Aarch64
,
160 (elf
::EM_AARCH64
, false) => Architecture
::Aarch64_Ilp32
,
161 (elf
::EM_ARM
, _
) => Architecture
::Arm
,
162 (elf
::EM_AVR
, _
) => Architecture
::Avr
,
163 (elf
::EM_BPF
, _
) => Architecture
::Bpf
,
164 (elf
::EM_386
, _
) => Architecture
::I386
,
165 (elf
::EM_X86_64
, false) => Architecture
::X86_64_X32
,
166 (elf
::EM_X86_64
, true) => Architecture
::X86_64
,
167 (elf
::EM_HEXAGON
, _
) => Architecture
::Hexagon
,
168 (elf
::EM_LOONGARCH
, true) => Architecture
::LoongArch64
,
169 (elf
::EM_MIPS
, false) => Architecture
::Mips
,
170 (elf
::EM_MIPS
, true) => Architecture
::Mips64
,
171 (elf
::EM_MSP430
, _
) => Architecture
::Msp430
,
172 (elf
::EM_PPC
, _
) => Architecture
::PowerPc
,
173 (elf
::EM_PPC64
, _
) => Architecture
::PowerPc64
,
174 (elf
::EM_RISCV
, false) => Architecture
::Riscv32
,
175 (elf
::EM_RISCV
, true) => Architecture
::Riscv64
,
176 // This is either s390 or s390x, depending on the ELF class.
177 // We only support the 64-bit variant s390x here.
178 (elf
::EM_S390
, true) => Architecture
::S390x
,
179 (elf
::EM_SBF
, _
) => Architecture
::Sbf
,
180 (elf
::EM_SPARCV9
, true) => Architecture
::Sparc64
,
181 (elf
::EM_XTENSA
, false) => Architecture
::Xtensa
,
182 _
=> Architecture
::Unknown
,
187 fn is_little_endian(&self) -> bool
{
188 self.header
.is_little_endian()
192 fn is_64(&self) -> bool
{
193 self.header
.is_class_64()
196 fn kind(&self) -> ObjectKind
{
197 match self.header
.e_type(self.endian
) {
198 elf
::ET_REL
=> ObjectKind
::Relocatable
,
199 elf
::ET_EXEC
=> ObjectKind
::Executable
,
200 // TODO: check for `DF_1_PIE`?
201 elf
::ET_DYN
=> ObjectKind
::Dynamic
,
202 elf
::ET_CORE
=> ObjectKind
::Core
,
203 _
=> ObjectKind
::Unknown
,
207 fn segments(&'file
self) -> ElfSegmentIterator
<'data
, 'file
, Elf
, R
> {
210 iter
: self.segments
.iter(),
214 fn section_by_name_bytes(
217 ) -> Option
<ElfSection
<'data
, 'file
, Elf
, R
>> {
218 self.raw_section_by_name(section_name
)
219 .or_else(|| self.zdebug_section_by_name(section_name
))
225 ) -> read
::Result
<ElfSection
<'data
, 'file
, Elf
, R
>> {
226 let section
= self.sections
.section(index
)?
;
234 fn sections(&'file
self) -> ElfSectionIterator
<'data
, 'file
, Elf
, R
> {
237 iter
: self.sections
.iter().enumerate(),
241 fn comdats(&'file
self) -> ElfComdatIterator
<'data
, 'file
, Elf
, R
> {
244 iter
: self.sections
.iter().enumerate(),
251 ) -> read
::Result
<ElfSymbol
<'data
, 'file
, Elf
, R
>> {
252 let symbol
= self.symbols
.symbol(index
.0)?
;
255 symbols
: &self.symbols
,
261 fn symbols(&'file
self) -> ElfSymbolIterator
<'data
, 'file
, Elf
, R
> {
264 symbols
: &self.symbols
,
269 fn symbol_table(&'file
self) -> Option
<ElfSymbolTable
<'data
, 'file
, Elf
, R
>> {
270 if self.symbols
.is_empty() {
273 Some(ElfSymbolTable
{
275 symbols
: &self.symbols
,
279 fn dynamic_symbols(&'file
self) -> ElfSymbolIterator
<'data
, 'file
, Elf
, R
> {
282 symbols
: &self.dynamic_symbols
,
287 fn dynamic_symbol_table(&'file
self) -> Option
<ElfSymbolTable
<'data
, 'file
, Elf
, R
>> {
288 if self.dynamic_symbols
.is_empty() {
291 Some(ElfSymbolTable
{
293 symbols
: &self.dynamic_symbols
,
297 fn dynamic_relocations(
299 ) -> Option
<ElfDynamicRelocationIterator
<'data
, 'file
, Elf
, R
>> {
300 Some(ElfDynamicRelocationIterator
{
301 section_index
: SectionIndex(1),
307 /// Get the imported symbols.
308 fn imports(&self) -> read
::Result
<Vec
<Import
<'data
>>> {
309 let mut imports
= Vec
::new();
310 for symbol
in self.dynamic_symbols
.iter() {
311 if symbol
.is_undefined(self.endian
) {
312 let name
= symbol
.name(self.endian
, self.dynamic_symbols
.strings())?
;
313 if !name
.is_empty() {
314 // TODO: use symbol versioning to determine library
315 imports
.push(Import
{
316 name
: ByteString(name
),
317 library
: ByteString(&[]),
325 /// Get the exported symbols.
326 fn exports(&self) -> read
::Result
<Vec
<Export
<'data
>>> {
327 let mut exports
= Vec
::new();
328 for symbol
in self.dynamic_symbols
.iter() {
329 if symbol
.is_definition(self.endian
) {
330 let name
= symbol
.name(self.endian
, self.dynamic_symbols
.strings())?
;
331 let address
= symbol
.st_value(self.endian
).into();
332 exports
.push(Export
{
333 name
: ByteString(name
),
341 fn has_debug_symbols(&self) -> bool
{
342 for section
in self.sections
.iter() {
343 if let Ok(name
) = self.sections
.section_name(self.endian
, section
) {
344 if name
== b
".debug_info" || name
== b
".zdebug_info" {
352 fn build_id(&self) -> read
::Result
<Option
<&'data
[u8]>> {
353 let endian
= self.endian
;
354 // Use section headers if present, otherwise use program headers.
355 if !self.sections
.is_empty() {
356 for section
in self.sections
.iter() {
357 if let Some(mut notes
) = section
.notes(endian
, self.data
)?
{
358 while let Some(note
) = notes
.next()?
{
359 if note
.name() == elf
::ELF_NOTE_GNU
360 && note
.n_type(endian
) == elf
::NT_GNU_BUILD_ID
362 return Ok(Some(note
.desc()));
368 for segment
in self.segments
{
369 if let Some(mut notes
) = segment
.notes(endian
, self.data
)?
{
370 while let Some(note
) = notes
.next()?
{
371 if note
.name() == elf
::ELF_NOTE_GNU
372 && note
.n_type(endian
) == elf
::NT_GNU_BUILD_ID
374 return Ok(Some(note
.desc()));
383 fn gnu_debuglink(&self) -> read
::Result
<Option
<(&'data
[u8], u32)>> {
384 let section
= match self.raw_section_by_name(b
".gnu_debuglink") {
385 Some(section
) => section
,
386 None
=> return Ok(None
),
390 .data(self.endian
, self.data
)
391 .read_error("Invalid ELF .gnu_debuglink section offset or size")
395 .read_error("Missing ELF .gnu_debuglink filename")?
;
396 let crc_offset
= util
::align(filename
.len() + 1, 4);
398 .read_at
::<U32
<_
>>(crc_offset
)
399 .read_error("Missing ELF .gnu_debuglink crc")?
401 Ok(Some((filename
, crc
)))
404 fn gnu_debugaltlink(&self) -> read
::Result
<Option
<(&'data
[u8], &'data
[u8])>> {
405 let section
= match self.raw_section_by_name(b
".gnu_debugaltlink") {
406 Some(section
) => section
,
407 None
=> return Ok(None
),
409 let mut data
= section
411 .data(self.endian
, self.data
)
412 .read_error("Invalid ELF .gnu_debugaltlink section offset or size")
416 .read_error("Missing ELF .gnu_debugaltlink filename")?
;
417 let build_id
= data
.0;
418 Ok(Some((filename
, build_id
)))
421 fn relative_address_base(&self) -> u64 {
425 fn entry(&self) -> u64 {
426 self.header
.e_entry(self.endian
).into()
429 fn flags(&self) -> FileFlags
{
431 os_abi
: self.header
.e_ident().os_abi
,
432 abi_version
: self.header
.e_ident().abi_version
,
433 e_flags
: self.header
.e_flags(self.endian
),
438 /// A trait for generic access to `FileHeader32` and `FileHeader64`.
439 #[allow(missing_docs)]
440 pub trait FileHeader
: Debug
+ Pod
{
441 // Ideally this would be a `u64: From<Word>`, but can't express that.
442 type Word
: Into
<u64>;
443 type Sword
: Into
<i64>;
444 type Endian
: endian
::Endian
;
445 type ProgramHeader
: ProgramHeader
<Elf
= Self, Endian
= Self::Endian
, Word
= Self::Word
>;
446 type SectionHeader
: SectionHeader
<Elf
= Self, Endian
= Self::Endian
, Word
= Self::Word
>;
447 type CompressionHeader
: CompressionHeader
<Endian
= Self::Endian
, Word
= Self::Word
>;
448 type NoteHeader
: NoteHeader
<Endian
= Self::Endian
>;
449 type Dyn
: Dyn
<Endian
= Self::Endian
, Word
= Self::Word
>;
450 type Sym
: Sym
<Endian
= Self::Endian
, Word
= Self::Word
>;
451 type Rel
: Rel
<Endian
= Self::Endian
, Word
= Self::Word
>;
452 type Rela
: Rela
<Endian
= Self::Endian
, Word
= Self::Word
> + From
<Self::Rel
>;
454 /// Return true if this type is a 64-bit header.
456 /// This is a property of the type, not a value in the header data.
457 fn is_type_64(&self) -> bool
;
459 fn e_ident(&self) -> &elf
::Ident
;
460 fn e_type(&self, endian
: Self::Endian
) -> u16;
461 fn e_machine(&self, endian
: Self::Endian
) -> u16;
462 fn e_version(&self, endian
: Self::Endian
) -> u32;
463 fn e_entry(&self, endian
: Self::Endian
) -> Self::Word
;
464 fn e_phoff(&self, endian
: Self::Endian
) -> Self::Word
;
465 fn e_shoff(&self, endian
: Self::Endian
) -> Self::Word
;
466 fn e_flags(&self, endian
: Self::Endian
) -> u32;
467 fn e_ehsize(&self, endian
: Self::Endian
) -> u16;
468 fn e_phentsize(&self, endian
: Self::Endian
) -> u16;
469 fn e_phnum(&self, endian
: Self::Endian
) -> u16;
470 fn e_shentsize(&self, endian
: Self::Endian
) -> u16;
471 fn e_shnum(&self, endian
: Self::Endian
) -> u16;
472 fn e_shstrndx(&self, endian
: Self::Endian
) -> u16;
476 /// Read the file header.
478 /// Also checks that the ident field in the file header is a supported format.
479 fn parse
<'data
, R
: ReadRef
<'data
>>(data
: R
) -> read
::Result
<&'data
Self> {
482 .read_error("Invalid ELF header size or alignment")?
;
483 if !header
.is_supported() {
484 return Err(Error("Unsupported ELF header"));
486 // TODO: Check self.e_ehsize?
490 /// Check that the ident field in the file header is a supported format.
492 /// This checks the magic number, version, class, and endianness.
493 fn is_supported(&self) -> bool
{
494 let ident
= self.e_ident();
495 // TODO: Check self.e_version too? Requires endian though.
496 ident
.magic
== elf
::ELFMAG
497 && (self.is_type_64() || self.is_class_32())
498 && (!self.is_type_64() || self.is_class_64())
499 && (self.is_little_endian() || self.is_big_endian())
500 && ident
.version
== elf
::EV_CURRENT
503 fn is_class_32(&self) -> bool
{
504 self.e_ident().class
== elf
::ELFCLASS32
507 fn is_class_64(&self) -> bool
{
508 self.e_ident().class
== elf
::ELFCLASS64
511 fn is_little_endian(&self) -> bool
{
512 self.e_ident().data
== elf
::ELFDATA2LSB
515 fn is_big_endian(&self) -> bool
{
516 self.e_ident().data
== elf
::ELFDATA2MSB
519 fn endian(&self) -> read
::Result
<Self::Endian
> {
520 Self::Endian
::from_big_endian(self.is_big_endian()).read_error("Unsupported ELF endian")
523 /// Return the first section header, if present.
525 /// Section 0 is a special case because getting the section headers normally
526 /// requires `shnum`, but `shnum` may be in the first section header.
527 fn section_0
<'data
, R
: ReadRef
<'data
>>(
529 endian
: Self::Endian
,
531 ) -> read
::Result
<Option
<&'data
Self::SectionHeader
>> {
532 let shoff
: u64 = self.e_shoff(endian
).into();
534 // No section headers is ok.
537 let shentsize
= usize::from(self.e_shentsize(endian
));
538 if shentsize
!= mem
::size_of
::<Self::SectionHeader
>() {
539 // Section header size must match.
540 return Err(Error("Invalid ELF section header entry size"));
544 .read_error("Invalid ELF section header offset or size")
547 /// Return the `e_phnum` field of the header. Handles extended values.
549 /// Returns `Err` for invalid values.
550 fn phnum
<'data
, R
: ReadRef
<'data
>>(
552 endian
: Self::Endian
,
554 ) -> read
::Result
<usize> {
555 let e_phnum
= self.e_phnum(endian
);
556 if e_phnum
< elf
::PN_XNUM
{
558 } else if let Some(section_0
) = self.section_0(endian
, data
)?
{
559 Ok(section_0
.sh_info(endian
) as usize)
561 // Section 0 must exist if e_phnum overflows.
562 Err(Error("Missing ELF section headers for e_phnum overflow"))
566 /// Return the `e_shnum` field of the header. Handles extended values.
568 /// Returns `Err` for invalid values.
569 fn shnum
<'data
, R
: ReadRef
<'data
>>(
571 endian
: Self::Endian
,
573 ) -> read
::Result
<usize> {
574 let e_shnum
= self.e_shnum(endian
);
577 } else if let Some(section_0
) = self.section_0(endian
, data
)?
{
583 .read_error("Invalid ELF extended e_shnum")
585 // No section headers is ok.
590 /// Return the `e_shstrndx` field of the header. Handles extended values.
592 /// Returns `Err` for invalid values (including if the index is 0).
593 fn shstrndx
<'data
, R
: ReadRef
<'data
>>(
595 endian
: Self::Endian
,
597 ) -> read
::Result
<u32> {
598 let e_shstrndx
= self.e_shstrndx(endian
);
599 let index
= if e_shstrndx
!= elf
::SHN_XINDEX
{
601 } else if let Some(section_0
) = self.section_0(endian
, data
)?
{
602 section_0
.sh_link(endian
)
604 // Section 0 must exist if we're trying to read e_shstrndx.
605 return Err(Error("Missing ELF section headers for e_shstrndx overflow"));
608 return Err(Error("Missing ELF e_shstrndx"));
613 /// Return the slice of program headers.
615 /// Returns `Ok(&[])` if there are no program headers.
616 /// Returns `Err` for invalid values.
617 fn program_headers
<'data
, R
: ReadRef
<'data
>>(
619 endian
: Self::Endian
,
621 ) -> read
::Result
<&'data
[Self::ProgramHeader
]> {
622 let phoff
: u64 = self.e_phoff(endian
).into();
624 // No program headers is ok.
627 let phnum
= self.phnum(endian
, data
)?
;
629 // No program headers is ok.
632 let phentsize
= self.e_phentsize(endian
) as usize;
633 if phentsize
!= mem
::size_of
::<Self::ProgramHeader
>() {
634 // Program header size must match.
635 return Err(Error("Invalid ELF program header entry size"));
637 data
.read_slice_at(phoff
, phnum
)
638 .read_error("Invalid ELF program header size or alignment")
641 /// Return the slice of section headers.
643 /// Returns `Ok(&[])` if there are no section headers.
644 /// Returns `Err` for invalid values.
645 fn section_headers
<'data
, R
: ReadRef
<'data
>>(
647 endian
: Self::Endian
,
649 ) -> read
::Result
<&'data
[Self::SectionHeader
]> {
650 let shoff
: u64 = self.e_shoff(endian
).into();
652 // No section headers is ok.
655 let shnum
= self.shnum(endian
, data
)?
;
657 // No section headers is ok.
660 let shentsize
= usize::from(self.e_shentsize(endian
));
661 if shentsize
!= mem
::size_of
::<Self::SectionHeader
>() {
662 // Section header size must match.
663 return Err(Error("Invalid ELF section header entry size"));
665 data
.read_slice_at(shoff
, shnum
)
666 .read_error("Invalid ELF section header offset/size/alignment")
669 /// Return the string table for the section headers.
670 fn section_strings
<'data
, R
: ReadRef
<'data
>>(
672 endian
: Self::Endian
,
674 sections
: &[Self::SectionHeader
],
675 ) -> read
::Result
<StringTable
<'data
, R
>> {
676 if sections
.is_empty() {
677 return Ok(StringTable
::default());
679 let index
= self.shstrndx(endian
, data
)?
as usize;
680 let shstrtab
= sections
.get(index
).read_error("Invalid ELF e_shstrndx")?
;
681 let strings
= if let Some((shstrtab_offset
, shstrtab_size
)) = shstrtab
.file_range(endian
) {
682 let shstrtab_end
= shstrtab_offset
683 .checked_add(shstrtab_size
)
684 .read_error("Invalid ELF shstrtab size")?
;
685 StringTable
::new(data
, shstrtab_offset
, shstrtab_end
)
687 StringTable
::default()
692 /// Return the section table.
693 fn sections
<'data
, R
: ReadRef
<'data
>>(
695 endian
: Self::Endian
,
697 ) -> read
::Result
<SectionTable
<'data
, Self, R
>> {
698 let sections
= self.section_headers(endian
, data
)?
;
699 let strings
= self.section_strings(endian
, data
, sections
)?
;
700 Ok(SectionTable
::new(sections
, strings
))
703 /// Returns whether this is a mips64el elf file.
704 fn is_mips64el(&self, endian
: Self::Endian
) -> bool
{
705 self.is_class_64() && self.is_little_endian() && self.e_machine(endian
) == elf
::EM_MIPS
709 impl<Endian
: endian
::Endian
> FileHeader
for elf
::FileHeader32
<Endian
> {
712 type Endian
= Endian
;
713 type ProgramHeader
= elf
::ProgramHeader32
<Endian
>;
714 type SectionHeader
= elf
::SectionHeader32
<Endian
>;
715 type CompressionHeader
= elf
::CompressionHeader32
<Endian
>;
716 type NoteHeader
= elf
::NoteHeader32
<Endian
>;
717 type Dyn
= elf
::Dyn32
<Endian
>;
718 type Sym
= elf
::Sym32
<Endian
>;
719 type Rel
= elf
::Rel32
<Endian
>;
720 type Rela
= elf
::Rela32
<Endian
>;
723 fn is_type_64(&self) -> bool
{
728 fn e_ident(&self) -> &elf
::Ident
{
733 fn e_type(&self, endian
: Self::Endian
) -> u16 {
734 self.e_type
.get(endian
)
738 fn e_machine(&self, endian
: Self::Endian
) -> u16 {
739 self.e_machine
.get(endian
)
743 fn e_version(&self, endian
: Self::Endian
) -> u32 {
744 self.e_version
.get(endian
)
748 fn e_entry(&self, endian
: Self::Endian
) -> Self::Word
{
749 self.e_entry
.get(endian
)
753 fn e_phoff(&self, endian
: Self::Endian
) -> Self::Word
{
754 self.e_phoff
.get(endian
)
758 fn e_shoff(&self, endian
: Self::Endian
) -> Self::Word
{
759 self.e_shoff
.get(endian
)
763 fn e_flags(&self, endian
: Self::Endian
) -> u32 {
764 self.e_flags
.get(endian
)
768 fn e_ehsize(&self, endian
: Self::Endian
) -> u16 {
769 self.e_ehsize
.get(endian
)
773 fn e_phentsize(&self, endian
: Self::Endian
) -> u16 {
774 self.e_phentsize
.get(endian
)
778 fn e_phnum(&self, endian
: Self::Endian
) -> u16 {
779 self.e_phnum
.get(endian
)
783 fn e_shentsize(&self, endian
: Self::Endian
) -> u16 {
784 self.e_shentsize
.get(endian
)
788 fn e_shnum(&self, endian
: Self::Endian
) -> u16 {
789 self.e_shnum
.get(endian
)
793 fn e_shstrndx(&self, endian
: Self::Endian
) -> u16 {
794 self.e_shstrndx
.get(endian
)
798 impl<Endian
: endian
::Endian
> FileHeader
for elf
::FileHeader64
<Endian
> {
801 type Endian
= Endian
;
802 type ProgramHeader
= elf
::ProgramHeader64
<Endian
>;
803 type SectionHeader
= elf
::SectionHeader64
<Endian
>;
804 type CompressionHeader
= elf
::CompressionHeader64
<Endian
>;
805 type NoteHeader
= elf
::NoteHeader32
<Endian
>;
806 type Dyn
= elf
::Dyn64
<Endian
>;
807 type Sym
= elf
::Sym64
<Endian
>;
808 type Rel
= elf
::Rel64
<Endian
>;
809 type Rela
= elf
::Rela64
<Endian
>;
812 fn is_type_64(&self) -> bool
{
817 fn e_ident(&self) -> &elf
::Ident
{
822 fn e_type(&self, endian
: Self::Endian
) -> u16 {
823 self.e_type
.get(endian
)
827 fn e_machine(&self, endian
: Self::Endian
) -> u16 {
828 self.e_machine
.get(endian
)
832 fn e_version(&self, endian
: Self::Endian
) -> u32 {
833 self.e_version
.get(endian
)
837 fn e_entry(&self, endian
: Self::Endian
) -> Self::Word
{
838 self.e_entry
.get(endian
)
842 fn e_phoff(&self, endian
: Self::Endian
) -> Self::Word
{
843 self.e_phoff
.get(endian
)
847 fn e_shoff(&self, endian
: Self::Endian
) -> Self::Word
{
848 self.e_shoff
.get(endian
)
852 fn e_flags(&self, endian
: Self::Endian
) -> u32 {
853 self.e_flags
.get(endian
)
857 fn e_ehsize(&self, endian
: Self::Endian
) -> u16 {
858 self.e_ehsize
.get(endian
)
862 fn e_phentsize(&self, endian
: Self::Endian
) -> u16 {
863 self.e_phentsize
.get(endian
)
867 fn e_phnum(&self, endian
: Self::Endian
) -> u16 {
868 self.e_phnum
.get(endian
)
872 fn e_shentsize(&self, endian
: Self::Endian
) -> u16 {
873 self.e_shentsize
.get(endian
)
877 fn e_shnum(&self, endian
: Self::Endian
) -> u16 {
878 self.e_shnum
.get(endian
)
882 fn e_shstrndx(&self, endian
: Self::Endian
) -> u16 {
883 self.e_shstrndx
.get(endian
)