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

Reply via email to