This is the mail archive of the 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]

[committed] Fix problem with hidden symbols on hppa-linux

This change fixes PR ld/13387, an abort in elf32-hppa.c linking

The scenario is roughly as follows:

1) elf32_hppa_hide_symbol is called with a plt.refcount of roughly 8.
   The plabel flag is not set, so the plt.refcount is reset.
2) The plabel reloc is processed and plt.refcount is incremented.
3) elf32_hppa_hide_symbol is called again but this time the plabel
   flag is set and it doesn't reset the plt.refcount.
4) However, garbage collection reduces the count to zero.
5) elf32_hppa_adjust_dynamic_symbol is called.  Seeing the zero
   plt.refcount, it decides that a PLT entry isn't needed.
6) Abort occurs processing the plabel reloc because no slot has
   been allocated.

The main fix is to set the plt.refcount to 1 in elf32_hppa_adjust_dynamic_symbol
if its value is <= 0 for symbols referenced by a plabel.

With this change, I was able to change elf32_hppa_hide_symbol so that
it is now more similar to the default hide_symbol.

Tested on hppa-unknown-linux-gnu with no regressions.  Committed to

J. David Anglin                        
National Research Council of Canada              (613) 990-0752 (FAX: 952-6602)

2011-11-06  John David Anglin  <>

	PR ld/13387
	* elf32-hppa.c (elf32_hppa_hide_symbol): Make STT_GNU_IFUNC symbol
	go through PLT.  Reset plt field with init_plt_offset.
	(elf32_hppa_adjust_dynamic_symbol): Ensure that a PLT slot is
	allocated for symbols referenced by a plabel.

Index: elf32-hppa.c
RCS file: /cvs/src/src/bfd/elf32-hppa.c,v
retrieving revision 1.181
diff -u -3 -p -r1.181 elf32-hppa.c
--- elf32-hppa.c	26 Oct 2011 09:47:58 -0000	1.181
+++ elf32-hppa.c	6 Nov 2011 18:21:46 -0000
@@ -1789,10 +1789,12 @@ elf32_hppa_hide_symbol (struct bfd_link_
-  if (! hppa_elf_hash_entry (eh)->plabel)
+  /* STT_GNU_IFUNC symbol must go through PLT.  */
+  if (! hppa_elf_hash_entry (eh)->plabel
+      && eh->type != STT_GNU_IFUNC)
       eh->needs_plt = 0;
-      eh->plt = elf_hash_table (info)->init_plt_refcount;
+      eh->plt = elf_hash_table (info)->init_plt_offset;
@@ -1814,6 +1816,13 @@ elf32_hppa_adjust_dynamic_symbol (struct
   if (eh->type == STT_FUNC
       || eh->needs_plt)
+      /* If the symbol is used by a plabel, we must allocate a PLT slot.
+	 The refcounts are not reliable when it has been hidden since
+	 hide_symbol can be called before the plabel flag is set.  */
+      if (hppa_elf_hash_entry (eh)->plabel
+	  && eh->plt.refcount <= 0)
+	eh->plt.refcount = 1;
       if (eh->plt.refcount <= 0
 	  || (eh->def_regular
 	      && eh->root.type != bfd_link_hash_defweak

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