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]

[PATCH] Porting the bug fix to Bug ld/19704 Missing dynamic relocation against undefined weak symbol into SPARC


https://lists.gnu.org/archive/html/bug-binutils/2016-02/msg00365.html

This bug is due to mixing PIC and Non_PIC object files for the same weak
function references without real definition to this weak function when
generating executable.

when this executable is running, the PIC version of the weak reference
behaviors differently from the NON-PIC version of the same weak
reference.

To resolve this issue, we should make the behavior of both cases
consistent: In cases where PIC and non-PIC references to same undefined
weak symbols happen, to handle the PIC case similar as the non-PIC case.

binutils Tests has been done on sparc64-unknown-linux-gnu, No
regression.

ChangeLog entry for bfd:

2017-03-21  Qing Zhao <qing.zhao@oracle.com>

        * elf32-sparc.c
        (elf_backend_fixup_symbol): New.
        * elf64-sparc.c.
        (elf_backend_fixup_symbol): New.
        * elfxx-sparc.c (UNDEFINED_WEAK_RESOLVED_TO_ZERO): New.
        (_bfd_sparc_elf_link_hash_entry): Add has_got_reloc and
        has_non_got_reloc.
        (link_hash_newfunc): Initialize has_got_reloc and
        has_non_got_reloc.
        (_bfd_sparc_elf_size_dynamic_sections): Set interp to .interp
        section.
        (_bfd_sparc_elf_copy_indirect_symbol): Copy has_got_reloc and
        has_non_got_reloc.
        (_bfd_sparc_elf_check_relocs): Set has_got_reloc and
        has_non_got_reloc.
        (_bfd_sparc_elf_fixup_symbol): New function.
        (allocate_dynrelocs): Don't allocate space for dynamic
        relocations and discard relocations against resolved undefined
        weak symbols in executable.  Don't make resolved undefined weak
        symbols in executable dynamic.  Keep dynamic non-GOT/non-PLT
        relocation against undefined weak symbols in PIE.
        (_bfd_sparc_elf_relocate_section): Don't generate dynamic
        relocations against resolved undefined weak symbols in PIE
        (_bfd_sparc_elf_finish_dynamic_symbol): Keep PLT/GOT entries
        without ynamic PLT/GOT relocations for resolved undefined weak
        symbols.
        Don't generate dynamic relocation against resolved undefined
        weak symbol in executable.
        (pie_finish_undefweak_symbol): New function.
        (_bfd_sparc_elf_finish_dynamic_sections): Call
        pie_finish_undefweak_symbol on all symbols in PIE.
        * elfxx-sparc.h
        (_bfd_sparc_elf_link_hash_table): Add interp.
        (_bfd_sparc_elf_fixup_symbol): New function.
---
 bfd/elf32-sparc.c |    1 +
 bfd/elf64-sparc.c |    2 +
 bfd/elfxx-sparc.c |  219 ++++++++++++++++++++++++++++++++++++++++++++++-------
 bfd/elfxx-sparc.h |    5 +
 4 files changed, 199 insertions(+), 28 deletions(-)

diff --git a/bfd/elf32-sparc.c b/bfd/elf32-sparc.c
index d21a2d4..86b20c7 100644
--- a/bfd/elf32-sparc.c
+++ b/bfd/elf32-sparc.c
@@ -238,6 +238,7 @@ elf32_sparc_add_symbol_hook (bfd * abfd,
 #define elf_backend_gc_sweep_hook       _bfd_sparc_elf_gc_sweep_hook
 #define elf_backend_plt_sym_val		_bfd_sparc_elf_plt_sym_val
 #define elf_backend_init_index_section	_bfd_elf_init_1_index_section
+#define elf_backend_fixup_symbol        _bfd_sparc_elf_fixup_symbol
 
 #define elf_backend_can_gc_sections 1
 #define elf_backend_can_refcount 1
diff --git a/bfd/elf64-sparc.c b/bfd/elf64-sparc.c
index 0190bd2..7425dbe 100644
--- a/bfd/elf64-sparc.c
+++ b/bfd/elf64-sparc.c
@@ -904,6 +904,8 @@ const struct elf_size_info elf64_sparc_size_info =
   _bfd_sparc_elf_finish_dynamic_symbol
 #define elf_backend_finish_dynamic_sections \
   _bfd_sparc_elf_finish_dynamic_sections
+#define elf_backend_fixup_symbol \
+  _bfd_sparc_elf_fixup_symbol
 
 #define bfd_elf64_mkobject \
   _bfd_sparc_elf_mkobject
diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c
index 80fda1b..d1647e1 100644
--- a/bfd/elfxx-sparc.c
+++ b/bfd/elfxx-sparc.c
@@ -683,6 +683,21 @@ struct _bfd_sparc_elf_dyn_relocs
   bfd_size_type pc_count;
 };
 
+/* Is an undefined weak symbol resolved to 0.  Reference to an
+ * undefined weak symbol is resolved to 0 when building executable if
+ * it isn't dynamic and
+ * 1. Has non-GOT/non-PLT relocations in text section.  
+ * Or
+ * 2. Has no GOT/PLT relocation.
+ *              */
+#define UNDEFINED_WEAK_RESOLVED_TO_ZERO(INFO, EH)               \
+  ((EH)->elf.root.type == bfd_link_hash_undefweak               \
+   && bfd_link_executable (INFO)                                \
+   && (_bfd_sparc_elf_hash_table (INFO)->interp == NULL         \
+       || !(EH)->has_got_reloc                                  \
+       || (EH)->has_non_got_reloc                               \
+       || !(INFO)->dynamic_undefined_weak))
+
 /* SPARC ELF linker hash entry.  */
 
 struct _bfd_sparc_elf_link_hash_entry
@@ -697,6 +712,13 @@ struct _bfd_sparc_elf_link_hash_entry
 #define GOT_TLS_GD      2
 #define GOT_TLS_IE      3
   unsigned char tls_type;
+
+    /* Symbol has GOT or PLT relocations.  */
+  unsigned int has_got_reloc : 1;
+
+  /* Symbol has non-GOT/non-PLT relocations in text sections.  */
+  unsigned int has_non_got_reloc : 1;
+
 };
 
 #define _bfd_sparc_elf_hash_entry(ent) ((struct _bfd_sparc_elf_link_hash_entry *)(ent))
@@ -1018,6 +1040,8 @@ link_hash_newfunc (struct bfd_hash_entry *entry,
       eh = (struct _bfd_sparc_elf_link_hash_entry *) entry;
       eh->dyn_relocs = NULL;
       eh->tls_type = GOT_UNKNOWN;
+      eh->has_got_reloc = 0;
+      eh->has_non_got_reloc = 0;
     }
 
   return entry;
@@ -1313,6 +1337,11 @@ _bfd_sparc_elf_copy_indirect_symbol (struct bfd_link_info *info,
       edir->tls_type = eind->tls_type;
       eind->tls_type = GOT_UNKNOWN;
     }
+  
+  /* Copy has_got_reloc and has_non_got_reloc */
+  edir->has_got_reloc |= eind->has_got_reloc;
+  edir->has_non_got_reloc |= eind->has_non_got_reloc;
+
   _bfd_elf_link_hash_copy_indirect (info, dir, ind);
 }
 
@@ -1400,6 +1429,7 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
       unsigned int r_type;
       unsigned long r_symndx;
       struct elf_link_hash_entry *h;
+      struct _bfd_sparc_elf_link_hash_entry *eh;
       Elf_Internal_Sym *isym;
 
       r_symndx = SPARC_ELF_R_SYMNDX (htab, rel->r_info);
@@ -1487,11 +1517,16 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	  }
 
       r_type = sparc_elf_tls_transition (info, abfd, r_type, h == NULL);
+
+      eh = (struct _bfd_sparc_elf_link_hash_entry *) h;
       switch (r_type)
 	{
 	case R_SPARC_TLS_LDM_HI22:
 	case R_SPARC_TLS_LDM_LO10:
 	  htab->tls_ldm_got.refcount += 1;
+          if (eh != NULL) 
+            eh->has_got_reloc = 1;
+          
 	  break;
 
 	case R_SPARC_TLS_LE_HIX22:
@@ -1609,6 +1644,10 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	      if (!_bfd_elf_create_got_section (htab->elf.dynobj, info))
 		return FALSE;
 	    }
+
+          if (eh != NULL)
+            eh->has_got_reloc = 1;
+
 	  break;
 
 	case R_SPARC_TLS_GD_CALL:
@@ -1677,6 +1716,10 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	      goto r_sparc_plt32;
 	  }
 	  h->plt.refcount += 1;
+
+          eh = (struct _bfd_sparc_elf_link_hash_entry *) h;
+          eh->has_got_reloc = 1;
+
 	  break;
 
 	case R_SPARC_PC10:
@@ -1729,6 +1772,8 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	case R_SPARC_UA64:
 	  if (h != NULL)
 	    h->non_got_ref = 1;
+          if (eh != NULL && (sec->flags & SEC_CODE) != 0) 
+            eh->has_non_got_reloc = 1;
 
 	r_sparc_plt32:
 	  if (h != NULL && !bfd_link_pic (info))
@@ -2073,6 +2118,24 @@ _bfd_sparc_elf_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
   return TRUE;
 }
 
+/* Remove undefined weak symbol from the dynamic symbol table if it
+   is resolved to 0.   */
+
+bfd_boolean
+_bfd_sparc_elf_fixup_symbol (struct bfd_link_info *info,
+                             struct elf_link_hash_entry *h)
+{
+  if (h->dynindx != -1
+      && UNDEFINED_WEAK_RESOLVED_TO_ZERO (info,
+                                          _bfd_sparc_elf_hash_entry (h)))
+    {
+      h->dynindx = -1;
+      _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
+                              h->dynstr_index);
+    }
+  return TRUE;
+}
+
 /* Adjust a symbol defined by a dynamic object and referenced by a
    regular object.  The current definition is in some section of the
    dynamic object, but we're not including those sections.  We have to
@@ -2228,6 +2291,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
   struct _bfd_sparc_elf_link_hash_table *htab;
   struct _bfd_sparc_elf_link_hash_entry *eh;
   struct _bfd_sparc_elf_dyn_relocs *p;
+  bfd_boolean resolved_to_zero;
 
   if (h->root.type == bfd_link_hash_indirect)
     return TRUE;
@@ -2236,6 +2300,10 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
   htab = _bfd_sparc_elf_hash_table (info);
   BFD_ASSERT (htab != NULL);
 
+  eh = (struct _bfd_sparc_elf_link_hash_entry *) h;
+
+  resolved_to_zero = UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh);
+
   if ((htab->elf.dynamic_sections_created
        && h->plt.refcount > 0)
       || (h->type == STT_GNU_IFUNC
@@ -2245,7 +2313,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
       /* Make sure this symbol is output as a dynamic symbol.
 	 Undefined weak syms won't yet be marked as dynamic.  */
       if (h->dynindx == -1
-	  && !h->forced_local)
+	  && !h->forced_local
+          && !resolved_to_zero)
 	{
 	  if (! bfd_elf_link_record_dynamic_symbol (info, h))
 	    return FALSE;
@@ -2307,11 +2376,16 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
 	  /* Make room for this entry.  */
 	  s->size += htab->plt_entry_size;
 
-	  /* We also need to make an entry in the .rela.plt section.  */
-	  if (s == htab->elf.splt)
-	    htab->elf.srelplt->size += SPARC_ELF_RELA_BYTES (htab);
-	  else
-	    htab->elf.irelplt->size += SPARC_ELF_RELA_BYTES (htab);
+          /* there should be no PLT relocation against resolved undefined
+             weak symbol in executable */
+          if (!resolved_to_zero) 
+            {
+	      /* We also need to make an entry in the .rela.plt section.  */
+	      if (s == htab->elf.splt)
+	        htab->elf.srelplt->size += SPARC_ELF_RELA_BYTES (htab);
+	      else
+	        htab->elf.irelplt->size += SPARC_ELF_RELA_BYTES (htab);
+            }
 
 	  if (htab->is_vxworks)
 	    {
@@ -2351,7 +2425,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
       /* Make sure this symbol is output as a dynamic symbol.
 	 Undefined weak syms won't yet be marked as dynamic.  */
       if (h->dynindx == -1
-	  && !h->forced_local)
+	  && !h->forced_local
+          && !resolved_to_zero)
 	{
 	  if (! bfd_elf_link_record_dynamic_symbol (info, h))
 	    return FALSE;
@@ -2366,22 +2441,25 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
       dyn = htab->elf.dynamic_sections_created;
       /* R_SPARC_TLS_IE_{HI22,LO10} needs one dynamic relocation,
 	 R_SPARC_TLS_GD_{HI22,LO10} needs one if local symbol and two if
-	 global.  */
+	 global.  No dynamic relocation against resolved undefined weak
+         symbol in executable. */
       if ((tls_type == GOT_TLS_GD && h->dynindx == -1)
 	  || tls_type == GOT_TLS_IE
 	  || h->type == STT_GNU_IFUNC)
 	htab->elf.srelgot->size += SPARC_ELF_RELA_BYTES (htab);
       else if (tls_type == GOT_TLS_GD)
 	htab->elf.srelgot->size += 2 * SPARC_ELF_RELA_BYTES (htab);
-      else if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
-						bfd_link_pic (info),
-						h))
+      else if (((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+                 && !resolved_to_zero)
+                || h->root.type != bfd_link_hash_undefweak)
+               && WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
+		                                   bfd_link_pic (info),
+						   h))
 	htab->elf.srelgot->size += SPARC_ELF_RELA_BYTES (htab);
     }
   else
     h->got.offset = (bfd_vma) -1;
 
-  eh = (struct _bfd_sparc_elf_link_hash_entry *) h;
   if (eh->dyn_relocs == NULL)
     return TRUE;
 
@@ -2422,12 +2500,44 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
 	}
 
       /* Also discard relocs on undefined weak syms with non-default
-	 visibility.  */
+	 visibility or in PIE.  */
       if (eh->dyn_relocs != NULL
 	  && h->root.type == bfd_link_hash_undefweak)
 	{
-	  if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
-	    eh->dyn_relocs = NULL;
+          /* Undefined weak symbol is never bound locally in shared
+            library.  */
+
+	  if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+              || resolved_to_zero)
+            {
+              if (h->non_got_ref)
+                {
+                  /* Keep dynamic non-GOT/non-PLT relocation so that we
+                     can branch to 0 without PLT.  */
+                  struct _bfd_sparc_elf_dyn_relocs **pp;
+
+                  for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
+                    if (p->pc_count == 0)
+                      *pp = p->next;
+                    else
+                      {
+                        /* Remove other relocations.  */
+                        p->count = p->pc_count;
+                        pp = &p->next;
+                      }
+
+                  if (eh->dyn_relocs != NULL)
+                    {
+                      /* Make sure undefined weak symbols are output
+                         as dynamic symbols in PIEs for dynamic non-GOT
+                         non-PLT reloations.  */
+                      if (! bfd_elf_link_record_dynamic_symbol (info, h))
+                        return FALSE;
+                    }
+                }
+              else
+	        eh->dyn_relocs = NULL;
+            }
 
 	  /* Make sure undefined weak symbols are output as a dynamic
 	     symbol in PIEs.  */
@@ -2445,7 +2555,9 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
 	 symbols which turn out to need copy relocs or are not
 	 dynamic.  */
 
-      if (!h->non_got_ref
+      if ((!h->non_got_ref
+           || (h->root.type == bfd_link_hash_undefweak
+               && !resolved_to_zero))
 	  && ((h->def_dynamic
 	       && !h->def_regular)
 	      || (htab->elf.dynamic_sections_created
@@ -2455,7 +2567,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
 	  /* Make sure this symbol is output as a dynamic symbol.
 	     Undefined weak syms won't yet be marked as dynamic.  */
 	  if (h->dynindx == -1
-	      && !h->forced_local)
+	      && !h->forced_local
+              && !resolved_to_zero)
 	    {
 	      if (! bfd_elf_link_record_dynamic_symbol (info, h))
 		return FALSE;
@@ -2564,12 +2677,13 @@ _bfd_sparc_elf_size_dynamic_sections (bfd *output_bfd,
     {
       /* Set the contents of the .interp section to the interpreter.  */
       if (bfd_link_executable (info) && !info->nointerp)
-	{
-	  s = bfd_get_linker_section (dynobj, ".interp");
-	  BFD_ASSERT (s != NULL);
-	  s->size = htab->dynamic_interpreter_size;
-	  s->contents = (unsigned char *) htab->dynamic_interpreter;
-	}
+        {
+          s = bfd_get_linker_section (dynobj, ".interp");
+          BFD_ASSERT (s != NULL);
+          s->size = htab->dynamic_interpreter_size;
+          s->contents = (unsigned char *) htab->dynamic_interpreter;
+          htab->interp = s;
+        }
     }
 
   /* Set up .got offsets for local syms, and space for local dynamic
@@ -3007,12 +3121,14 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
       reloc_howto_type *howto;
       unsigned long r_symndx;
       struct elf_link_hash_entry *h;
+      struct _bfd_sparc_elf_link_hash_entry *eh;
       Elf_Internal_Sym *sym;
       asection *sec;
       bfd_vma relocation, off;
       bfd_reloc_status_type r;
       bfd_boolean is_plt = FALSE;
       bfd_boolean unresolved_reloc;
+      bfd_boolean resolved_to_zero;
 
       r_type = SPARC_ELF_R_TYPE (rel->r_info);
       if (r_type == R_SPARC_GNU_VTINHERIT
@@ -3191,6 +3307,10 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
 	    }
 	}
 
+      eh = (struct _bfd_sparc_elf_link_hash_entry *) h;
+      resolved_to_zero = (eh != NULL
+                          && UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh));
+
       switch (r_type)
 	{
 	case R_SPARC_GOTDATA_OP_HIX22:
@@ -3419,10 +3539,14 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
 	      || is_vxworks_tls)
 	    break;
 
+          /* Copy dynamic function pointer relocations.  Don't generate
+             dynamic relocations against resolved undefined weak symbols
+             in PIE */
 	  if ((bfd_link_pic (info)
 	       && (h == NULL
-		   || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
-		   || h->root.type != bfd_link_hash_undefweak)
+		   || ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+                        && !resolved_to_zero) 
+		       || h->root.type != bfd_link_hash_undefweak))
 	       && (! howto->pc_relative
 		   || !SYMBOL_CALLS_LOCAL (info, h)))
 	      || (!bfd_link_pic (info)
@@ -3431,7 +3555,8 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
 		  && !h->non_got_ref
 		  && ((h->def_dynamic
 		       && !h->def_regular)
-		      || h->root.type == bfd_link_hash_undefweak
+		      || (h->root.type == bfd_link_hash_undefweak
+                          && !resolved_to_zero)
 		      || h->root.type == bfd_link_hash_undefined)))
 	    {
 	      Elf_Internal_Rela outrel;
@@ -4352,11 +4477,20 @@ _bfd_sparc_elf_finish_dynamic_symbol (bfd *output_bfd,
 {
   struct _bfd_sparc_elf_link_hash_table *htab;
   const struct elf_backend_data *bed;
+  struct _bfd_sparc_elf_link_hash_entry  *eh;
+  bfd_boolean local_undefweak;
 
   htab = _bfd_sparc_elf_hash_table (info);
   BFD_ASSERT (htab != NULL);
   bed = get_elf_backend_data (output_bfd);
 
+  eh = (struct _bfd_sparc_elf_link_hash_entry *) h;
+
+  /* We keep PLT/GOT entries without dynamic PLT/GOT relocations for
+     resolved undefined weak symbols in executable so that their
+     references have value 0 at run-time.  */
+  local_undefweak = UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh);
+
   if (h->plt.offset != (bfd_vma) -1)
     {
       asection *splt;
@@ -4480,7 +4614,8 @@ _bfd_sparc_elf_finish_dynamic_symbol (bfd *output_bfd,
       loc += rela_index * bed->s->sizeof_rela;
       bed->s->swap_reloca_out (output_bfd, &rela, loc);
 
-      if (!h->def_regular)
+      if (!local_undefweak
+          && !h->def_regular)
 	{
 	  /* Mark the symbol as undefined, rather than as defined in
 	     the .plt section.  Leave the value alone.  */
@@ -4494,9 +4629,12 @@ _bfd_sparc_elf_finish_dynamic_symbol (bfd *output_bfd,
 	}
     }
 
+  /* Don't generate dynamic GOT relocation against undefined weak
+     symbol in executable.  */
   if (h->got.offset != (bfd_vma) -1
       && _bfd_sparc_elf_hash_entry(h)->tls_type != GOT_TLS_GD
-      && _bfd_sparc_elf_hash_entry(h)->tls_type != GOT_TLS_IE)
+      && _bfd_sparc_elf_hash_entry(h)->tls_type != GOT_TLS_IE
+      && !local_undefweak)
     {
       asection *sgot;
       asection *srela;
@@ -4787,6 +4925,26 @@ finish_local_dynamic_symbol (void **slot, void *inf)
 					       h, NULL);
 }
 
+/* Finish up undefined weak symbol handling in PIE.  Fill its PLT entry
+   here since undefined weak symbol may not be dynamic and may not be
+   called for _bfd_sparc_elf_finish_dynamic_symbol.  */
+
+static bfd_boolean
+pie_finish_undefweak_symbol (struct bfd_hash_entry *bh,
+                             void *inf)
+{
+  struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) bh;
+  struct bfd_link_info *info = (struct bfd_link_info *) inf;
+
+  if (h->root.type != bfd_link_hash_undefweak
+      || h->dynindx != -1)
+    return TRUE;
+
+  return _bfd_sparc_elf_finish_dynamic_symbol (info->output_bfd, info,
+                                               h, NULL);
+}
+
+
 bfd_boolean
 _bfd_sparc_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
 {
@@ -4853,6 +5011,11 @@ _bfd_sparc_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *i
   /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols.  */
   htab_traverse (htab->loc_hash_table, finish_local_dynamic_symbol, info);
 
+  /* Fill PLT entries for undefined weak symbols in PIE.  */
+  if (bfd_link_pie (info))
+    bfd_hash_traverse (&info->hash->table,
+                       pie_finish_undefweak_symbol,
+                       info);
   return TRUE;
 }
 
diff --git a/bfd/elfxx-sparc.h b/bfd/elfxx-sparc.h
index 15322df..f5bb6cc 100644
--- a/bfd/elfxx-sparc.h
+++ b/bfd/elfxx-sparc.h
@@ -46,6 +46,9 @@ struct _bfd_sparc_elf_link_hash_table
 {
   struct elf_link_hash_table elf;
 
+  /* short-cuts to get to dynamic linker sections . */
+  asection *interp;
+
   union
   {
     bfd_signed_vma refcount;
@@ -136,6 +139,8 @@ extern bfd_boolean _bfd_sparc_elf_finish_dynamic_symbol
    Elf_Internal_Sym *sym);
 extern bfd_boolean _bfd_sparc_elf_finish_dynamic_sections
   (bfd *, struct bfd_link_info *);
+extern bfd_boolean _bfd_sparc_elf_fixup_symbol
+  (struct bfd_link_info *, struct elf_link_hash_entry *);
 extern bfd_boolean _bfd_sparc_elf_object_p
   (bfd *);
 extern bfd_vma _bfd_sparc_elf_plt_sym_val
-- 
1.7.1


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