From: Jan Kratochvil Date: Wed, 10 Oct 2012 06:04:01 +0000 (+0200) Subject: libdwfl/ X-Git-Tag: elfutils-0.156~81 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=78dec228b3cfb2f9300cd0b682ebf416c9674c91;p=thirdparty%2Felfutils.git libdwfl/ * dwfl_module_addrsym.c (dwfl_module_addrsym): New function binding_value. Use it for both zero and non-zero size symbols comparisons. tests/ * run-addrname-test.sh: New test for symbol preferences. * testfile64.bz2: New file. Signed-off-by: Jan Kratochvil --- diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog index 403b0ec7b..4a5f4eb1d 100644 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog @@ -1,3 +1,9 @@ +2012-10-10 Jan Kratochvil + + * dwfl_module_addrsym.c (dwfl_module_addrsym): New function + binding_value. Use it for both zero and non-zero size symbols + comparisons. + 2012-10-01 Mark Wielaard * cu.c (cudie_offset): Don't use type_sig8, it might not be diff --git a/libdwfl/dwfl_module_addrsym.c b/libdwfl/dwfl_module_addrsym.c index 4e0646e19..fdc95fc0c 100644 --- a/libdwfl/dwfl_module_addrsym.c +++ b/libdwfl/dwfl_module_addrsym.c @@ -106,12 +106,26 @@ dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr addr, if (sym.st_size == 0 || addr - sym.st_value < sym.st_size) { + /* Return GELF_ST_BIND as higher-is-better integer. */ + inline int binding_value (const GElf_Sym *symp) + { + switch (GELF_ST_BIND (symp->st_info)) + { + case STB_GLOBAL: + return 3; + case STB_WEAK: + return 2; + case STB_LOCAL: + return 1; + default: + return 0; + } + } /* This symbol is a better candidate than the current one if it's closer to ADDR or is global when it was local. */ if (closest_name == NULL || closest_sym->st_value < sym.st_value - || (GELF_ST_BIND (closest_sym->st_info) - < GELF_ST_BIND (sym.st_info))) + || binding_value (closest_sym) < binding_value (&sym)) { if (sym.st_size != 0) { @@ -133,13 +147,17 @@ dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr addr, } } /* When the beginning of its range is no closer, - the end of its range might be. But do not - replace a global symbol with a local! */ + the end of its range might be. Otherwise follow + GELF_ST_BIND preference. If all are equal prefer + the first symbol found. */ else if (sym.st_size != 0 && closest_sym->st_value == sym.st_value - && closest_sym->st_size > sym.st_size - && (GELF_ST_BIND (closest_sym->st_info) - <= GELF_ST_BIND (sym.st_info))) + && ((closest_sym->st_size > sym.st_size + && (binding_value (closest_sym) + <= binding_value (&sym))) + || (closest_sym->st_size >= sym.st_size + && (binding_value (closest_sym) + < binding_value (&sym))))) { *closest_sym = sym; closest_shndx = shndx; diff --git a/tests/ChangeLog b/tests/ChangeLog index 37e214ef9..ac1a1f878 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,8 @@ +2012-10-10 Jan Kratochvil + + * run-addrname-test.sh: New test for symbol preferences. + * testfile64.bz2: New file. + 2012-10-01 Mark Wielaard * Makefile.am (TESTS_ENVIRONMENT): Define valgrind_cmd if USE_VALGRIND. diff --git a/tests/run-addrname-test.sh b/tests/run-addrname-test.sh index 353164395..034cf6f08 100755 --- a/tests/run-addrname-test.sh +++ b/tests/run-addrname-test.sh @@ -211,4 +211,85 @@ local_outer+0x9 ??:0 EOF +# .macro global label size +#\label: .globl \label +# .size \label, \size +# .endm +# .macro weak label size +#\label: .weak \label +# .size \label, \size +# .endm +# .macro local label size +#\label: .size \label, \size +# .endm +# .macro offset val +# .ifne (. - _start) - \val +# .err +# .endif +# .byte \val +# .endm +# +#_start: +# offset 0 +# +# local glocal, 1 +# weak gweak, 1 +# global gglobal1, 2 +# global gglobal2, 1 +# global gglobal3, 1 +# offset 1 +# /* Symbols end here. */ +# offset 2 +# /* gglobal1 ends here. */ +# offset 3 +# +# local g0local, 0 +# weak g0weak, 0 +# global g0global1, 0 +# global g0global2, 0 +# offset 4 +# +# local wlocal, 1 +# weak wweak1, 2 +# weak wweak2, 1 +# weak wweak3, 1 +# offset 5 +# /* Symbols end here. */ +# offset 6 +# /* wweak1 ends here. */ +# offset 7 +# +# local w0local, 0 +# weak w0weak1, 0 +# weak w0weak2, 0 +# offset 8 +# +# local llocal1, 2 +# local llocal2, 1 +# local llocal3, 1 +# offset 9 +# /* Symbols end here. */ +# offset 10 +# /* llocal1 ends here. */ +# offset 11 +# +# local l0local1, 0 +# local l0local2, 0 +# offset 12 +testfiles testfile64 +testrun_compare ../src/addr2line -S -e testfile64 1 4 5 8 9 12 <<\EOF +gglobal2 +??:0 +g0global2 +??:0 +wweak2 +??:0 +w0weak2 +??:0 +llocal2 +??:0 +l0local2 +??:0 +EOF + exit 0 diff --git a/tests/testfile64.bz2 b/tests/testfile64.bz2 new file mode 100644 index 000000000..674bd5397 Binary files /dev/null and b/tests/testfile64.bz2 differ