Skip to content

Commit

Permalink
elf: parse library from symbol versioning table (#693)
Browse files Browse the repository at this point in the history
  • Loading branch information
robbje authored Jun 9, 2024
1 parent 2f45bc0 commit 7b58f78
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 11 deletions.
8 changes: 4 additions & 4 deletions crates/examples/testfiles/elf/base-aarch64.objdump
Original file line number Diff line number Diff line change
Expand Up @@ -152,12 +152,12 @@ Dynamic relocations
(10fb8, Relocation { kind: Unknown, encoding: Generic, size: 0, target: Symbol(SymbolIndex(9)), addend: 0, implicit_addend: false, flags: Elf { r_type: 402 } })

Import { library: "", name: "_ITM_deregisterTMCloneTable" }
Import { library: "", name: "__cxa_finalize" }
Import { library: "", name: "__libc_start_main" }
Import { library: "libc.so.6", name: "__cxa_finalize" }
Import { library: "libc.so.6", name: "__libc_start_main" }
Import { library: "", name: "__gmon_start__" }
Import { library: "", name: "abort" }
Import { library: "libc.so.6", name: "abort" }
Import { library: "", name: "_ITM_registerTMCloneTable" }
Import { library: "", name: "printf" }
Import { library: "libc.so.6", name: "printf" }

Symbol map
0x598 "_init"
Expand Down
6 changes: 3 additions & 3 deletions crates/examples/testfiles/elf/base.objdump
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,11 @@ Dynamic relocations
(200fd0, Relocation { kind: Unknown, encoding: Generic, size: 0, target: Symbol(SymbolIndex(2)), addend: 0, implicit_addend: false, flags: Elf { r_type: 7 } })

Import { library: "", name: "_ITM_deregisterTMCloneTable" }
Import { library: "", name: "printf" }
Import { library: "", name: "__libc_start_main" }
Import { library: "libc.so.6", name: "printf" }
Import { library: "libc.so.6", name: "__libc_start_main" }
Import { library: "", name: "__gmon_start__" }
Import { library: "", name: "_ITM_registerTMCloneTable" }
Import { library: "", name: "__cxa_finalize" }
Import { library: "libc.so.6", name: "__cxa_finalize" }

Symbol map
0x520 "_init"
Expand Down
14 changes: 11 additions & 3 deletions src/read/elf/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,15 +334,23 @@ where
}

fn imports(&self) -> read::Result<Vec<Import<'data>>> {
let versions = self.sections.versions(self.endian, self.data)?;

let mut imports = Vec::new();
for symbol in self.dynamic_symbols.iter() {
for (index, symbol) in self.dynamic_symbols.enumerate() {
if symbol.is_undefined(self.endian) {
let name = symbol.name(self.endian, self.dynamic_symbols.strings())?;
if !name.is_empty() {
// TODO: use symbol versioning to determine library
let library = if let Some(svt) = versions.as_ref() {
let vi = svt.version_index(self.endian, index);
svt.version(vi)?.and_then(|v| v.file())
} else {
None
}
.unwrap_or(&[]);
imports.push(Import {
name: ByteString(name),
library: ByteString(&[]),
library: ByteString(library),
});
}
}
Expand Down
13 changes: 12 additions & 1 deletion src/read/elf/version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ pub struct Version<'data> {
hash: u32,
// Used to keep track of valid indices in `VersionTable`.
valid: bool,
file: Option<&'data [u8]>,
}

impl<'data> Version<'data> {
Expand All @@ -52,6 +53,14 @@ impl<'data> Version<'data> {
pub fn hash(&self) -> u32 {
self.hash
}

/// Return the filename of the library containing this version.
///
/// This is the `vn_file` field of the associated entry in [`elf::SHT_GNU_VERNEED`].
/// or `None` if the version info was parsed from a [`elf::SHT_GNU_VERDEF`] section.
pub fn file(&self) -> Option<&'data [u8]> {
self.file
}
}

/// A table of version definitions and requirements.
Expand Down Expand Up @@ -128,12 +137,13 @@ impl<'data, Elf: FileHeader> VersionTable<'data, Elf> {
name: verdaux.name(endian, strings)?,
hash: verdef.vd_hash.get(endian),
valid: true,
file: None,
};
}
}
}
if let Some(mut verneeds) = verneeds {
while let Some((_, mut vernauxs)) = verneeds.next()? {
while let Some((verneed, mut vernauxs)) = verneeds.next()? {
while let Some(vernaux) = vernauxs.next()? {
let index = vernaux.vna_other.get(endian) & elf::VERSYM_VERSION;
if index <= elf::VER_NDX_GLOBAL {
Expand All @@ -144,6 +154,7 @@ impl<'data, Elf: FileHeader> VersionTable<'data, Elf> {
name: vernaux.name(endian, strings)?,
hash: vernaux.vna_hash.get(endian),
valid: true,
file: Some(verneed.file(endian, strings)?),
};
}
}
Expand Down

0 comments on commit 7b58f78

Please sign in to comment.