arc: Don't generate dynamic relocation for non SEC_ALLOC sections
[deliverable/binutils-gdb.git] / bfd / elf-vxworks.c
index 2fcf01253bed2ab8a613c2764a5543314719c8b9..0984cc83e6dc2f7aa9490024b30490a45429e006 100644 (file)
@@ -1,11 +1,11 @@
 /* VxWorks support for ELF
-   Copyright 2005 Free Software Foundation, Inc.
+   Copyright (C) 2005-2020 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 /* This file provides routines used by all VxWorks targets.  */
 
-#include "bfd.h"
 #include "sysdep.h"
+#include "bfd.h"
 #include "libbfd.h"
 #include "elf-bfd.h"
 #include "elf-vxworks.h"
+#include "elf/vxworks.h"
 
 /* Return true if symbol NAME, as defined by ABFD, is one of the special
    __GOTT_BASE__ or __GOTT_INDEX__ symbols.  */
@@ -63,7 +62,7 @@ elf_vxworks_add_symbol_hook (bfd *abfd,
      give the symbol weak binding to get the desired samantics.
      This transformation will be undone in
      elf_i386_vxworks_link_output_symbol_hook. */
-  if ((info->shared || abfd->flags & DYNAMIC)
+  if ((bfd_link_pic (info) || abfd->flags & DYNAMIC)
       && elf_vxworks_gott_symbol_p (abfd, *namep))
     {
       sym->st_info = ELF_ST_INFO (STB_WEAK, ELF_ST_TYPE (sym->st_info));
@@ -88,16 +87,17 @@ elf_vxworks_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info,
   htab = elf_hash_table (info);
   bed = get_elf_backend_data (dynobj);
 
-  if (!info->shared)
+  if (!bfd_link_pic (info))
     {
-      s = bfd_make_section_with_flags (dynobj,
-                                      bed->default_use_rela_p
-                                      ? ".rela.plt.unloaded"
-                                      : ".rel.plt.unloaded",
-                                      SEC_HAS_CONTENTS | SEC_IN_MEMORY
-                                      | SEC_READONLY | SEC_LINKER_CREATED);
+      s = bfd_make_section_anyway_with_flags (dynobj,
+                                             bed->default_use_rela_p
+                                             ? ".rela.plt.unloaded"
+                                             : ".rel.plt.unloaded",
+                                             SEC_HAS_CONTENTS | SEC_IN_MEMORY
+                                             | SEC_READONLY
+                                             | SEC_LINKER_CREATED);
       if (s == NULL
-         || !bfd_set_section_alignment (dynobj, s, bed->s->log_file_align))
+         || !bfd_set_section_alignment (s, bed->s->log_file_align))
        return FALSE;
 
       *srelplt2_out = s;
@@ -126,7 +126,7 @@ elf_vxworks_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info,
 }
 
 /* Tweak magic VxWorks symbols as they are written to the output file.  */
-bfd_boolean
+int
 elf_vxworks_link_output_symbol_hook (struct bfd_link_info *info
                                       ATTRIBUTE_UNUSED,
                                     const char *name,
@@ -140,11 +140,10 @@ elf_vxworks_link_output_symbol_hook (struct bfd_link_info *info
       && elf_vxworks_gott_symbol_p (h->root.u.undef.abfd, name))
     sym->st_info = ELF_ST_INFO (STB_GLOBAL, ELF_ST_TYPE (sym->st_info));
 
-  return TRUE;
+  return 1;
 }
 
-
-/* Copy relocations into the output file.  Fixes up relocations againt PLT
+/* Copy relocations into the output file.  Fixes up relocations against PLT
    entries, then calls the generic routine.  */
 
 bfd_boolean
@@ -155,49 +154,55 @@ elf_vxworks_emit_relocs (bfd *output_bfd,
                         struct elf_link_hash_entry **rel_hash)
 {
   const struct elf_backend_data *bed;
-  Elf_Internal_Rela *irela;
-  Elf_Internal_Rela *irelaend;
   int j;
 
   bed = get_elf_backend_data (output_bfd);
 
-  irela = internal_relocs;
-  irelaend = irela + (NUM_SHDR_ENTRIES (input_rel_hdr)
-                     * bed->s->int_rels_per_ext_rel);
-  while (irela < irelaend)
+  if (output_bfd->flags & (DYNAMIC|EXEC_P))
     {
-      if ((output_bfd->flags & (DYNAMIC|EXEC_P))
-         && *rel_hash
-         && (*rel_hash)->def_dynamic
-         && !(*rel_hash)->def_regular
-         && ((*rel_hash)->root.type == bfd_link_hash_defined
-             || (*rel_hash)->root.type == bfd_link_hash_defweak)
-         && (*rel_hash)->root.u.def.section->output_section != NULL)
+      Elf_Internal_Rela *irela;
+      Elf_Internal_Rela *irelaend;
+      struct elf_link_hash_entry **hash_ptr;
+
+      for (irela = internal_relocs,
+            irelaend = irela + (NUM_SHDR_ENTRIES (input_rel_hdr)
+                                * bed->s->int_rels_per_ext_rel),
+            hash_ptr = rel_hash;
+          irela < irelaend;
+          irela += bed->s->int_rels_per_ext_rel,
+            hash_ptr++)
        {
-         /* This is a relocation from an executable or shared library
-            against a symbol in a different shared library.  We are
-            creating a definition in the output file but it does not come
-            from any of our normal (.o) files. ie. a PLT stub.
-            Normally this would be a relocation against against SHN_UNDEF
-            with the VMA of the PLT stub.  This upsets the VxWorks loader.
-            Convert it to a section-relative relocation.
-            This gets some other symbols (for instance .dynbss),
-            but is conservatively correct.  */
-         for (j = 0; j < bed->s->int_rels_per_ext_rel; j++)
+         if (*hash_ptr
+             && (*hash_ptr)->def_dynamic
+             && !(*hash_ptr)->def_regular
+             && ((*hash_ptr)->root.type == bfd_link_hash_defined
+                 || (*hash_ptr)->root.type == bfd_link_hash_defweak)
+             && (*hash_ptr)->root.u.def.section->output_section != NULL)
            {
-             asection *sec = (*rel_hash)->root.u.def.section;
-             int this_idx = sec->output_section->target_index;
+             /* This is a relocation from an executable or shared
+                library against a symbol in a different shared
+                library.  We are creating a definition in the output
+                file but it does not come from any of our normal (.o)
+                files. ie. a PLT stub.  Normally this would be a
+                relocation against against SHN_UNDEF with the VMA of
+                the PLT stub.  This upsets the VxWorks loader.
+                Convert it to a section-relative relocation.  This
+                gets some other symbols (for instance .dynbss), but
+                is conservatively correct.  */
+             for (j = 0; j < bed->s->int_rels_per_ext_rel; j++)
+               {
+                 asection *sec = (*hash_ptr)->root.u.def.section;
+                 int this_idx = sec->output_section->target_index;
 
-             irela[j].r_info = ELF32_R_INFO (this_idx,
-                 ELF32_R_TYPE (irela[j].r_info));
-             irela[j].r_addend += (*rel_hash)->root.u.def.value;
-             irela[j].r_addend += sec->output_offset;
+                 irela[j].r_info
+                   = ELF32_R_INFO (this_idx, ELF32_R_TYPE (irela[j].r_info));
+                 irela[j].r_addend += (*hash_ptr)->root.u.def.value;
+                 irela[j].r_addend += sec->output_offset;
+               }
+             /* Stop the generic routine adjusting this entry.  */
+             *hash_ptr = NULL;
            }
-         /* Stop the generic routine adjusting this entry.  */
-         *rel_hash = NULL;
        }
-      irela += bed->s->int_rels_per_ext_rel;
-      rel_hash++;
     }
   return _bfd_elf_link_output_relocs (output_bfd, input_section,
                                      input_rel_hdr, internal_relocs,
@@ -207,9 +212,8 @@ elf_vxworks_emit_relocs (bfd *output_bfd,
 
 /* Set the sh_link and sh_info fields on the static plt relocation secton.  */
 
-void
-elf_vxworks_final_write_processing (bfd *abfd,
-                                   bfd_boolean linker ATTRIBUTE_UNUSED)
+bfd_boolean
+elf_vxworks_final_write_processing (bfd *abfd)
 {
   asection * sec;
   struct bfd_elf_section_data *d;
@@ -217,11 +221,78 @@ elf_vxworks_final_write_processing (bfd *abfd,
   sec = bfd_get_section_by_name (abfd, ".rel.plt.unloaded");
   if (!sec)
     sec = bfd_get_section_by_name (abfd, ".rela.plt.unloaded");
-  if (!sec)
-    return;
-  d = elf_section_data (sec);
-  d->this_hdr.sh_link = elf_tdata (abfd)->symtab_section;
-  sec = bfd_get_section_by_name (abfd, ".plt");
   if (sec)
-    d->this_hdr.sh_info = elf_section_data (sec)->this_idx;
+    {
+      d = elf_section_data (sec);
+      d->this_hdr.sh_link = elf_onesymtab (abfd);
+      sec = bfd_get_section_by_name (abfd, ".plt");
+      if (sec)
+       d->this_hdr.sh_info = elf_section_data (sec)->this_idx;
+    }
+  return _bfd_elf_final_write_processing (abfd);
+}
+
+/* Add the dynamic entries required by VxWorks.  These point to the
+   tls sections.  */
+
+bfd_boolean
+elf_vxworks_add_dynamic_entries (bfd *output_bfd, struct bfd_link_info *info)
+{
+  if (bfd_get_section_by_name (output_bfd, ".tls_data"))
+    {
+      if (!_bfd_elf_add_dynamic_entry (info, DT_VX_WRS_TLS_DATA_START, 0)
+         || !_bfd_elf_add_dynamic_entry (info, DT_VX_WRS_TLS_DATA_SIZE, 0)
+         || !_bfd_elf_add_dynamic_entry (info, DT_VX_WRS_TLS_DATA_ALIGN, 0))
+       return FALSE;
+    }
+  if (bfd_get_section_by_name (output_bfd, ".tls_vars"))
+    {
+      if (!_bfd_elf_add_dynamic_entry (info, DT_VX_WRS_TLS_VARS_START, 0)
+         || !_bfd_elf_add_dynamic_entry (info, DT_VX_WRS_TLS_VARS_SIZE, 0))
+       return FALSE;
+    }
+  return TRUE;
 }
+
+/* If *DYN is one of the VxWorks-specific dynamic entries, then fill
+   in the value now  and return TRUE.  Otherwise return FALSE.  */
+
+bfd_boolean
+elf_vxworks_finish_dynamic_entry (bfd *output_bfd, Elf_Internal_Dyn *dyn)
+{
+  asection *sec;
+
+  switch (dyn->d_tag)
+    {
+    default:
+      return FALSE;
+
+    case DT_VX_WRS_TLS_DATA_START:
+      sec = bfd_get_section_by_name (output_bfd, ".tls_data");
+      dyn->d_un.d_ptr = sec->vma;
+      break;
+
+    case DT_VX_WRS_TLS_DATA_SIZE:
+      sec = bfd_get_section_by_name (output_bfd, ".tls_data");
+      dyn->d_un.d_val = sec->size;
+      break;
+
+    case DT_VX_WRS_TLS_DATA_ALIGN:
+      sec = bfd_get_section_by_name (output_bfd, ".tls_data");
+      dyn->d_un.d_val = (bfd_size_type) 1 << bfd_section_alignment (sec);
+      break;
+
+    case DT_VX_WRS_TLS_VARS_START:
+      sec = bfd_get_section_by_name (output_bfd, ".tls_vars");
+      dyn->d_un.d_ptr = sec->vma;
+      break;
+
+    case DT_VX_WRS_TLS_VARS_SIZE:
+      sec = bfd_get_section_by_name (output_bfd, ".tls_vars");
+      dyn->d_un.d_val = sec->size;
+      break;
+    }
+  return TRUE;
+}
+
+
This page took 0.028728 seconds and 4 git commands to generate.