ChangeLog rotation
[deliverable/binutils-gdb.git] / bfd / elfxx-sparc.c
index 3bba5aa641e06a73e0bef162fa08870c93be78b2..d7b26885ecafd2934e13dc3423665983cceea967 100644 (file)
@@ -1206,10 +1206,6 @@ _bfd_sparc_elf_create_dynamic_sections (bfd *dynobj,
   if (!_bfd_elf_create_dynamic_sections (dynobj, info))
     return FALSE;
 
-  htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
-  if (!bfd_link_pic (info))
-    htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
-
   if (htab->is_vxworks)
     {
       if (!elf_vxworks_create_dynamic_sections (dynobj, info, &htab->srelplt2))
@@ -1230,8 +1226,8 @@ _bfd_sparc_elf_create_dynamic_sections (bfd *dynobj,
        }
     }
 
-  if (!htab->elf.splt || !htab->elf.srelplt || !htab->sdynbss
-      || (!bfd_link_pic (info) && !htab->srelbss))
+  if (!htab->elf.splt || !htab->elf.srelplt || !htab->elf.sdynbss
+      || (!bfd_link_pic (info) && !htab->elf.srelbss))
     abort ();
 
   return TRUE;
@@ -1411,6 +1407,7 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 
       if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
        {
+         /* xgettext:c-format */
          _bfd_error_handler (_("%B: bad symbol index: %d"), abfd, r_symndx);
          return FALSE;
        }
@@ -1591,6 +1588,7 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
                else
                  {
                    _bfd_error_handler
+                     /* xgettext:c-format */
                      (_("%B: `%s' accessed both as normal and thread local symbol"),
                       abfd, h ? h->root.root.string : "<local>");
                    return FALSE;
@@ -2088,7 +2086,7 @@ _bfd_sparc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
   struct _bfd_sparc_elf_link_hash_table *htab;
   struct _bfd_sparc_elf_link_hash_entry * eh;
   struct _bfd_sparc_elf_dyn_relocs *p;
-  asection *s;
+  asection *s, *srel;
 
   htab = _bfd_sparc_elf_hash_table (info);
   BFD_ASSERT (htab != NULL);
@@ -2201,14 +2199,22 @@ _bfd_sparc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
      to copy the initial value out of the dynamic object and into the
      runtime process image.  We need to remember the offset into the
      .rel.bss section we are going to use.  */
+  if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+    {
+      s = htab->elf.sdynrelro;
+      srel = htab->elf.sreldynrelro;
+    }
+  else
+    {
+      s = htab->elf.sdynbss;
+      srel = htab->elf.srelbss;
+    }
   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
     {
-      htab->srelbss->size += SPARC_ELF_RELA_BYTES (htab);
+      srel->size += SPARC_ELF_RELA_BYTES (htab);
       h->needs_copy = 1;
     }
 
-  s = htab->sdynbss;
-
   return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
@@ -2659,19 +2665,19 @@ _bfd_sparc_elf_size_dynamic_sections (bfd *output_bfd,
   /* Allocate .plt and .got entries, and space for local symbols.  */
   htab_traverse (htab->loc_hash_table, allocate_local_dynrelocs, info);
 
-  if (!htab->is_vxworks
+  if (! ABI_64_P (output_bfd)
+      && !htab->is_vxworks
       && elf_hash_table (info)->dynamic_sections_created)
     {
-      if (! ABI_64_P (output_bfd))
-        {
-          /* Make space for the trailing nop in .plt.  */
-          if (htab->elf.splt->size > 0)
-            htab->elf.splt->size += 1 * SPARC_INSN_BYTES;
-        }
+      /* Make space for the trailing nop in .plt.  */
+      if (htab->elf.splt->size > 0)
+       htab->elf.splt->size += 1 * SPARC_INSN_BYTES;
 
       /* If the .got section is more than 0x1000 bytes, we add
         0x1000 to the value of _GLOBAL_OFFSET_TABLE_, so that 13
-        bit relocations have a greater chance of working.  */
+        bit relocations have a greater chance of working.
+
+        FIXME: Make this optimization work for 64-bit too.  */
       if (htab->elf.sgot->size >= 0x1000
          && elf_hash_table (info)->hgot->root.u.def.value == 0)
        elf_hash_table (info)->hgot->root.u.def.value = 0x1000;
@@ -2687,7 +2693,8 @@ _bfd_sparc_elf_size_dynamic_sections (bfd *output_bfd,
 
       if (s == htab->elf.splt
          || s == htab->elf.sgot
-         || s == htab->sdynbss
+         || s == htab->elf.sdynbss
+         || s == htab->elf.sdynrelro
          || s == htab->elf.iplt
          || s == htab->elf.sgotplt)
        {
@@ -3147,6 +3154,7 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
                name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
                                         NULL);
              _bfd_error_handler
+               /* xgettext:c-format */
                (_("%B: relocation %s against STT_GNU_IFUNC "
                   "symbol `%s' isn't handled by %s"), input_bfd,
                 _bfd_sparc_elf_howto_table[r_type].name,
@@ -3161,14 +3169,12 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
        case R_SPARC_GOTDATA_OP_HIX22:
        case R_SPARC_GOTDATA_OP_LOX10:
          if (SYMBOL_REFERENCES_LOCAL (info, h))
-           r_type = (r_type == R_SPARC_GOTDATA_OP_HIX22
-                     ? R_SPARC_GOTDATA_HIX22
-                     : R_SPARC_GOTDATA_LOX10);
-         else
-           r_type = (r_type == R_SPARC_GOTDATA_OP_HIX22
-                     ? R_SPARC_GOT22
-                     : R_SPARC_GOT10);
-         howto = _bfd_sparc_elf_howto_table + r_type;
+           {
+             r_type = (r_type == R_SPARC_GOTDATA_OP_HIX22
+                       ? R_SPARC_GOTDATA_HIX22
+                       : R_SPARC_GOTDATA_LOX10);
+             howto = _bfd_sparc_elf_howto_table + r_type;
+           }
          break;
 
        case R_SPARC_GOTDATA_OP:
@@ -3190,6 +3196,8 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
          relocation = gdopoff (info, relocation);
          break;
 
+       case R_SPARC_GOTDATA_OP_HIX22:
+       case R_SPARC_GOTDATA_OP_LOX10:
        case R_SPARC_GOT10:
        case R_SPARC_GOT13:
        case R_SPARC_GOT22:
@@ -3906,6 +3914,7 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
          && _bfd_elf_section_offset (output_bfd, info, input_section,
                                      rel->r_offset) != (bfd_vma) -1)
        _bfd_error_handler
+         /* xgettext:c-format */
          (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
           input_bfd,
           input_section,
@@ -4013,7 +4022,8 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
          r = bfd_reloc_ok;
        }
       else if (r_type == R_SPARC_HIX22
-              || r_type == R_SPARC_GOTDATA_HIX22)
+              || r_type == R_SPARC_GOTDATA_HIX22
+              || r_type == R_SPARC_GOTDATA_OP_HIX22)
        {
          bfd_vma x;
 
@@ -4032,7 +4042,8 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
                                  relocation);
        }
       else if (r_type == R_SPARC_LOX10
-              || r_type == R_SPARC_GOTDATA_LOX10)
+              || r_type == R_SPARC_GOTDATA_LOX10
+              || r_type == R_SPARC_GOTDATA_OP_LOX10)
        {
          bfd_vma x;
 
@@ -4116,7 +4127,7 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
                                          contents + rel->r_offset - 4);
                          if ((z & (0xffffffff ^ RD(~0)))
                              != (INSN_OR | RS1(O7) | RS2(G0)))
-                           break;
+                           continue;
 
                          /* The sequence was
                             or %o7, %g0, %rN
@@ -4129,7 +4140,7 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
                          reg = (y & RS1(~0)) >> 14;
                          if (reg != ((z & RD(~0)) >> 25)
                              || reg == G0 || reg == O7)
-                           break;
+                           continue;
 
                          bfd_put_32 (input_bfd, (bfd_vma) INSN_NOP,
                                      contents + rel->r_offset + 4);
@@ -4525,15 +4536,15 @@ _bfd_sparc_elf_finish_dynamic_symbol (bfd *output_bfd,
       /* This symbols needs a copy reloc.  Set it up.  */
       BFD_ASSERT (h->dynindx != -1);
 
-      s = bfd_get_linker_section (h->root.u.def.section->owner,
-                                 ".rela.bss");
-      BFD_ASSERT (s != NULL);
-
       rela.r_offset = (h->root.u.def.value
                       + h->root.u.def.section->output_section->vma
                       + h->root.u.def.section->output_offset);
       rela.r_info = SPARC_ELF_R_INFO (htab, NULL, h->dynindx, R_SPARC_COPY);
       rela.r_addend = 0;
+      if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+       s = htab->elf.sreldynrelro;
+      else
+       s = htab->elf.srelbss;
       sparc_elf_append_rela (output_bfd, s, &rela);
     }
 
@@ -4572,22 +4583,11 @@ sparc_finish_dyn (bfd *output_bfd, struct bfd_link_info *info,
   for (dyncon = sdyn->contents; dyncon < dynconend; dyncon += dynsize)
     {
       Elf_Internal_Dyn dyn;
-      const char *name;
       bfd_boolean size;
 
       bed->s->swap_dyn_in (dynobj, dyncon, &dyn);
 
-      if (htab->is_vxworks && dyn.d_tag == DT_RELASZ)
-       {
-         /* On VxWorks, DT_RELASZ should not include the relocations
-            in .rela.plt.  */
-         if (htab->elf.srelplt)
-           {
-             dyn.d_un.d_val -= htab->elf.srelplt->size;
-             bed->s->swap_dyn_out (output_bfd, &dyn, dyncon);
-           }
-       }
-      else if (htab->is_vxworks && dyn.d_tag == DT_PLTGOT)
+      if (htab->is_vxworks && dyn.d_tag == DT_PLTGOT)
        {
          /* On VxWorks, DT_PLTGOT should point to the start of the GOT,
             not to the start of the PLT.  */
@@ -4615,30 +4615,36 @@ sparc_finish_dyn (bfd *output_bfd, struct bfd_link_info *info,
        }
       else
        {
+         asection *s;
+
          switch (dyn.d_tag)
            {
-           case DT_PLTGOT:   name = ".plt"; size = FALSE; break;
-           case DT_PLTRELSZ: name = ".rela.plt"; size = TRUE; break;
-           case DT_JMPREL:   name = ".rela.plt"; size = FALSE; break;
-           default:          name = NULL; size = FALSE; break;
+           case DT_PLTGOT:
+             s = htab->elf.splt;
+             size = FALSE;
+             break;
+           case DT_PLTRELSZ:
+             s = htab->elf.srelplt;
+             size = TRUE;
+             break;
+           case DT_JMPREL:
+             s = htab->elf.srelplt;
+             size = FALSE;
+             break;
+           default:
+             continue;
            }
 
-         if (name != NULL)
+         if (s == NULL)
+           dyn.d_un.d_val = 0;
+         else
            {
-             asection *s;
-
-             s = bfd_get_linker_section (dynobj, name);
-             if (s == NULL)
-               dyn.d_un.d_val = 0;
+             if (!size)
+               dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
              else
-               {
-                 if (! size)
-                   dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
-                 else
-                   dyn.d_un.d_val = s->size;
-               }
-             bed->s->swap_dyn_out (output_bfd, &dyn, dyncon);
+               dyn.d_un.d_val = s->size;
            }
+         bed->s->swap_dyn_out (output_bfd, &dyn, dyncon);
        }
     }
   return TRUE;
This page took 0.026537 seconds and 4 git commands to generate.