On Tue, 09 Oct 2012 20:14:51 +0200, Roland McGrath wrote: > Don't use a macro. Use a nested inline function. > I'd make it: > /* Return true if A's binding is preferable to B's. */ > bool binding_preferred (const GElf_Sym *a, const GElf_Sym *b) > (But season to taste.)
The comparison is there in both > and >= form so I do not find such function too convenient with two parameters. Thanks, Jan libdwfl/ 2012-10-09 Jan Kratochvil <[email protected]> * dwfl_module_addrsym.c (dwfl_module_addrsym): New function binding_value. Use it for both zero and non-zero size symbols comparisons. tests/ 2012-10-09 Jan Kratochvil <[email protected]> * run-addrname-test.sh: New test for symbol preferences. * testfile64.bz2: New file. diff --git a/libdwfl/dwfl_module_addrsym.c b/libdwfl/dwfl_module_addrsym.c index 4e0646e..84ce3d4 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/run-addrname-test.sh b/tests/run-addrname-test.sh index 3531643..034cf6f 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 0000000000000000000000000000000000000000..674bd5397137e49a3781b04cb50018d937340011 GIT binary patch literal 395 zcmV;60d)RCT4*^jL0KkKS*zvL!2kiRfB1j@=*eM)c>!aDK>)ta{NT_82oNA3U;r=y zYX+<|(v#IUpriFqQ`9ufp!A-TCPsq@dYUs(XQ)Pmrh%Xao}d5#0iXZ?2@z9M(HR;5 zXahq=hCtD#ng*DJiwmabqM7gEtAsjEIf9~vRiA<f9`>pd2~C&Z1o9(GUTGSJ61fo& z%_5RFm8&WNFvKLWHGqIquWbPWkizy0|2ZfNKKXNI&-+SCb)<x9qTQ)4-c5}Vg)I$< zDg&{E7TF23#0+Q_9Jq;fBj*R!8Jsm;NukV4#KSsiMT8Z++>kODHk(b27rLYu<(gEO z>3}(|5DKdR{>2sI0<%S@p<*sQMvca)yLLkp60X$^Hi8&9#^ota1~0+1-33B{Kp+r7 zU}SdrzO6pSSj9$-G=cny`UOK980RlS&Ww!%*h-5jX4)Hq#yZIoF%4P>%Vb<6JcLfj pTM&vjR<)mpw7j*1N{*Du34jUjIIUqy29p1axgwk>NLBLcV1V8+t4RO= literal 0 HcmV?d00001 _______________________________________________ elfutils-devel mailing list [email protected] https://lists.fedorahosted.org/mailman/listinfo/elfutils-devel
