bfd: prevent all but undef weak syms from becoming dynamic in sparc.
authorEgeyar Bagcioglu <egeyar.bagcioglu@oracle.com>
Thu, 29 Jun 2017 11:28:27 +0000 (04:28 -0700)
committerJose E. Marchesi <jose.marchesi@oracle.com>
Thu, 29 Jun 2017 11:28:27 +0000 (04:28 -0700)
Prevent sparc backend making symbols dynamic unless they are undefined
weak. Use R_SPARC_RELATIVE for the symbols which are not dynamic in PIC.

This patch is tested on sparc64-unknown-linux-gnu, no regressions are
found.

bfd/ChangeLog:

2017-06-29  Egeyar Bagcioglu  <egeyar.bagcioglu@oracle.com>

* elfxx-sparc.c (allocate_dynrelocs): Don't make a symbol dynamic
unless it is undefined weak.
* elfxx-sparc.c (_bfd_sparc_elf_relocate_section): Set the flag
relative_reloc to direct non-dynamic symbols to R_SPARC_RELATIVE
relocation.
* elfxx-sparc.c (_bfd_sparc_elf_finish_dynamic_symbol): If symbol
        is not dynamic in PIC, abort.

bfd/ChangeLog
bfd/elfxx-sparc.c

index 5045c818d3c00a6a0e93e7faa36951950b028a0b..7195221c0c957fa4021b24bd9fa218ad245e3514 100644 (file)
@@ -1,3 +1,13 @@
+2017-06-29  Egeyar Bagcioglu  <egeyar.bagcioglu@oracle.com>
+
+       * elfxx-sparc.c (allocate_dynrelocs): Don't make a symbol dynamic
+       unless it is undefined weak.
+       * elfxx-sparc.c (_bfd_sparc_elf_relocate_section): Set the flag
+       relative_reloc to direct non-dynamic symbols to R_SPARC_RELATIVE
+       relocation.
+       * elfxx-sparc.c (_bfd_sparc_elf_finish_dynamic_symbol): If symbol
+        is not dynamic in PIC, abort.
+
 2017-06-29  Jiong Wang  <jiong.wang@arm.com>
 
         PR ld/21402
index a9362a31ac12b4d6eef29bf43166da8d8109c7b6..1fd214143a3de8786cae9c3e9ad97b7138a301f1 100644 (file)
@@ -2310,7 +2310,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
         Undefined weak syms won't yet be marked as dynamic.  */
       if (h->dynindx == -1
          && !h->forced_local
-          && !resolved_to_zero)
+          && !resolved_to_zero
+          && h->root.type == bfd_link_hash_undefweak)
        {
          if (! bfd_elf_link_record_dynamic_symbol (info, h))
            return FALSE;
@@ -2422,7 +2423,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
         Undefined weak syms won't yet be marked as dynamic.  */
       if (h->dynindx == -1
          && !h->forced_local
-          && !resolved_to_zero)
+          && !resolved_to_zero
+          && h->root.type == bfd_link_hash_undefweak)
        {
          if (! bfd_elf_link_record_dynamic_symbol (info, h))
            return FALSE;
@@ -2564,7 +2566,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
             Undefined weak syms won't yet be marked as dynamic.  */
          if (h->dynindx == -1
              && !h->forced_local
-              && !resolved_to_zero)
+              && !resolved_to_zero
+              && h->root.type == bfd_link_hash_undefweak)
            {
              if (! bfd_elf_link_record_dynamic_symbol (info, h))
                return FALSE;
@@ -3125,6 +3128,7 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
       bfd_boolean is_plt = FALSE;
       bfd_boolean unresolved_reloc;
       bfd_boolean resolved_to_zero;
+      bfd_boolean relative_reloc;
 
       r_type = SPARC_ELF_R_TYPE (rel->r_info);
       if (r_type == R_SPARC_GNU_VTINHERIT
@@ -3349,6 +3353,7 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
          if (htab->elf.sgot == NULL)
            abort ();
 
+         relative_reloc = FALSE;
          if (h != NULL)
            {
              bfd_boolean dyn;
@@ -3382,6 +3387,16 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
                      SPARC_ELF_PUT_WORD (htab, output_bfd, relocation,
                                          htab->elf.sgot->contents + off);
                      h->got.offset |= 1;
+
+                     if (h->dynindx == -1
+                         && !h->forced_local
+                         && h->root.type != bfd_link_hash_undefweak
+                         && bfd_link_pic (info))
+                       {
+                         /* If this symbol isn't dynamic in PIC
+                            generate R_SPARC_RELATIVE here.  */
+                         relative_reloc = TRUE;
+                       }
                    }
                }
              else
@@ -3401,25 +3416,9 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
                off &= ~1;
              else
                {
-
                  if (bfd_link_pic (info))
                    {
-                     asection *s;
-                     Elf_Internal_Rela outrel;
-
-                     /* We need to generate a R_SPARC_RELATIVE reloc
-                        for the dynamic linker.  */
-                     s = htab->elf.srelgot;
-                     BFD_ASSERT (s != NULL);
-
-                     outrel.r_offset = (htab->elf.sgot->output_section->vma
-                                        + htab->elf.sgot->output_offset
-                                        + off);
-                     outrel.r_info = SPARC_ELF_R_INFO (htab, NULL,
-                                                       0, R_SPARC_RELATIVE);
-                     outrel.r_addend = relocation;
-                     relocation = 0;
-                     sparc_elf_append_rela (output_bfd, s, &outrel);
+                     relative_reloc = TRUE;
                    }
 
                  SPARC_ELF_PUT_WORD (htab, output_bfd, relocation,
@@ -3427,6 +3426,27 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
                  local_got_offsets[r_symndx] |= 1;
                }
            }
+
+         if (relative_reloc)
+           {
+             asection *s;
+             Elf_Internal_Rela outrel;
+
+             /* We need to generate a R_SPARC_RELATIVE reloc
+                for the dynamic linker.  */
+             s = htab->elf.srelgot;
+             BFD_ASSERT (s != NULL);
+
+             outrel.r_offset = (htab->elf.sgot->output_section->vma
+                                + htab->elf.sgot->output_offset
+                                + off);
+             outrel.r_info = SPARC_ELF_R_INFO (htab, NULL,
+                                               0, R_SPARC_RELATIVE);
+             outrel.r_addend = relocation;
+             relocation = 0;
+             sparc_elf_append_rela (output_bfd, s, &outrel);
+           }
+
          relocation = htab->elf.sgot->output_offset + off - got_base;
          break;
 
@@ -4482,6 +4502,13 @@ _bfd_sparc_elf_finish_dynamic_symbol (bfd *output_bfd,
 
   eh = (struct _bfd_sparc_elf_link_hash_entry *) h;
 
+  /* Abort if the symbol is not dynamic in PIC */
+  if (h->dynindx == -1
+      && !h->forced_local
+      && h->root.type != bfd_link_hash_undefweak
+      && bfd_link_pic (info))
+    abort();
+
   /* 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.  */