1use alloc::vec::Vec;
2use core::convert::TryInto;
3use core::fmt::Debug;
4use core::mem;
5
6use crate::elf;
7use crate::endian::{self, Endian, Endianness, U32};
8use crate::pod::Pod;
9use crate::read::{
10 self, util, Architecture, ByteString, Bytes, Error, Export, FileFlags, Import, Object,
11 ObjectKind, ReadError, ReadRef, SectionIndex, StringTable, SymbolIndex,
12};
13
14use super::{
15 CompressionHeader, Dyn, ElfComdat, ElfComdatIterator, ElfDynamicRelocationIterator, ElfSection,
16 ElfSectionIterator, ElfSegment, ElfSegmentIterator, ElfSymbol, ElfSymbolIterator,
17 ElfSymbolTable, NoteHeader, ProgramHeader, Rel, Rela, RelocationSections, SectionHeader,
18 SectionTable, Sym, SymbolTable,
19};
20
21pub type ElfFile32<'data, Endian = Endianness, R = &'data [u8]> =
26 ElfFile<'data, elf::FileHeader32<Endian>, R>;
27pub type ElfFile64<'data, Endian = Endianness, R = &'data [u8]> =
32 ElfFile<'data, elf::FileHeader64<Endian>, R>;
33
34#[derive(Debug)]
38pub struct ElfFile<'data, Elf, R = &'data [u8]>
39where
40 Elf: FileHeader,
41 R: ReadRef<'data>,
42{
43 pub(super) endian: Elf::Endian,
44 pub(super) data: R,
45 pub(super) header: &'data Elf,
46 pub(super) segments: &'data [Elf::ProgramHeader],
47 pub(super) sections: SectionTable<'data, Elf, R>,
48 pub(super) relocations: RelocationSections,
49 pub(super) symbols: SymbolTable<'data, Elf, R>,
50 pub(super) dynamic_symbols: SymbolTable<'data, Elf, R>,
51}
52
53impl<'data, Elf, R> ElfFile<'data, Elf, R>
54where
55 Elf: FileHeader,
56 R: ReadRef<'data>,
57{
58 pub fn parse(data: R) -> read::Result<Self> {
60 let header = Elf::parse(data)?;
61 let endian = header.endian()?;
62 let segments = header.program_headers(endian, data)?;
63 let sections = header.sections(endian, data)?;
64 let symbols = sections.symbols(endian, data, elf::SHT_SYMTAB)?;
65 let dynamic_symbols = sections.symbols(endian, data, elf::SHT_DYNSYM)?;
67 let relocations = sections.relocation_sections(endian, symbols.section())?;
69
70 Ok(ElfFile {
71 endian,
72 data,
73 header,
74 segments,
75 sections,
76 relocations,
77 symbols,
78 dynamic_symbols,
79 })
80 }
81
82 pub fn endian(&self) -> Elf::Endian {
84 self.endian
85 }
86
87 pub fn data(&self) -> R {
89 self.data
90 }
91
92 #[deprecated(note = "Use `elf_header` instead")]
94 pub fn raw_header(&self) -> &'data Elf {
95 self.header
96 }
97
98 #[deprecated(note = "Use `elf_program_headers` instead")]
100 pub fn raw_segments(&self) -> &'data [Elf::ProgramHeader] {
101 self.segments
102 }
103
104 pub fn elf_header(&self) -> &'data Elf {
106 self.header
107 }
108
109 pub fn elf_program_headers(&self) -> &'data [Elf::ProgramHeader] {
113 self.segments
114 }
115
116 pub fn elf_section_table(&self) -> &SectionTable<'data, Elf, R> {
120 &self.sections
121 }
122
123 pub fn elf_symbol_table(&self) -> &SymbolTable<'data, Elf, R> {
127 &self.symbols
128 }
129
130 pub fn elf_dynamic_symbol_table(&self) -> &SymbolTable<'data, Elf, R> {
134 &self.dynamic_symbols
135 }
136
137 pub fn elf_relocation_sections(&self) -> &RelocationSections {
139 &self.relocations
140 }
141
142 fn raw_section_by_name<'file>(
143 &'file self,
144 section_name: &[u8],
145 ) -> Option<ElfSection<'data, 'file, Elf, R>> {
146 self.sections
147 .section_by_name(self.endian, section_name)
148 .map(|(index, section)| ElfSection {
149 file: self,
150 index,
151 section,
152 })
153 }
154
155 #[cfg(feature = "compression")]
156 fn zdebug_section_by_name<'file>(
157 &'file self,
158 section_name: &[u8],
159 ) -> Option<ElfSection<'data, 'file, Elf, R>> {
160 if !section_name.starts_with(b".debug_") {
161 return None;
162 }
163 let mut name = Vec::with_capacity(section_name.len() + 1);
164 name.extend_from_slice(b".zdebug_");
165 name.extend_from_slice(§ion_name[7..]);
166 self.raw_section_by_name(&name)
167 }
168
169 #[cfg(not(feature = "compression"))]
170 fn zdebug_section_by_name<'file>(
171 &'file self,
172 _section_name: &[u8],
173 ) -> Option<ElfSection<'data, 'file, Elf, R>> {
174 None
175 }
176}
177
178impl<'data, Elf, R> read::private::Sealed for ElfFile<'data, Elf, R>
179where
180 Elf: FileHeader,
181 R: ReadRef<'data>,
182{
183}
184
185impl<'data, Elf, R> Object<'data> for ElfFile<'data, Elf, R>
186where
187 Elf: FileHeader,
188 R: ReadRef<'data>,
189{
190 type Segment<'file> = ElfSegment<'data, 'file, Elf, R> where Self: 'file, 'data: 'file;
191 type SegmentIterator<'file> = ElfSegmentIterator<'data, 'file, Elf, R> where Self: 'file, 'data: 'file;
192 type Section<'file> = ElfSection<'data, 'file, Elf, R> where Self: 'file, 'data: 'file;
193 type SectionIterator<'file> = ElfSectionIterator<'data, 'file, Elf, R> where Self: 'file, 'data: 'file;
194 type Comdat<'file> = ElfComdat<'data, 'file, Elf, R> where Self: 'file, 'data: 'file;
195 type ComdatIterator<'file> = ElfComdatIterator<'data, 'file, Elf, R> where Self: 'file, 'data: 'file;
196 type Symbol<'file> = ElfSymbol<'data, 'file, Elf, R> where Self: 'file, 'data: 'file;
197 type SymbolIterator<'file> = ElfSymbolIterator<'data, 'file, Elf, R> where Self: 'file, 'data: 'file;
198 type SymbolTable<'file> = ElfSymbolTable<'data, 'file, Elf, R> where Self: 'file, 'data: 'file;
199 type DynamicRelocationIterator<'file> = ElfDynamicRelocationIterator<'data, 'file, Elf, R> where Self: 'file, 'data: 'file;
200
201 fn architecture(&self) -> Architecture {
202 match (
203 self.header.e_machine(self.endian),
204 self.header.is_class_64(),
205 ) {
206 (elf::EM_AARCH64, true) => Architecture::Aarch64,
207 (elf::EM_AARCH64, false) => Architecture::Aarch64_Ilp32,
208 (elf::EM_ARM, _) => Architecture::Arm,
209 (elf::EM_AVR, _) => Architecture::Avr,
210 (elf::EM_BPF, _) => Architecture::Bpf,
211 (elf::EM_CSKY, _) => Architecture::Csky,
212 (elf::EM_386, _) => Architecture::I386,
213 (elf::EM_X86_64, false) => Architecture::X86_64_X32,
214 (elf::EM_X86_64, true) => Architecture::X86_64,
215 (elf::EM_HEXAGON, _) => Architecture::Hexagon,
216 (elf::EM_LOONGARCH, true) => Architecture::LoongArch64,
217 (elf::EM_MIPS, false) => Architecture::Mips,
218 (elf::EM_MIPS, true) => Architecture::Mips64,
219 (elf::EM_MSP430, _) => Architecture::Msp430,
220 (elf::EM_PPC, _) => Architecture::PowerPc,
221 (elf::EM_PPC64, _) => Architecture::PowerPc64,
222 (elf::EM_RISCV, false) => Architecture::Riscv32,
223 (elf::EM_RISCV, true) => Architecture::Riscv64,
224 (elf::EM_S390, true) => Architecture::S390x,
227 (elf::EM_SBF, _) => Architecture::Sbf,
228 (elf::EM_SHARC, false) => Architecture::Sharc,
229 (elf::EM_SPARC, false) => Architecture::Sparc,
230 (elf::EM_SPARC32PLUS, false) => Architecture::Sparc32Plus,
231 (elf::EM_SPARCV9, true) => Architecture::Sparc64,
232 (elf::EM_XTENSA, false) => Architecture::Xtensa,
233 _ => Architecture::Unknown,
234 }
235 }
236
237 #[inline]
238 fn is_little_endian(&self) -> bool {
239 self.header.is_little_endian()
240 }
241
242 #[inline]
243 fn is_64(&self) -> bool {
244 self.header.is_class_64()
245 }
246
247 fn kind(&self) -> ObjectKind {
248 match self.header.e_type(self.endian) {
249 elf::ET_REL => ObjectKind::Relocatable,
250 elf::ET_EXEC => ObjectKind::Executable,
251 elf::ET_DYN => ObjectKind::Dynamic,
253 elf::ET_CORE => ObjectKind::Core,
254 _ => ObjectKind::Unknown,
255 }
256 }
257
258 fn segments(&self) -> ElfSegmentIterator<'data, '_, Elf, R> {
259 ElfSegmentIterator {
260 file: self,
261 iter: self.segments.iter(),
262 }
263 }
264
265 fn section_by_name_bytes<'file>(
266 &'file self,
267 section_name: &[u8],
268 ) -> Option<ElfSection<'data, 'file, Elf, R>> {
269 self.raw_section_by_name(section_name)
270 .or_else(|| self.zdebug_section_by_name(section_name))
271 }
272
273 fn section_by_index(&self, index: SectionIndex) -> read::Result<ElfSection<'data, '_, Elf, R>> {
274 let section = self.sections.section(index)?;
275 Ok(ElfSection {
276 file: self,
277 index,
278 section,
279 })
280 }
281
282 fn sections(&self) -> ElfSectionIterator<'data, '_, Elf, R> {
283 ElfSectionIterator::new(self)
284 }
285
286 fn comdats(&self) -> ElfComdatIterator<'data, '_, Elf, R> {
287 ElfComdatIterator::new(self)
288 }
289
290 fn symbol_by_index(&self, index: SymbolIndex) -> read::Result<ElfSymbol<'data, '_, Elf, R>> {
291 let symbol = self.symbols.symbol(index)?;
292 Ok(ElfSymbol {
293 endian: self.endian,
294 symbols: &self.symbols,
295 index,
296 symbol,
297 })
298 }
299
300 fn symbols(&self) -> ElfSymbolIterator<'data, '_, Elf, R> {
301 ElfSymbolIterator::new(self.endian, &self.symbols)
302 }
303
304 fn symbol_table(&self) -> Option<ElfSymbolTable<'data, '_, Elf, R>> {
305 if self.symbols.is_empty() {
306 return None;
307 }
308 Some(ElfSymbolTable {
309 endian: self.endian,
310 symbols: &self.symbols,
311 })
312 }
313
314 fn dynamic_symbols(&self) -> ElfSymbolIterator<'data, '_, Elf, R> {
315 ElfSymbolIterator::new(self.endian, &self.dynamic_symbols)
316 }
317
318 fn dynamic_symbol_table(&self) -> Option<ElfSymbolTable<'data, '_, Elf, R>> {
319 if self.dynamic_symbols.is_empty() {
320 return None;
321 }
322 Some(ElfSymbolTable {
323 endian: self.endian,
324 symbols: &self.dynamic_symbols,
325 })
326 }
327
328 fn dynamic_relocations<'file>(
329 &'file self,
330 ) -> Option<ElfDynamicRelocationIterator<'data, 'file, Elf, R>> {
331 Some(ElfDynamicRelocationIterator {
332 section_index: SectionIndex(1),
333 file: self,
334 relocations: None,
335 })
336 }
337
338 fn imports(&self) -> read::Result<Vec<Import<'data>>> {
339 let versions = self.sections.versions(self.endian, self.data)?;
340
341 let mut imports = Vec::new();
342 for (index, symbol) in self.dynamic_symbols.enumerate() {
343 if symbol.is_undefined(self.endian) {
344 let name = symbol.name(self.endian, self.dynamic_symbols.strings())?;
345 if !name.is_empty() {
346 let library = if let Some(svt) = versions.as_ref() {
347 let vi = svt.version_index(self.endian, index);
348 svt.version(vi)?.and_then(|v| v.file())
349 } else {
350 None
351 }
352 .unwrap_or(&[]);
353 imports.push(Import {
354 name: ByteString(name),
355 library: ByteString(library),
356 });
357 }
358 }
359 }
360 Ok(imports)
361 }
362
363 fn exports(&self) -> read::Result<Vec<Export<'data>>> {
364 let mut exports = Vec::new();
365 for symbol in self.dynamic_symbols.iter() {
366 if symbol.is_definition(self.endian) {
367 let name = symbol.name(self.endian, self.dynamic_symbols.strings())?;
368 let address = symbol.st_value(self.endian).into();
369 exports.push(Export {
370 name: ByteString(name),
371 address,
372 });
373 }
374 }
375 Ok(exports)
376 }
377
378 fn has_debug_symbols(&self) -> bool {
379 for section in self.sections.iter() {
380 if let Ok(name) = self.sections.section_name(self.endian, section) {
381 if name == b".debug_info" || name == b".zdebug_info" {
382 return true;
383 }
384 }
385 }
386 false
387 }
388
389 fn build_id(&self) -> read::Result<Option<&'data [u8]>> {
390 let endian = self.endian;
391 if !self.sections.is_empty() {
393 for section in self.sections.iter() {
394 if let Some(mut notes) = section.notes(endian, self.data)? {
395 while let Some(note) = notes.next()? {
396 if note.name() == elf::ELF_NOTE_GNU
397 && note.n_type(endian) == elf::NT_GNU_BUILD_ID
398 {
399 return Ok(Some(note.desc()));
400 }
401 }
402 }
403 }
404 } else {
405 for segment in self.segments {
406 if let Some(mut notes) = segment.notes(endian, self.data)? {
407 while let Some(note) = notes.next()? {
408 if note.name() == elf::ELF_NOTE_GNU
409 && note.n_type(endian) == elf::NT_GNU_BUILD_ID
410 {
411 return Ok(Some(note.desc()));
412 }
413 }
414 }
415 }
416 }
417 Ok(None)
418 }
419
420 fn gnu_debuglink(&self) -> read::Result<Option<(&'data [u8], u32)>> {
421 let section = match self.raw_section_by_name(b".gnu_debuglink") {
422 Some(section) => section,
423 None => return Ok(None),
424 };
425 let data = section
426 .section
427 .data(self.endian, self.data)
428 .read_error("Invalid ELF .gnu_debuglink section offset or size")
429 .map(Bytes)?;
430 let filename = data
431 .read_string_at(0)
432 .read_error("Missing ELF .gnu_debuglink filename")?;
433 let crc_offset = util::align(filename.len() + 1, 4);
434 let crc = data
435 .read_at::<U32<_>>(crc_offset)
436 .read_error("Missing ELF .gnu_debuglink crc")?
437 .get(self.endian);
438 Ok(Some((filename, crc)))
439 }
440
441 fn gnu_debugaltlink(&self) -> read::Result<Option<(&'data [u8], &'data [u8])>> {
442 let section = match self.raw_section_by_name(b".gnu_debugaltlink") {
443 Some(section) => section,
444 None => return Ok(None),
445 };
446 let mut data = section
447 .section
448 .data(self.endian, self.data)
449 .read_error("Invalid ELF .gnu_debugaltlink section offset or size")
450 .map(Bytes)?;
451 let filename = data
452 .read_string()
453 .read_error("Missing ELF .gnu_debugaltlink filename")?;
454 let build_id = data.0;
455 Ok(Some((filename, build_id)))
456 }
457
458 fn relative_address_base(&self) -> u64 {
459 0
460 }
461
462 fn entry(&self) -> u64 {
463 self.header.e_entry(self.endian).into()
464 }
465
466 fn flags(&self) -> FileFlags {
467 FileFlags::Elf {
468 os_abi: self.header.e_ident().os_abi,
469 abi_version: self.header.e_ident().abi_version,
470 e_flags: self.header.e_flags(self.endian),
471 }
472 }
473}
474
475#[allow(missing_docs)]
477pub trait FileHeader: Debug + Pod {
478 type Word: Into<u64>;
480 type Sword: Into<i64>;
481 type Endian: endian::Endian;
482 type ProgramHeader: ProgramHeader<Elf = Self, Endian = Self::Endian, Word = Self::Word>;
483 type SectionHeader: SectionHeader<Elf = Self, Endian = Self::Endian, Word = Self::Word>;
484 type CompressionHeader: CompressionHeader<Endian = Self::Endian, Word = Self::Word>;
485 type NoteHeader: NoteHeader<Endian = Self::Endian>;
486 type Dyn: Dyn<Endian = Self::Endian, Word = Self::Word>;
487 type Sym: Sym<Endian = Self::Endian, Word = Self::Word>;
488 type Rel: Rel<Endian = Self::Endian, Word = Self::Word>;
489 type Rela: Rela<Endian = Self::Endian, Word = Self::Word> + From<Self::Rel>;
490
491 fn is_type_64(&self) -> bool;
495
496 fn is_type_64_sized() -> bool
502 where
503 Self: Sized;
504
505 fn e_ident(&self) -> &elf::Ident;
506 fn e_type(&self, endian: Self::Endian) -> u16;
507 fn e_machine(&self, endian: Self::Endian) -> u16;
508 fn e_version(&self, endian: Self::Endian) -> u32;
509 fn e_entry(&self, endian: Self::Endian) -> Self::Word;
510 fn e_phoff(&self, endian: Self::Endian) -> Self::Word;
511 fn e_shoff(&self, endian: Self::Endian) -> Self::Word;
512 fn e_flags(&self, endian: Self::Endian) -> u32;
513 fn e_ehsize(&self, endian: Self::Endian) -> u16;
514 fn e_phentsize(&self, endian: Self::Endian) -> u16;
515 fn e_phnum(&self, endian: Self::Endian) -> u16;
516 fn e_shentsize(&self, endian: Self::Endian) -> u16;
517 fn e_shnum(&self, endian: Self::Endian) -> u16;
518 fn e_shstrndx(&self, endian: Self::Endian) -> u16;
519
520 fn parse<'data, R: ReadRef<'data>>(data: R) -> read::Result<&'data Self> {
526 let header = data
527 .read_at::<Self>(0)
528 .read_error("Invalid ELF header size or alignment")?;
529 if !header.is_supported() {
530 return Err(Error("Unsupported ELF header"));
531 }
532 Ok(header)
534 }
535
536 fn is_supported(&self) -> bool {
540 let ident = self.e_ident();
541 ident.magic == elf::ELFMAG
543 && (self.is_type_64() || self.is_class_32())
544 && (!self.is_type_64() || self.is_class_64())
545 && (self.is_little_endian() || self.is_big_endian())
546 && ident.version == elf::EV_CURRENT
547 }
548
549 fn is_class_32(&self) -> bool {
550 self.e_ident().class == elf::ELFCLASS32
551 }
552
553 fn is_class_64(&self) -> bool {
554 self.e_ident().class == elf::ELFCLASS64
555 }
556
557 fn is_little_endian(&self) -> bool {
558 self.e_ident().data == elf::ELFDATA2LSB
559 }
560
561 fn is_big_endian(&self) -> bool {
562 self.e_ident().data == elf::ELFDATA2MSB
563 }
564
565 fn endian(&self) -> read::Result<Self::Endian> {
566 Self::Endian::from_big_endian(self.is_big_endian()).read_error("Unsupported ELF endian")
567 }
568
569 fn section_0<'data, R: ReadRef<'data>>(
574 &self,
575 endian: Self::Endian,
576 data: R,
577 ) -> read::Result<Option<&'data Self::SectionHeader>> {
578 let shoff: u64 = self.e_shoff(endian).into();
579 if shoff == 0 {
580 return Ok(None);
582 }
583 let shentsize = usize::from(self.e_shentsize(endian));
584 if shentsize != mem::size_of::<Self::SectionHeader>() {
585 return Err(Error("Invalid ELF section header entry size"));
587 }
588 data.read_at(shoff)
589 .map(Some)
590 .read_error("Invalid ELF section header offset or size")
591 }
592
593 fn phnum<'data, R: ReadRef<'data>>(
597 &self,
598 endian: Self::Endian,
599 data: R,
600 ) -> read::Result<usize> {
601 let e_phnum = self.e_phnum(endian);
602 if e_phnum < elf::PN_XNUM {
603 Ok(e_phnum as usize)
604 } else if let Some(section_0) = self.section_0(endian, data)? {
605 Ok(section_0.sh_info(endian) as usize)
606 } else {
607 Err(Error("Missing ELF section headers for e_phnum overflow"))
609 }
610 }
611
612 fn shnum<'data, R: ReadRef<'data>>(
616 &self,
617 endian: Self::Endian,
618 data: R,
619 ) -> read::Result<usize> {
620 let e_shnum = self.e_shnum(endian);
621 if e_shnum > 0 {
622 Ok(e_shnum as usize)
623 } else if let Some(section_0) = self.section_0(endian, data)? {
624 section_0
625 .sh_size(endian)
626 .into()
627 .try_into()
628 .ok()
629 .read_error("Invalid ELF extended e_shnum")
630 } else {
631 Ok(0)
633 }
634 }
635
636 fn shstrndx<'data, R: ReadRef<'data>>(
640 &self,
641 endian: Self::Endian,
642 data: R,
643 ) -> read::Result<u32> {
644 let e_shstrndx = self.e_shstrndx(endian);
645 let index = if e_shstrndx != elf::SHN_XINDEX {
646 e_shstrndx.into()
647 } else if let Some(section_0) = self.section_0(endian, data)? {
648 section_0.sh_link(endian)
649 } else {
650 return Err(Error("Missing ELF section headers for e_shstrndx overflow"));
652 };
653 if index == 0 {
654 return Err(Error("Missing ELF e_shstrndx"));
655 }
656 Ok(index)
657 }
658
659 fn program_headers<'data, R: ReadRef<'data>>(
664 &self,
665 endian: Self::Endian,
666 data: R,
667 ) -> read::Result<&'data [Self::ProgramHeader]> {
668 let phoff: u64 = self.e_phoff(endian).into();
669 if phoff == 0 {
670 return Ok(&[]);
672 }
673 let phnum = self.phnum(endian, data)?;
674 if phnum == 0 {
675 return Ok(&[]);
677 }
678 let phentsize = self.e_phentsize(endian) as usize;
679 if phentsize != mem::size_of::<Self::ProgramHeader>() {
680 return Err(Error("Invalid ELF program header entry size"));
682 }
683 data.read_slice_at(phoff, phnum)
684 .read_error("Invalid ELF program header size or alignment")
685 }
686
687 fn section_headers<'data, R: ReadRef<'data>>(
692 &self,
693 endian: Self::Endian,
694 data: R,
695 ) -> read::Result<&'data [Self::SectionHeader]> {
696 let shoff: u64 = self.e_shoff(endian).into();
697 if shoff == 0 {
698 return Ok(&[]);
700 }
701 let shnum = self.shnum(endian, data)?;
702 if shnum == 0 {
703 return Ok(&[]);
705 }
706 let shentsize = usize::from(self.e_shentsize(endian));
707 if shentsize != mem::size_of::<Self::SectionHeader>() {
708 return Err(Error("Invalid ELF section header entry size"));
710 }
711 data.read_slice_at(shoff, shnum)
712 .read_error("Invalid ELF section header offset/size/alignment")
713 }
714
715 fn section_strings_index<'data, R: ReadRef<'data>>(
719 &self,
720 endian: Self::Endian,
721 data: R,
722 ) -> read::Result<SectionIndex> {
723 self.shstrndx(endian, data)
724 .map(|index| SectionIndex(index as usize))
725 }
726
727 fn section_strings<'data, R: ReadRef<'data>>(
729 &self,
730 endian: Self::Endian,
731 data: R,
732 sections: &[Self::SectionHeader],
733 ) -> read::Result<StringTable<'data, R>> {
734 if sections.is_empty() {
735 return Ok(StringTable::default());
736 }
737 let index = self.section_strings_index(endian, data)?;
738 let shstrtab = sections.get(index.0).read_error("Invalid ELF e_shstrndx")?;
739 let strings = if let Some((shstrtab_offset, shstrtab_size)) = shstrtab.file_range(endian) {
740 let shstrtab_end = shstrtab_offset
741 .checked_add(shstrtab_size)
742 .read_error("Invalid ELF shstrtab size")?;
743 StringTable::new(data, shstrtab_offset, shstrtab_end)
744 } else {
745 StringTable::default()
746 };
747 Ok(strings)
748 }
749
750 fn sections<'data, R: ReadRef<'data>>(
752 &self,
753 endian: Self::Endian,
754 data: R,
755 ) -> read::Result<SectionTable<'data, Self, R>> {
756 let sections = self.section_headers(endian, data)?;
757 let strings = self.section_strings(endian, data, sections)?;
758 Ok(SectionTable::new(sections, strings))
759 }
760
761 fn is_mips64el(&self, endian: Self::Endian) -> bool {
763 self.is_class_64() && self.is_little_endian() && self.e_machine(endian) == elf::EM_MIPS
764 }
765}
766
767impl<Endian: endian::Endian> FileHeader for elf::FileHeader32<Endian> {
768 type Word = u32;
769 type Sword = i32;
770 type Endian = Endian;
771 type ProgramHeader = elf::ProgramHeader32<Endian>;
772 type SectionHeader = elf::SectionHeader32<Endian>;
773 type CompressionHeader = elf::CompressionHeader32<Endian>;
774 type NoteHeader = elf::NoteHeader32<Endian>;
775 type Dyn = elf::Dyn32<Endian>;
776 type Sym = elf::Sym32<Endian>;
777 type Rel = elf::Rel32<Endian>;
778 type Rela = elf::Rela32<Endian>;
779
780 #[inline]
781 fn is_type_64(&self) -> bool {
782 false
783 }
784
785 #[inline]
786 fn is_type_64_sized() -> bool
787 where
788 Self: Sized,
789 {
790 false
791 }
792
793 #[inline]
794 fn e_ident(&self) -> &elf::Ident {
795 &self.e_ident
796 }
797
798 #[inline]
799 fn e_type(&self, endian: Self::Endian) -> u16 {
800 self.e_type.get(endian)
801 }
802
803 #[inline]
804 fn e_machine(&self, endian: Self::Endian) -> u16 {
805 self.e_machine.get(endian)
806 }
807
808 #[inline]
809 fn e_version(&self, endian: Self::Endian) -> u32 {
810 self.e_version.get(endian)
811 }
812
813 #[inline]
814 fn e_entry(&self, endian: Self::Endian) -> Self::Word {
815 self.e_entry.get(endian)
816 }
817
818 #[inline]
819 fn e_phoff(&self, endian: Self::Endian) -> Self::Word {
820 self.e_phoff.get(endian)
821 }
822
823 #[inline]
824 fn e_shoff(&self, endian: Self::Endian) -> Self::Word {
825 self.e_shoff.get(endian)
826 }
827
828 #[inline]
829 fn e_flags(&self, endian: Self::Endian) -> u32 {
830 self.e_flags.get(endian)
831 }
832
833 #[inline]
834 fn e_ehsize(&self, endian: Self::Endian) -> u16 {
835 self.e_ehsize.get(endian)
836 }
837
838 #[inline]
839 fn e_phentsize(&self, endian: Self::Endian) -> u16 {
840 self.e_phentsize.get(endian)
841 }
842
843 #[inline]
844 fn e_phnum(&self, endian: Self::Endian) -> u16 {
845 self.e_phnum.get(endian)
846 }
847
848 #[inline]
849 fn e_shentsize(&self, endian: Self::Endian) -> u16 {
850 self.e_shentsize.get(endian)
851 }
852
853 #[inline]
854 fn e_shnum(&self, endian: Self::Endian) -> u16 {
855 self.e_shnum.get(endian)
856 }
857
858 #[inline]
859 fn e_shstrndx(&self, endian: Self::Endian) -> u16 {
860 self.e_shstrndx.get(endian)
861 }
862}
863
864impl<Endian: endian::Endian> FileHeader for elf::FileHeader64<Endian> {
865 type Word = u64;
866 type Sword = i64;
867 type Endian = Endian;
868 type ProgramHeader = elf::ProgramHeader64<Endian>;
869 type SectionHeader = elf::SectionHeader64<Endian>;
870 type CompressionHeader = elf::CompressionHeader64<Endian>;
871 type NoteHeader = elf::NoteHeader32<Endian>;
872 type Dyn = elf::Dyn64<Endian>;
873 type Sym = elf::Sym64<Endian>;
874 type Rel = elf::Rel64<Endian>;
875 type Rela = elf::Rela64<Endian>;
876
877 #[inline]
878 fn is_type_64(&self) -> bool {
879 true
880 }
881
882 #[inline]
883 fn is_type_64_sized() -> bool
884 where
885 Self: Sized,
886 {
887 true
888 }
889
890 #[inline]
891 fn e_ident(&self) -> &elf::Ident {
892 &self.e_ident
893 }
894
895 #[inline]
896 fn e_type(&self, endian: Self::Endian) -> u16 {
897 self.e_type.get(endian)
898 }
899
900 #[inline]
901 fn e_machine(&self, endian: Self::Endian) -> u16 {
902 self.e_machine.get(endian)
903 }
904
905 #[inline]
906 fn e_version(&self, endian: Self::Endian) -> u32 {
907 self.e_version.get(endian)
908 }
909
910 #[inline]
911 fn e_entry(&self, endian: Self::Endian) -> Self::Word {
912 self.e_entry.get(endian)
913 }
914
915 #[inline]
916 fn e_phoff(&self, endian: Self::Endian) -> Self::Word {
917 self.e_phoff.get(endian)
918 }
919
920 #[inline]
921 fn e_shoff(&self, endian: Self::Endian) -> Self::Word {
922 self.e_shoff.get(endian)
923 }
924
925 #[inline]
926 fn e_flags(&self, endian: Self::Endian) -> u32 {
927 self.e_flags.get(endian)
928 }
929
930 #[inline]
931 fn e_ehsize(&self, endian: Self::Endian) -> u16 {
932 self.e_ehsize.get(endian)
933 }
934
935 #[inline]
936 fn e_phentsize(&self, endian: Self::Endian) -> u16 {
937 self.e_phentsize.get(endian)
938 }
939
940 #[inline]
941 fn e_phnum(&self, endian: Self::Endian) -> u16 {
942 self.e_phnum.get(endian)
943 }
944
945 #[inline]
946 fn e_shentsize(&self, endian: Self::Endian) -> u16 {
947 self.e_shentsize.get(endian)
948 }
949
950 #[inline]
951 fn e_shnum(&self, endian: Self::Endian) -> u16 {
952 self.e_shnum.get(endian)
953 }
954
955 #[inline]
956 fn e_shstrndx(&self, endian: Self::Endian) -> u16 {
957 self.e_shstrndx.get(endian)
958 }
959}