Does the LD --wrap feature work for library internal references?

Sebastian Huber sebastian.huber@embedded-brains.de
Mon Jan 28 09:28:00 GMT 2019


On 26/01/2019 00:52, Alan Modra wrote:
> On Fri, Jan 25, 2019 at 02:55:35PM +0100, Sebastian Huber wrote:
>> @@ -2780,6 +2780,8 @@ extern asection _bfd_elf_large_com_section;
>>   	return FALSE;							\
>>   									\
>>         h = sym_hashes[r_symndx - symtab_hdr->sh_info];			\
> Is it possible to arrange for the symbol hashes to be set up to point
> to the wrapped symbols?  I'm thinking a change to always use
> bfd_wrapped_link_hash_lookup in _bfd_generic_link_add_one_symbol might
> work.

Is this hash table only used for the relocations? We need mappings for

__real_S -> S
__wrap_S -> __wrap_S
S -> __wrap_S

I don't know why there is a special case for debug sections in 
RELOC_FOR_GLOBAL_SYMBOL():

       if (info->wrap_hash != NULL
           && (input_section->flags & SEC_DEBUGGING) != 0)
         eh = ((struct elf_link_hash_entry *)
           unwrap_hash_lookup (info, input_bfd, &eh->root));

Replacing bfd_link_hash_lookup() with bfd_wrapped_link_hash_lookup() in 
_bfd_generic_link_add_one_symbol() is not enough. The wrapping needs to 
be added at least to this area in the function as well:

   do
     {
       enum link_action action;
       int prev;

       prev = h->type;
       /* Treat symbols defined by early linker script pass as 
undefined.  */
       if (h->ldscript_def)
     prev = bfd_link_hash_undefined;
       cycle = FALSE;
       action = link_action[(int) row][prev];
       switch (action)
     {
     case FAIL:
       abort ();

1473          switch (action)
(gdb) p action
$1 = DEF
(gdb) bt
#0  _bfd_generic_link_add_one_symbol (info=0x8c2de0 <link_info>, 
abfd=0x8eec40, name=0x8f2c00 "f", flags=2, section=0x8efe20, value=0, 
string=0x0, copy=0, collect=0, hashp=0x8f2bb0) at ../../bfd/linker.c:1473
#1  0x00000000004a3172 in elf_link_add_object_symbols (abfd=0x8eec40, 
info=0x8c2de0 <link_info>) at ../../bfd/elflink.c:4701
#2  0x00000000004a57dd in bfd_elf_link_add_symbols (abfd=0x8eec40, 
info=0x8c2de0 <link_info>) at ../../bfd/elflink.c:5740
#3  0x0000000000411cb5 in load_symbols (entry=0x8c6390, 
place=0x7fffffffd5e0) at ../../ld/ldlang.c:3080
#4  0x000000000041298c in open_input_bfds (s=0x8c6390, 
mode=OPEN_BFD_NORMAL) at ../../ld/ldlang.c:3529
#5  0x00000000004197c5 in lang_process () at ../../ld/ldlang.c:7383
#6  0x000000000041def9 in main (argc=6, argv=0x7fffffffd838) at 
../../ld/ldmain.c:440

I change it like this to see what happens:

diff --git a/bfd/linker.c b/bfd/linker.c
index cf7d673f59..508ccac4c1 100644
--- a/bfd/linker.c
+++ b/bfd/linker.c
@@ -1431,20 +1431,12 @@ _bfd_generic_link_add_one_symbol (struct 
bfd_link_info *info,
    else
      row = DEF_ROW;

-  if (hashp != NULL && *hashp != NULL)
-    h = *hashp;
-  else
+  h = bfd_wrapped_link_hash_lookup (abfd, info, name, TRUE, copy, FALSE);
+  if (h == NULL)
      {
-      if (row == UNDEF_ROW || row == UNDEFW_ROW)
-       h = bfd_wrapped_link_hash_lookup (abfd, info, name, TRUE, copy, 
FALSE);
-      else
-       h = bfd_link_hash_lookup (info->hash, name, TRUE, copy, FALSE);
-      if (h == NULL)
-       {
-         if (hashp != NULL)
-           *hashp = NULL;
-         return FALSE;
-       }
+      if (hashp != NULL)
+       *hashp = NULL;
+      return FALSE;
      }

    if (info->notice_all

This leads to multiple definition errors and unresolved references:

build/ld/ld-new: main2.o: in function `__wrap_f':
main2.c:(.text+0x11): multiple definition of `__wrap_f'; 
main2.o:main2.c:(.text+0x0): first defined here
build/ld/ld-new: g.o: in function `g':
g.c:(.text+0x0): multiple definition of `__wrap_g'; 
main2.o:main2.c:(.text+0x2c): first defined here
build/ld/ld-new: main2.o: in function `__wrap_f':
main2.c:(.text+0x25): undefined reference to `f'
build/ld/ld-new: main2.o: in function `__wrap_g':
main2.c:(.text+0x40): undefined reference to `g'

I am not sure if the wrapping can be done using only the symbol hash 
table. We have the definition of the symbol and the references to it.

Attached is a second version which does the wrapping in 
RELOC_FOR_GLOBAL_SYMBOL(). It removes bfd_wrapped_link_hash_lookup(). I 
am not sure if this is a good idea. This function is used in various 
places. Maybe the wrapping needs to be done on other spots and not only 
in RELOC_FOR_GLOBAL_SYMBOL().

-- 
Sebastian Huber, embedded brains GmbH

Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone   : +49 89 189 47 41-16
Fax     : +49 89 189 47 41-09
E-Mail  : sebastian.huber@embedded-brains.de
PGP     : Public key available on request.

Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: v2-0001-HACK-Do-LD-wrap-at-relocation-level.patch
Type: text/x-patch
Size: 13817 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/binutils/attachments/20190128/a4e6ae98/attachment.bin>


More information about the Binutils mailing list