From a566ef143104f71d8c85a1f79a95de179e760ee1 Mon Sep 17 00:00:00 2001 From: Philip Craig Date: Fri, 20 Mar 2026 19:19:28 +1000 Subject: [PATCH] symbol_map: use symbol size if known --- .../testfiles/elf/base-aarch64.o.objdump | 2 +- .../testfiles/elf/base-aarch64.objdump | 8 +-- .../testfiles/elf/base-crel.o.objdump | 2 +- .../testfiles/elf/base-relr-i686.objdump | 10 +-- .../testfiles/elf/base-relr-x86_64.objdump | 8 +-- crates/examples/testfiles/elf/base.o.objdump | 2 +- crates/examples/testfiles/elf/base.objdump | 12 ++-- crates/examples/testfiles/wasm/base.o.objdump | 6 +- .../examples/testfiles/wasm/base.wasm.objdump | 72 +++++++++---------- .../testfiles/wasm/global-wasm32.objdump | 4 +- .../wasm/global-wasm64-import.objdump | 4 +- .../testfiles/wasm/global-wasm64.objdump | 4 +- .../examples/testfiles/xcoff/base.o.objdump | 6 +- .../testfiles/xcoff/base.xcoff.objdump | 16 ++--- .../examples/testfiles/xcoff/base32.o.objdump | 6 +- .../testfiles/xcoff/base32.xcoff.objdump | 14 ++-- src/read/symbol_map.rs | 21 ++++-- src/read/traits.rs | 3 +- 18 files changed, 106 insertions(+), 94 deletions(-) diff --git a/crates/examples/testfiles/elf/base-aarch64.o.objdump b/crates/examples/testfiles/elf/base-aarch64.o.objdump index 6eaa76b..8693375 100644 --- a/crates/examples/testfiles/elf/base-aarch64.o.objdump +++ b/crates/examples/testfiles/elf/base-aarch64.o.objdump @@ -38,4 +38,4 @@ Dynamic symbols Dynamic relocations Symbol map -0x0-0x0 "main" +0x0-0x20 "main" diff --git a/crates/examples/testfiles/elf/base-aarch64.objdump b/crates/examples/testfiles/elf/base-aarch64.objdump index b21ae4d..4787052 100644 --- a/crates/examples/testfiles/elf/base-aarch64.objdump +++ b/crates/examples/testfiles/elf/base-aarch64.objdump @@ -162,18 +162,18 @@ Import { library: "libc.so.6", name: "printf" } Symbol map 0x598-0x620 "_init" 0x620-0x658 "_start" -0x658-0x670 "call_weak_fn" +0x658-0x66c "call_weak_fn" 0x670-0x6a0 "deregister_tm_clones" 0x6a0-0x6d8 "register_tm_clones" 0x6d8-0x720 "__do_global_dtors_aux" 0x720-0x724 "frame_dummy" -0x724-0x748 "main" +0x724-0x744 "main" 0x748-0x7c8 "__libc_csu_init" 0x7c8-0x7cc "__libc_csu_fini" 0x7cc-0x7e0 "_fini" -0x7e0-0x7f8 "_IO_stdin_used" +0x7e0-0x7e4 "_IO_stdin_used" 0x7f8-0x10d80 "__FRAME_END__" 0x10d80-0x10d88 "__frame_dummy_init_array_entry" 0x10d88-0x11008 "__do_global_dtors_aux_fini_array_entry" 0x11008-0x11010 "__dso_handle" -0x11010-0x11010 "__TMC_END__" +0x11010-0x11011 "completed.8500" diff --git a/crates/examples/testfiles/elf/base-crel.o.objdump b/crates/examples/testfiles/elf/base-crel.o.objdump index 123e87d..cf87613 100644 --- a/crates/examples/testfiles/elf/base-crel.o.objdump +++ b/crates/examples/testfiles/elf/base-crel.o.objdump @@ -34,4 +34,4 @@ Dynamic symbols Dynamic relocations Symbol map -0x0-0x0 "main" +0x0-0x25 "main" diff --git a/crates/examples/testfiles/elf/base-relr-i686.objdump b/crates/examples/testfiles/elf/base-relr-i686.objdump index 047d3e5..cfe51a1 100644 --- a/crates/examples/testfiles/elf/base-relr-i686.objdump +++ b/crates/examples/testfiles/elf/base-relr-i686.objdump @@ -107,10 +107,10 @@ Import { library: "", name: "_ITM_registerTMCloneTable" } Export { name: "_IO_stdin_used", address: 2004 } Symbol map -0x1cc-0x1000 "__abi_tag" +0x1cc-0x1ec "__abi_tag" 0x1000-0x1060 "_init" -0x1060-0x1090 "_start" -0x1090-0x10a0 "__x86.get_pc_thunk.bx" +0x1060-0x108c "_start" +0x1090-0x1094 "__x86.get_pc_thunk.bx" 0x10a0-0x10e0 "deregister_tm_clones" 0x10e0-0x1130 "register_tm_clones" 0x1130-0x1180 "__do_global_dtors_aux" @@ -120,11 +120,11 @@ Symbol map 0x11cd-0x11d4 "__x86.get_pc_thunk.ax" 0x11d4-0x2000 "_fini" 0x2000-0x2004 "_fp_hw" -0x2004-0x2110 "_IO_stdin_used" +0x2004-0x2008 "_IO_stdin_used" 0x2110-0x3ec0 "__FRAME_END__" 0x3ec0-0x3ec4 "__frame_dummy_init_array_entry" 0x3ec4-0x3ec8 "__do_global_dtors_aux_fini_array_entry" 0x3ec8-0x3fd8 "_DYNAMIC" 0x3fd8-0x4004 "_GLOBAL_OFFSET_TABLE_" 0x4004-0x4008 "__dso_handle" -0x4008-0x4008 "__TMC_END__" +0x4008-0x4009 "completed.0" diff --git a/crates/examples/testfiles/elf/base-relr-x86_64.objdump b/crates/examples/testfiles/elf/base-relr-x86_64.objdump index f03f318..f26e25c 100644 --- a/crates/examples/testfiles/elf/base-relr-x86_64.objdump +++ b/crates/examples/testfiles/elf/base-relr-x86_64.objdump @@ -102,20 +102,20 @@ Import { library: "", name: "_ITM_registerTMCloneTable" } Import { library: "libc.so.6", name: "__cxa_finalize" } Symbol map -0x38c-0x1000 "__abi_tag" +0x38c-0x3ac "__abi_tag" 0x1000-0x1060 "_init" -0x1060-0x1090 "_start" +0x1060-0x1086 "_start" 0x1090-0x10c0 "deregister_tm_clones" 0x10c0-0x1100 "register_tm_clones" 0x1100-0x1140 "__do_global_dtors_aux" 0x1140-0x1149 "frame_dummy" 0x1149-0x116c "main" 0x116c-0x2000 "_fini" -0x2000-0x20f0 "_IO_stdin_used" +0x2000-0x2004 "_IO_stdin_used" 0x20f0-0x3d88 "__FRAME_END__" 0x3d88-0x3d90 "__frame_dummy_init_array_entry" 0x3d90-0x3d98 "__do_global_dtors_aux_fini_array_entry" 0x3d98-0x3fb8 "_DYNAMIC" 0x3fb8-0x4008 "_GLOBAL_OFFSET_TABLE_" 0x4008-0x4010 "__dso_handle" -0x4010-0x4010 "__TMC_END__" +0x4010-0x4011 "completed.0" diff --git a/crates/examples/testfiles/elf/base.o.objdump b/crates/examples/testfiles/elf/base.o.objdump index 0e21a5c..4823870 100644 --- a/crates/examples/testfiles/elf/base.o.objdump +++ b/crates/examples/testfiles/elf/base.o.objdump @@ -42,4 +42,4 @@ Dynamic symbols Dynamic relocations Symbol map -0x0-0x0 "main" +0x0-0x1c "main" diff --git a/crates/examples/testfiles/elf/base.objdump b/crates/examples/testfiles/elf/base.objdump index 52cc22e..7315512 100644 --- a/crates/examples/testfiles/elf/base.objdump +++ b/crates/examples/testfiles/elf/base.objdump @@ -130,20 +130,20 @@ Import { library: "libc.so.6", name: "__cxa_finalize" } Symbol map 0x520-0x570 "_init" -0x570-0x5a0 "_start" +0x570-0x59b "_start" 0x5a0-0x5e0 "deregister_tm_clones" 0x5e0-0x630 "register_tm_clones" 0x630-0x670 "__do_global_dtors_aux" 0x670-0x67a "frame_dummy" -0x67a-0x6a0 "main" -0x6a0-0x710 "__libc_csu_init" -0x710-0x714 "__libc_csu_fini" +0x67a-0x696 "main" +0x6a0-0x705 "__libc_csu_init" +0x710-0x712 "__libc_csu_fini" 0x714-0x720 "_fini" -0x720-0x874 "_IO_stdin_used" +0x720-0x724 "_IO_stdin_used" 0x874-0x200da8 "__FRAME_END__" 0x200da8-0x200db0 "__frame_dummy_init_array_entry" 0x200db0-0x200db8 "__do_global_dtors_aux_fini_array_entry" 0x200db8-0x200fb8 "_DYNAMIC" 0x200fb8-0x201008 "_GLOBAL_OFFSET_TABLE_" 0x201008-0x201010 "__dso_handle" -0x201010-0x201010 "__TMC_END__" +0x201010-0x201011 "completed.7698" diff --git a/crates/examples/testfiles/wasm/base.o.objdump b/crates/examples/testfiles/wasm/base.o.objdump index f55dd5c..a300b0b 100644 --- a/crates/examples/testfiles/wasm/base.o.objdump +++ b/crates/examples/testfiles/wasm/base.o.objdump @@ -25,6 +25,6 @@ Symbols Dynamic symbols Symbol map -0x0-0x2 ".L.str" -0x2-0x5e "__main_void" -0x5e-0x5e "main" +0x0-0xd ".L.str" +0x2-0x5d "__main_void" +0x5e-0x6d "main" diff --git a/crates/examples/testfiles/wasm/base.wasm.objdump b/crates/examples/testfiles/wasm/base.wasm.objdump index 8f22703..460411d 100644 --- a/crates/examples/testfiles/wasm/base.wasm.objdump +++ b/crates/examples/testfiles/wasm/base.wasm.objdump @@ -67,39 +67,39 @@ Dynamic symbols Symbol map 0x0-0x2 "memory" -0x2-0x5 "__wasm_call_ctors" -0x5-0x2f "_start" -0x2f-0x8b "__original_main" -0x8b-0x8e "dummy" -0x8e-0x9d "__wasm_call_dtors" -0x9d-0xd9 "printf" -0xd9-0x13e "__lseek" -0x13e-0x150 "__stdio_seek" -0x150-0x15a "__ofl_lock" -0x15a-0x2de "__stdio_exit" -0x2de-0x33c "__towrite" -0x33c-0x432 "__fwritex" -0x432-0x554 "fwrite" -0x554-0x5aa "strerror" -0x5aa-0x61d "writev" -0x61d-0x75f "__stdio_write" -0x75f-0x784 "fputs" -0x784-0x78a "abort" -0x78a-0x91f "vfprintf" -0x91f-0x2e01 "printf_core" -0x2e01-0x3035 "pop_arg" -0x3035-0x3052 "long_double_not_supported" -0x3052-0x3074 "close" -0x3074-0x3082 "__stdio_close" -0x3082-0x30e9 "__isatty" -0x30e9-0x3125 "__stdout_write" -0x3125-0x3141 "strnlen" -0x3141-0x3696 "memcpy" -0x3696-0x3814 "memset" -0x3814-0x38ca "strlen" -0x38ca-0x39d3 "memchr" -0x39d3-0x39d8 "dummy" -0x39d8-0x39e5 "__lctrans" -0x39e5-0x39ff "wctomb" -0x39ff-0x3b37 "wcrtomb" -0x3b37-0x3b37 "frexp" +0x2-0x4 "__wasm_call_ctors" +0x5-0x2e "_start" +0x2f-0x8a "__original_main" +0x8b-0x8d "dummy" +0x8e-0x9c "__wasm_call_dtors" +0x9d-0xd8 "printf" +0xd9-0x13d "__lseek" +0x13e-0x14f "__stdio_seek" +0x150-0x158 "__ofl_lock" +0x15a-0x2dd "__stdio_exit" +0x2de-0x33a "__towrite" +0x33c-0x430 "__fwritex" +0x432-0x553 "fwrite" +0x554-0x5a9 "strerror" +0x5aa-0x61b "writev" +0x61d-0x75e "__stdio_write" +0x75f-0x783 "fputs" +0x784-0x788 "abort" +0x78a-0x91d "vfprintf" +0x91f-0x2dff "printf_core" +0x2e01-0x3034 "pop_arg" +0x3035-0x3051 "long_double_not_supported" +0x3052-0x3073 "close" +0x3074-0x3081 "__stdio_close" +0x3082-0x30e8 "__isatty" +0x30e9-0x3124 "__stdout_write" +0x3125-0x313f "strnlen" +0x3141-0x3694 "memcpy" +0x3696-0x3812 "memset" +0x3814-0x38c8 "strlen" +0x38ca-0x39d2 "memchr" +0x39d3-0x39d7 "dummy" +0x39d8-0x39e4 "__lctrans" +0x39e5-0x39fd "wctomb" +0x39ff-0x3b35 "wcrtomb" +0x3b37-0x3bc6 "frexp" diff --git a/crates/examples/testfiles/wasm/global-wasm32.objdump b/crates/examples/testfiles/wasm/global-wasm32.objdump index a3a3d79..da821aa 100644 --- a/crates/examples/testfiles/wasm/global-wasm32.objdump +++ b/crates/examples/testfiles/wasm/global-wasm32.objdump @@ -40,8 +40,8 @@ Dynamic symbols Symbol map 0x0-0x1 "__memory_base" 0x1-0x2 "__table_base" -0x2-0x5 "__wasm_call_ctors" -0x5-0x400 "print" +0x2-0x4 "__wasm_call_ctors" +0x5-0x38 "print" 0x400-0x404 "__global_base" 0x404-0x408 "global2" 0x408-0x410 "__data_end" diff --git a/crates/examples/testfiles/wasm/global-wasm64-import.objdump b/crates/examples/testfiles/wasm/global-wasm64-import.objdump index 7334f19..c79a84e 100644 --- a/crates/examples/testfiles/wasm/global-wasm64-import.objdump +++ b/crates/examples/testfiles/wasm/global-wasm64-import.objdump @@ -40,8 +40,8 @@ Dynamic symbols Symbol map 0x0-0x1 "__memory_base" 0x1-0x2 "__table_base32" -0x2-0x5 "__wasm_call_ctors" -0x5-0x400 "print" +0x2-0x4 "__wasm_call_ctors" +0x5-0x48 "print" 0x400-0x404 "__global_base" 0x404-0x408 "global2" 0x408-0x410 "__data_end" diff --git a/crates/examples/testfiles/wasm/global-wasm64.objdump b/crates/examples/testfiles/wasm/global-wasm64.objdump index d7be709..38ec944 100644 --- a/crates/examples/testfiles/wasm/global-wasm64.objdump +++ b/crates/examples/testfiles/wasm/global-wasm64.objdump @@ -41,8 +41,8 @@ Dynamic symbols Symbol map 0x0-0x1 "__memory_base" 0x1-0x2 "__table_base32" -0x2-0x5 "__wasm_call_ctors" -0x5-0x400 "print" +0x2-0x4 "__wasm_call_ctors" +0x5-0x48 "print" 0x400-0x404 "__global_base" 0x404-0x408 "global2" 0x408-0x410 "__data_end" diff --git a/crates/examples/testfiles/xcoff/base.o.objdump b/crates/examples/testfiles/xcoff/base.o.objdump index 3219714..37d5ee2 100644 --- a/crates/examples/testfiles/xcoff/base.o.objdump +++ b/crates/examples/testfiles/xcoff/base.o.objdump @@ -30,7 +30,7 @@ Symbols Dynamic symbols Symbol map -0x0-0x58 ".main" -0x58-0x68 ".rodata.str1.1L...str" +0x0-0x57 ".text" +0x58-0x65 ".rodata.str1.1L...str" 0x68-0x80 "main" -0x80-0x80 ".rodata.str1.1L...str" +0x80-0x88 ".rodata.str1.1L...str" diff --git a/crates/examples/testfiles/xcoff/base.xcoff.objdump b/crates/examples/testfiles/xcoff/base.xcoff.objdump index 40b2404..5d8a351 100644 --- a/crates/examples/testfiles/xcoff/base.xcoff.objdump +++ b/crates/examples/testfiles/xcoff/base.xcoff.objdump @@ -165,7 +165,7 @@ Symbols Dynamic symbols Symbol map -0x1000001f8-0x1000002c0 ".__start" +0x1000001f8-0x1000002a5 ".__start" 0x1000002c0-0x100000300 ".__threads_init" 0x100000300-0x100000420 ".__threads_init@AF2_1" 0x100000420-0x100000448 ".__User_sinit_begin" @@ -175,14 +175,14 @@ Symbol map 0x100000598-0x1000005c0 ".__run_final_dtors" 0x1000005c0-0x1000005e8 ".atexit" 0x1000005e8-0x100000610 ".__run_initial_ctors" -0x100000610-0x100000640 ".exit" -0x100000640-0x100000698 ".main" +0x100000610-0x100000638 ".exit" +0x100000640-0x100000697 ".text" 0x100000698-0x1000006c0 ".printf" -0x1000006c0-0x1100006d0 ".rodata.str1.1L...str" +0x1000006c0-0x1000006cd ".rodata.str1.1L...str" 0x1100006d0-0x110000738 "crt0_data" -0x110000738-0x110000798 "_$STATIC" +0x110000738-0x110000791 "_$STATIC" 0x110000798-0x1100007a0 "__C_runtime_pstartup" -0x1100007a0-0x110000838 "_$STATIC" +0x1100007a0-0x110000835 "_$STATIC" 0x110000838-0x110000848 "_cdtors" 0x110000848-0x110000858 "__start" 0x110000858-0x110000870 "__threads_init" @@ -190,7 +190,7 @@ Symbol map 0x110000888-0x1100008a0 "__dftdt__L304e50f8c42_5CatchFv" 0x1100008a0-0x1100008b8 "__C_runtime_termination" 0x1100008b8-0x1100008c0 "_malloc_user_defined_name" -0x1100008c0-0x1100008c8 "p_xargc" +0x1100008c0-0x1100008c4 "p_xargc" 0x1100008c8-0x1100008d0 "__pth_init_routine" 0x1100008d0-0x1100008d8 "_bsd_init_routine" 0x1100008d8-0x1100008e0 "_xti_tli_init_routine" @@ -213,4 +213,4 @@ Symbol map 0x110000958-0x110000960 "__malloc_user_defined_name" 0x110000960-0x110000968 "errno" 0x110000968-0x110000970 ".rodata.str1.1L...str" -0x110000970-0x110000970 "printf" +0x110000970-0x110000978 "printf" diff --git a/crates/examples/testfiles/xcoff/base32.o.objdump b/crates/examples/testfiles/xcoff/base32.o.objdump index ae6ef44..fefe654 100644 --- a/crates/examples/testfiles/xcoff/base32.o.objdump +++ b/crates/examples/testfiles/xcoff/base32.o.objdump @@ -30,7 +30,7 @@ Symbols Dynamic symbols Symbol map -0x0-0x5c ".main" -0x5c-0x6c ".rodata.str1.1L...str" +0x0-0x5b ".text" +0x5c-0x69 ".rodata.str1.1L...str" 0x6c-0x78 "main" -0x78-0x78 ".rodata.str1.1L...str" +0x78-0x7c ".rodata.str1.1L...str" diff --git a/crates/examples/testfiles/xcoff/base32.xcoff.objdump b/crates/examples/testfiles/xcoff/base32.xcoff.objdump index 3a01162..e66d829 100644 --- a/crates/examples/testfiles/xcoff/base32.xcoff.objdump +++ b/crates/examples/testfiles/xcoff/base32.xcoff.objdump @@ -159,7 +159,7 @@ Symbols Dynamic symbols Symbol map -0x10000128-0x100001e0 ".__start" +0x10000128-0x100001cd ".__start" 0x100001e0-0x10000220 ".__threads_init" 0x10000220-0x10000340 ".__threads_init@AF2_1" 0x10000340-0x10000368 ".__User_sinit_begin" @@ -169,14 +169,14 @@ Symbol map 0x100004b8-0x100004e0 ".__run_final_dtors" 0x100004e0-0x10000508 ".atexit" 0x10000508-0x10000530 ".__run_initial_ctors" -0x10000530-0x10000560 ".exit" -0x10000560-0x100005bc ".main" +0x10000530-0x10000558 ".exit" +0x10000560-0x100005bb ".text" 0x100005bc-0x100005e4 ".printf" -0x100005e4-0x200005f4 ".rodata.str1.1L...str" +0x100005e4-0x100005f1 ".rodata.str1.1L...str" 0x200005f4-0x20000620 "crt0_data" -0x20000620-0x2000067c "_$STATIC" +0x20000620-0x20000679 "_$STATIC" 0x2000067c-0x20000680 "__C_runtime_pstartup" -0x20000680-0x20000708 "_$STATIC" +0x20000680-0x20000701 "_$STATIC" 0x20000708-0x20000710 "_cdtors" 0x20000710-0x20000718 "__start" 0x20000718-0x20000724 "__threads_init" @@ -206,4 +206,4 @@ Symbol map 0x20000798-0x2000079c "__malloc_user_defined_name" 0x2000079c-0x200007a0 "errno" 0x200007a0-0x200007a4 ".rodata.str1.1L...str" -0x200007a4-0x200007a4 "printf" +0x200007a4-0x200007a8 "printf" diff --git a/src/read/symbol_map.rs b/src/read/symbol_map.rs index 2efce7c..103dafb 100644 --- a/src/read/symbol_map.rs +++ b/src/read/symbol_map.rs @@ -264,6 +264,11 @@ impl SymbolMapBuilder { } /// Read the symbols from an object file to create a symbol map. + /// + /// The map will only contain defined text and data symbols. + /// The dynamic symbol table will only be used if there are no debugging symbols. + /// + /// If symbol sizes are unknown then we guess the size based on the next symbol. pub fn build<'data, O>(self, object: &O) -> SymbolMap> where O: Object<'data> + ?Sized, @@ -299,6 +304,11 @@ impl SymbolMapBuilder { _ => continue, } + // Prefer symbols that have a size. + let size = symbol.size(); + priority *= 2; + priority += (size == 0) as u32; + // Prefer global visibility. priority *= 4; priority += match symbol.scope() { @@ -312,23 +322,26 @@ impl SymbolMapBuilder { let index = !0 - symbol.index().0; // Tuple is ordered for sort. - all_symbols.push((symbol.address(), priority, index, name)); + all_symbols.push((symbol.address(), priority, index, size, name)); } // Unstable sort is okay because tuple includes index. all_symbols.sort_unstable(); let mut previous_address = !0; - for (address, _priority, _index, name) in all_symbols { + for (address, _priority, _index, size, name) in all_symbols { if address != previous_address { - symbols.push(SymbolMapName::new(address, 0, name)); + symbols.push(SymbolMapName::new(address, size, name)); previous_address = address; } } + // Guess size for symbols with zero size. let mut symbol_iter = symbols.iter_mut().rev(); let mut previous_address = symbol_iter.next().map(|s| s.address).unwrap_or(0); for symbol in symbol_iter { - symbol.size = previous_address.saturating_sub(symbol.address); + if symbol.size == 0 { + symbol.size = previous_address.saturating_sub(symbol.address); + } previous_address = symbol.address; } } diff --git a/src/read/traits.rs b/src/read/traits.rs index c43e394..598e43e 100644 --- a/src/read/traits.rs +++ b/src/read/traits.rs @@ -213,8 +213,7 @@ pub trait Object<'data>: read::private::Sealed { /// Construct a map from addresses to symbol names. /// - /// The map will only contain defined text and data symbols. - /// The dynamic symbol table will only be used if there are no debugging symbols. + /// See [`SymbolMapBuilder::build`] for details of the map contents. fn symbol_map(&self) -> SymbolMap> { SymbolMapBuilder::new().build(self) }