diff --git a/crates/examples/src/objdump.rs b/crates/examples/src/objdump.rs index 67c6e78a..1a6d4b20 100644 --- a/crates/examples/src/objdump.rs +++ b/crates/examples/src/objdump.rs @@ -211,6 +211,16 @@ fn dump_parsed_object(w: &mut W, e: &mut E, file: &object::F writeln!(w, "{:x?}", relocation)?; } } + if section.dynamic_relocations().next().is_some() { + writeln!( + w, + "\n{} dynamic relocations", + section.name().unwrap_or("") + )?; + for relocation in section.dynamic_relocations() { + writeln!(w, "{:x?}", relocation)?; + } + } } writeln!(w)?; diff --git a/crates/examples/testfiles/elf/base-aarch64.objdump b/crates/examples/testfiles/elf/base-aarch64.objdump index 242a2cc0..19b63345 100644 --- a/crates/examples/testfiles/elf/base-aarch64.objdump +++ b/crates/examples/testfiles/elf/base-aarch64.objdump @@ -123,6 +123,13 @@ Symbols 86: Symbol { name: "printf@@GLIBC_2.17", address: 0, size: 0, kind: Text, section: Undefined, scope: Unknown, weak: false, flags: Elf { st_info: 12, st_other: 0 } } 87: Symbol { name: "_init", address: 598, size: 0, kind: Text, section: Section(SectionIndex(b)), scope: Dynamic, weak: false, flags: Elf { st_info: 12, st_other: 0 } } +.got dynamic relocations +(10f98, Relocation { kind: Unknown, encoding: Generic, size: 0, target: Symbol(SymbolIndex(4)), addend: 0, implicit_addend: false, flags: Elf { r_type: 402 } }) +(10fa0, Relocation { kind: Unknown, encoding: Generic, size: 0, target: Symbol(SymbolIndex(5)), addend: 0, implicit_addend: false, flags: Elf { r_type: 402 } }) +(10fa8, Relocation { kind: Unknown, encoding: Generic, size: 0, target: Symbol(SymbolIndex(6)), addend: 0, implicit_addend: false, flags: Elf { r_type: 402 } }) +(10fb0, Relocation { kind: Unknown, encoding: Generic, size: 0, target: Symbol(SymbolIndex(7)), addend: 0, implicit_addend: false, flags: Elf { r_type: 402 } }) +(10fb8, Relocation { kind: Unknown, encoding: Generic, size: 0, target: Symbol(SymbolIndex(9)), addend: 0, implicit_addend: false, flags: Elf { r_type: 402 } }) + Dynamic symbols 1: Symbol { name: "", address: 598, size: 0, kind: Section, section: Section(SectionIndex(b)), scope: Compilation, weak: false, flags: Elf { st_info: 3, st_other: 0 } } 2: Symbol { name: "", address: 11000, size: 0, kind: Section, section: Section(SectionIndex(15)), scope: Compilation, weak: false, flags: Elf { st_info: 3, st_other: 0 } } diff --git a/crates/examples/testfiles/elf/base.objdump b/crates/examples/testfiles/elf/base.objdump index 484db5cb..52370e93 100644 --- a/crates/examples/testfiles/elf/base.objdump +++ b/crates/examples/testfiles/elf/base.objdump @@ -102,6 +102,9 @@ Symbols 62: Symbol { name: "__cxa_finalize@@GLIBC_2.2.5", address: 0, size: 0, kind: Text, section: Undefined, scope: Unknown, weak: true, flags: Elf { st_info: 22, st_other: 0 } } 63: Symbol { name: "_init", address: 520, size: 0, kind: Text, section: Section(SectionIndex(c)), scope: Dynamic, weak: false, flags: Elf { st_info: 12, st_other: 0 } } +.got dynamic relocations +(200fd0, Relocation { kind: Unknown, encoding: Generic, size: 0, target: Symbol(SymbolIndex(2)), addend: 0, implicit_addend: false, flags: Elf { r_type: 7 } }) + Dynamic symbols 1: Symbol { name: "_ITM_deregisterTMCloneTable", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: true, flags: Elf { st_info: 20, st_other: 0 } } 2: Symbol { name: "printf", address: 0, size: 0, kind: Text, section: Undefined, scope: Unknown, weak: false, flags: Elf { st_info: 12, st_other: 0 } } diff --git a/src/read/any.rs b/src/read/any.rs index 6ce20bc2..e1a6e1ce 100644 --- a/src/read/any.rs +++ b/src/read/any.rs @@ -789,6 +789,17 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectSection<'data> for Section<'data, 'f } } + fn dynamic_relocations(&self) -> SectionRelocationIterator<'data, 'file, R> { + SectionRelocationIterator { + inner: map_inner!( + self.inner, + SectionInternal, + SectionRelocationIteratorInternal, + |x| x.dynamic_relocations() + ), + } + } + fn relocation_map(&self) -> Result { with_inner!(self.inner, SectionInternal, |x| x.relocation_map()) } diff --git a/src/read/coff/section.rs b/src/read/coff/section.rs index 280b5c43..f232eaec 100644 --- a/src/read/coff/section.rs +++ b/src/read/coff/section.rs @@ -414,6 +414,13 @@ impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> ObjectSection<'data> } } + fn dynamic_relocations(&self) -> CoffRelocationIterator<'data, 'file, R, Coff> { + CoffRelocationIterator { + file: self.file, + iter: [].iter(), + } + } + fn relocation_map(&self) -> read::Result { RelocationMap::new(self.file, self) } diff --git a/src/read/elf/file.rs b/src/read/elf/file.rs index 6de69ee5..2bef846e 100644 --- a/src/read/elf/file.rs +++ b/src/read/elf/file.rs @@ -46,6 +46,7 @@ where pub(super) segments: &'data [Elf::ProgramHeader], pub(super) sections: SectionTable<'data, Elf, R>, pub(super) relocations: RelocationSections, + pub(super) dynamic_relocations: RelocationSections, pub(super) symbols: SymbolTable<'data, Elf, R>, pub(super) dynamic_symbols: SymbolTable<'data, Elf, R>, } @@ -66,6 +67,8 @@ where let dynamic_symbols = sections.symbols(endian, data, elf::SHT_DYNSYM)?; // The API we provide requires a mapping from section to relocations, so build it now. let relocations = sections.relocation_sections(endian, symbols.section())?; + let dynamic_relocations = + sections.relocation_sections(endian, dynamic_symbols.section())?; Ok(ElfFile { endian, @@ -74,6 +77,7 @@ where segments, sections, relocations, + dynamic_relocations, symbols, dynamic_symbols, }) diff --git a/src/read/elf/relocation.rs b/src/read/elf/relocation.rs index f73ff288..b3b953ec 100644 --- a/src/read/elf/relocation.rs +++ b/src/read/elf/relocation.rs @@ -190,6 +190,7 @@ where /// The current pointer in the chain of relocation sections. pub(super) section_index: SectionIndex, pub(super) file: &'file ElfFile<'data, Elf, R>, + pub(super) relocation_sections: &'file RelocationSections, pub(super) relocations: Option>, } @@ -211,7 +212,7 @@ where } self.relocations = None; } - self.section_index = self.file.relocations.get(self.section_index)?; + self.section_index = self.relocation_sections.get(self.section_index)?; // The construction of RelocationSections ensures section_index is valid. let section = self.file.sections.section(self.section_index).unwrap(); match section.sh_type(endian) { diff --git a/src/read/elf/section.rs b/src/read/elf/section.rs index f175d84d..b804febb 100644 --- a/src/read/elf/section.rs +++ b/src/read/elf/section.rs @@ -663,6 +663,16 @@ where ElfSectionRelocationIterator { section_index: self.index, file: self.file, + relocation_sections: &self.file.relocations, + relocations: None, + } + } + + fn dynamic_relocations(&self) -> ElfSectionRelocationIterator<'data, 'file, Elf, R> { + ElfSectionRelocationIterator { + section_index: self.index, + file: self.file, + relocation_sections: &self.file.dynamic_relocations, relocations: None, } } diff --git a/src/read/macho/section.rs b/src/read/macho/section.rs index d27a9a9f..4bc43bc5 100644 --- a/src/read/macho/section.rs +++ b/src/read/macho/section.rs @@ -226,6 +226,13 @@ where } } + fn dynamic_relocations(&self) -> MachORelocationIterator<'data, 'file, Mach, R> { + MachORelocationIterator { + file: self.file, + relocations: [].iter(), + } + } + fn relocation_map(&self) -> read::Result { RelocationMap::new(self.file, self) } diff --git a/src/read/pe/section.rs b/src/read/pe/section.rs index 4c53d1e2..754cb003 100644 --- a/src/read/pe/section.rs +++ b/src/read/pe/section.rs @@ -320,6 +320,10 @@ where PeRelocationIterator(PhantomData) } + fn dynamic_relocations(&self) -> PeRelocationIterator<'data, 'file, R> { + PeRelocationIterator(PhantomData) + } + fn relocation_map(&self) -> read::Result { RelocationMap::new(self.file, self) } diff --git a/src/read/traits.rs b/src/read/traits.rs index cbc93fc7..5d5c7b41 100644 --- a/src/read/traits.rs +++ b/src/read/traits.rs @@ -454,6 +454,15 @@ pub trait ObjectSection<'data>: read::private::Sealed { /// Get the relocations for this section. fn relocations(&self) -> Self::RelocationIterator; + /// Get the dynamic relocations for this section. + /// + /// Symbol indices in these relocations refer to the dynamic symbol table. + /// + /// Only ELF has dynamic relocations. This may not return all of the dynamic + /// relocations for the section; it can only return relocations from sections + /// that have their `sh_info` set to the index of this section. + fn dynamic_relocations(&self) -> Self::RelocationIterator; + /// Construct a relocation map for this section. fn relocation_map(&self) -> Result; diff --git a/src/read/wasm.rs b/src/read/wasm.rs index 95828ad1..8c6976db 100644 --- a/src/read/wasm.rs +++ b/src/read/wasm.rs @@ -736,6 +736,10 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectSection<'data> for WasmSection<'data WasmRelocationIterator(PhantomData) } + fn dynamic_relocations(&self) -> WasmRelocationIterator<'data, 'file, R> { + WasmRelocationIterator(PhantomData) + } + fn relocation_map(&self) -> read::Result { RelocationMap::new(self.file, self) } diff --git a/src/read/xcoff/section.rs b/src/read/xcoff/section.rs index dac3c2a3..ab614a70 100644 --- a/src/read/xcoff/section.rs +++ b/src/read/xcoff/section.rs @@ -206,6 +206,13 @@ where } } + fn dynamic_relocations(&self) -> Self::RelocationIterator { + XcoffRelocationIterator { + file: self.file, + relocations: [].iter(), + } + } + fn relocation_map(&self) -> read::Result { RelocationMap::new(self.file, self) }