read/elf: include unsized symbols in is_definition() (#866)

It's useful to have these in the symbol map.

Co-authored-by: Peter Collingbourne <pcc@google.com>
This commit is contained in:
Philip Craig
2026-03-29 11:08:06 +10:00
committed by GitHub
parent 7eaeb11dcc
commit 870389fab6
6 changed files with 30 additions and 6 deletions
@@ -175,5 +175,7 @@ Symbol map
0x7f8-0x7fc "__FRAME_END__"
0x10d80-0x10d88 "__frame_dummy_init_array_entry"
0x10d88-0x10d90 "__do_global_dtors_aux_fini_array_entry"
0x11000-0x11008 "__data_start"
0x11008-0x11010 "__dso_handle"
0x11010-0x11011 "completed.8500"
0x11018-0x11018 "__end__"
@@ -121,10 +121,13 @@ Symbol map
0x11d4-0x11e8 "_fini"
0x2000-0x2004 "_fp_hw"
0x2004-0x2008 "_IO_stdin_used"
0x2018-0x204c "__GNU_EH_FRAME_HDR"
0x2110-0x2114 "__FRAME_END__"
0x3ec0-0x3ec4 "__frame_dummy_init_array_entry"
0x3ec4-0x3ec8 "__do_global_dtors_aux_fini_array_entry"
0x3ec8-0x3fd8 "_DYNAMIC"
0x3fd8-0x4000 "_GLOBAL_OFFSET_TABLE_"
0x4000-0x4004 "__data_start"
0x4004-0x4008 "__dso_handle"
0x4008-0x4009 "completed.0"
0x400c-0x400c "_end"
@@ -112,10 +112,13 @@ Symbol map
0x1149-0x116c "main"
0x116c-0x1179 "_fini"
0x2000-0x2004 "_IO_stdin_used"
0x2014-0x2048 "__GNU_EH_FRAME_HDR"
0x20f0-0x20f4 "__FRAME_END__"
0x3d88-0x3d90 "__frame_dummy_init_array_entry"
0x3d90-0x3d98 "__do_global_dtors_aux_fini_array_entry"
0x3d98-0x3fb8 "_DYNAMIC"
0x3fb8-0x4000 "_GLOBAL_OFFSET_TABLE_"
0x4000-0x4008 "__data_start"
0x4008-0x4010 "__dso_handle"
0x4010-0x4011 "completed.0"
0x4018-0x4018 "_end"
@@ -140,10 +140,13 @@ Symbol map
0x710-0x712 "__libc_csu_fini"
0x714-0x71d "_fini"
0x720-0x724 "_IO_stdin_used"
0x734-0x770 "__GNU_EH_FRAME_HDR"
0x874-0x878 "__FRAME_END__"
0x200da8-0x200db0 "__frame_dummy_init_array_entry"
0x200db0-0x200db8 "__do_global_dtors_aux_fini_array_entry"
0x200db8-0x200fb8 "_DYNAMIC"
0x200fb8-0x201000 "_GLOBAL_OFFSET_TABLE_"
0x201000-0x201008 "__data_start"
0x201008-0x201010 "__dso_handle"
0x201010-0x201011 "completed.7698"
0x201018-0x201018 "_end"
+1 -1
View File
@@ -432,7 +432,7 @@ where
fn exports(&self) -> read::Result<Vec<Export<'data>>> {
let mut exports = Vec::new();
for symbol in self.dynamic_symbols.iter() {
if symbol.is_definition(self.endian) {
if symbol.is_definition(self.endian, self.dynamic_symbols.strings()) {
let name = symbol.name(self.endian, self.dynamic_symbols.strings())?;
let address = symbol.st_value(self.endian).into();
exports.push(Export {
+18 -5
View File
@@ -206,7 +206,7 @@ impl<'data, Elf: FileHeader, R: ReadRef<'data>> SymbolTable<'data, Elf, R> {
) -> SymbolMap<Entry> {
let mut symbols = Vec::with_capacity(self.symbols.len());
for symbol in self.symbols {
if !symbol.is_definition(endian) {
if !symbol.is_definition(endian, self.strings) {
continue;
}
if let Some(entry) = f(symbol) {
@@ -436,7 +436,8 @@ impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data>
#[inline]
fn is_definition(&self) -> bool {
self.symbol.is_definition(self.endian)
self.symbol
.is_definition(self.endian, self.symbols.strings())
}
#[inline]
@@ -520,14 +521,26 @@ pub trait Sym: Debug + Pod {
}
/// Return true if the symbol is a definition of a function or data object.
fn is_definition(&self, endian: Self::Endian) -> bool {
fn is_definition<'data, R: ReadRef<'data>>(
&self,
endian: Self::Endian,
strings: StringTable<'data, R>,
) -> bool {
let shndx = self.st_shndx(endian);
if shndx == elf::SHN_UNDEF || (shndx >= elf::SHN_LORESERVE && shndx != elf::SHN_XINDEX) {
return false;
}
match self.st_type() {
elf::STT_NOTYPE => self.st_size(endian).into() != 0,
elf::STT_FUNC | elf::STT_OBJECT => true,
elf::STT_NOTYPE if self.st_bind() == elf::STB_LOCAL => {
// Exclude mapping symbols.
let Ok(name) = self.name(endian, strings) else {
// Not worth changing API to return an error for this case.
// Caller is likely to call name() themselves.
return true;
};
!name.starts_with(b"$")
}
elf::STT_FUNC | elf::STT_OBJECT | elf::STT_NOTYPE => true,
_ => false,
}
}