PowerPC VLE typo fix
[deliverable/binutils-gdb.git] / bfd / elfxx-sparc.c
index 050993ce1b3fd0d5ef3f0b6183fb4e063a948fb2..80fda1b0e04ff80c3c0206e624d58120e25ab817 100644 (file)
@@ -1,5 +1,5 @@
 /* SPARC-specific support for ELF
-   Copyright (C) 2005-2016 Free Software Foundation, Inc.
+   Copyright (C) 2005-2017 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -2086,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);
@@ -2199,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->elf.srelbss->size += SPARC_ELF_RELA_BYTES (htab);
+      srel->size += SPARC_ELF_RELA_BYTES (htab);
       h->needs_copy = 1;
     }
 
-  s = htab->elf.sdynbss;
-
   return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
@@ -2686,6 +2694,7 @@ _bfd_sparc_elf_size_dynamic_sections (bfd *output_bfd,
       if (s == htab->elf.splt
          || s == htab->elf.sgot
          || s == htab->elf.sdynbss
+         || s == htab->elf.sdynrelro
          || s == htab->elf.iplt
          || s == htab->elf.sgotplt)
        {
@@ -2918,6 +2927,33 @@ gdopoff (struct bfd_link_info *info, bfd_vma address)
   return address - got_base;
 }
 
+/* Return whether H is local and its ADDRESS is within 4G of
+   _GLOBAL_OFFSET_TABLE_ and thus the offset may be calculated by a
+   sethi, xor sequence.  */
+
+static bfd_boolean
+gdop_relative_offset_ok (struct bfd_link_info *info,
+                        struct elf_link_hash_entry *h,
+                        bfd_vma address ATTRIBUTE_UNUSED)
+{
+  if (!SYMBOL_REFERENCES_LOCAL (info, h))
+    return FALSE;
+  /* If H is undefined, ADDRESS will be zero.  We can't allow a
+     relative offset to "zero" when producing PIEs or shared libs.
+     Note that to get here with an undefined symbol it must also be
+     hidden or internal visibility.  */
+  if (bfd_link_pic (info)
+      && h != NULL
+      && (h->root.type == bfd_link_hash_undefweak
+         || h->root.type == bfd_link_hash_undefined))
+    return FALSE;
+#ifdef BFD64
+  return gdopoff (info, address) + ((bfd_vma) 1 << 32) < (bfd_vma) 2 << 32;
+#else
+  return TRUE;
+#endif
+}
+
 /* Relocate a SPARC ELF section.  */
 
 bfd_boolean
@@ -3159,7 +3195,7 @@ _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))
+         if (gdop_relative_offset_ok (info, h, relocation))
            {
              r_type = (r_type == R_SPARC_GOTDATA_OP_HIX22
                        ? R_SPARC_GOTDATA_HIX22
@@ -3169,7 +3205,7 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd,
          break;
 
        case R_SPARC_GOTDATA_OP:
-         if (SYMBOL_REFERENCES_LOCAL (info, h))
+         if (gdop_relative_offset_ok (info, h, relocation))
            {
              bfd_vma insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
 
@@ -4527,15 +4563,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 == htab->elf.sdynrelro)
+       s = htab->elf.sreldynrelro;
+      else
+       s = htab->elf.srelbss;
       sparc_elf_append_rela (output_bfd, s, &rela);
     }
 
This page took 0.024177 seconds and 4 git commands to generate.