This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC] Fix PR 16910: Relocate symbol correctly if it is wrapped


ld relocate symbol in .debug_info incorrectly if it is wrapped.
In the example I gave in PR 16910, the attribute of DIE for function
main is updated incorrectly, that DW_AT_low_pc is __wrap_main, which
is wrong.

In order to fix it, RELOC_FOR_GLOBAL_SYMBOL should take care.  If a
symbol SYM is from .debug_info section (and other debug sections?), and
the SYM is wrapped, linker should look for SYM or __real_SYM instead
of __wrap_SYM.  This is what this patch does.  It is hacky to me that
it checks whether the section name is ".debug_info".  What do you
think?

I configured binutils with --disable-gdb  --enable-targets=all
--enable-64-bit-bfd on x86_64-linux and run testsuite via 'make
check'.  Test results are unchanged in binutils.sum, gas.sum and
ld.sum.

bfd:

2014-05-08  Yao Qi  <yao@codesourcery.com>

	PR ld/16910
	* elf-bfd.h (RELOC_FOR_GLOBAL_SYMBOL): If the symbol is from a
	debug section and is wrapped, look for it instead of the wrapped
	one.
---
 bfd/elf-bfd.h | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index 2c02135..aa43101 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -2429,7 +2429,28 @@ extern asection _bfd_elf_large_com_section;
       if (sym_hashes == NULL)						\
 	return FALSE;							\
 									\
-      h = sym_hashes[r_symndx - symtab_hdr->sh_info];			\
+      if (strcmp (input_section->name, ".debug_info") == 0)		\
+	{								\
+	  char *name1							\
+	    =  bfd_elf_string_from_elf_section (input_bfd,		\
+						symtab_hdr->sh_link,	\
+						symtab_hdr->sh_name);	\
+	  /* If the symbol SYM is wrapped, the attributes of debug	\
+	     information is about __real_SYM instead of __wrap_SYM.  */ \
+	  if (info->wrap_hash != NULL					\
+	      && bfd_hash_lookup (info->wrap_hash, name1, FALSE,	\
+				  FALSE) != NULL)			\
+	    {								\
+	      /* Look for SYM instead of __wrap_SYM.  */		\
+	      h = ((struct elf_link_hash_entry *)			\
+		   bfd_link_hash_lookup (info->hash, name1, FALSE,	\
+					 TRUE, FALSE));		\
+	    }								\
+	  else								\
+	    h = sym_hashes[r_symndx - symtab_hdr->sh_info];		\
+	}								\
+      else								\
+	h = sym_hashes[r_symndx - symtab_hdr->sh_info];		\
 									\
       while (h->root.type == bfd_link_hash_indirect			\
 	     || h->root.type == bfd_link_hash_warning)			\
-- 
1.9.0


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]