diff --git a/crates/examples/testfiles/elf/base-aarch64.objdump b/crates/examples/testfiles/elf/base-aarch64.objdump index 787f5c6..8d4f061 100644 --- a/crates/examples/testfiles/elf/base-aarch64.objdump +++ b/crates/examples/testfiles/elf/base-aarch64.objdump @@ -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__" diff --git a/crates/examples/testfiles/elf/base-relr-i686.objdump b/crates/examples/testfiles/elf/base-relr-i686.objdump index 4db6460..0ef3816 100644 --- a/crates/examples/testfiles/elf/base-relr-i686.objdump +++ b/crates/examples/testfiles/elf/base-relr-i686.objdump @@ -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" diff --git a/crates/examples/testfiles/elf/base-relr-x86_64.objdump b/crates/examples/testfiles/elf/base-relr-x86_64.objdump index 00cb247..6dac00d 100644 --- a/crates/examples/testfiles/elf/base-relr-x86_64.objdump +++ b/crates/examples/testfiles/elf/base-relr-x86_64.objdump @@ -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" diff --git a/crates/examples/testfiles/elf/base.objdump b/crates/examples/testfiles/elf/base.objdump index 597c164..e8bb26c 100644 --- a/crates/examples/testfiles/elf/base.objdump +++ b/crates/examples/testfiles/elf/base.objdump @@ -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" diff --git a/src/read/elf/file.rs b/src/read/elf/file.rs index 62cc882..32185aa 100644 --- a/src/read/elf/file.rs +++ b/src/read/elf/file.rs @@ -432,7 +432,7 @@ where fn exports(&self) -> read::Result>> { 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 { diff --git a/src/read/elf/symbol.rs b/src/read/elf/symbol.rs index 3c0bee3..0207cde 100644 --- a/src/read/elf/symbol.rs +++ b/src/read/elf/symbol.rs @@ -206,7 +206,7 @@ impl<'data, Elf: FileHeader, R: ReadRef<'data>> SymbolTable<'data, Elf, R> { ) -> SymbolMap { 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, } }