ELF: Consolidate readonly_dynrelocs
[deliverable/binutils-gdb.git] / bfd / elf32-metag.c
index 07e9856fa9060ffa33b2e473acc82f604df277c7..b2cb918d4c856ef2350e14c4df31bf4878f81e14 100644 (file)
@@ -785,10 +785,6 @@ struct elf_metag_link_hash_entry
      symbol.  */
   struct elf_metag_stub_hash_entry *hsh_cache;
 
-  /* Used to count relocations for delayed sizing of relocation
-     sections.  */
-  struct elf_dyn_relocs *dyn_relocs;
-
   enum
     {
       GOT_UNKNOWN = 0, GOT_NORMAL = 1, GOT_TLS_IE = 2, GOT_TLS_LDM = 4, GOT_TLS_GD = 8
@@ -994,7 +990,6 @@ metag_link_hash_newfunc (struct bfd_hash_entry *entry,
       /* Initialize the local fields.  */
       hh = (struct elf_metag_link_hash_entry *) entry;
       hh->hsh_cache = NULL;
-      hh->dyn_relocs = NULL;
       hh->tls_type = GOT_UNKNOWN;
     }
 
@@ -2328,7 +2323,7 @@ elf_metag_check_relocs (bfd *abfd,
              /* If this is a global symbol, we count the number of
                 relocations we need for this symbol.  */
              if (hh != NULL)
-               hdh_head = &((struct elf_metag_link_hash_entry *) hh)->dyn_relocs;
+               hdh_head = &hh->eh.dyn_relocs;
              else
                {
                  /* Track dynamic relocs needed for local syms too.  */
@@ -2395,9 +2390,9 @@ elf_metag_copy_indirect_symbol (struct bfd_link_info *info,
   hh_dir = metag_elf_hash_entry (eh_dir);
   hh_ind = metag_elf_hash_entry (eh_ind);
 
-  if (hh_ind->dyn_relocs != NULL)
+  if (eh_ind->dyn_relocs != NULL)
     {
-      if (hh_dir->dyn_relocs != NULL)
+      if (eh_dir->dyn_relocs != NULL)
        {
          struct elf_dyn_relocs **hdh_pp;
          struct elf_dyn_relocs *hdh_p;
@@ -2407,11 +2402,11 @@ elf_metag_copy_indirect_symbol (struct bfd_link_info *info,
 
          /* Add reloc counts against the weak sym to the strong sym
             list.  Merge any entries against the same section.  */
-         for (hdh_pp = &hh_ind->dyn_relocs; (hdh_p = *hdh_pp) != NULL; )
+         for (hdh_pp = &eh_ind->dyn_relocs; (hdh_p = *hdh_pp) != NULL; )
            {
              struct elf_dyn_relocs *hdh_q;
 
-             for (hdh_q = hh_dir->dyn_relocs; hdh_q != NULL;
+             for (hdh_q = eh_dir->dyn_relocs; hdh_q != NULL;
                   hdh_q = hdh_q->next)
                if (hdh_q->sec == hdh_p->sec)
                  {
@@ -2423,11 +2418,11 @@ elf_metag_copy_indirect_symbol (struct bfd_link_info *info,
              if (hdh_q == NULL)
                hdh_pp = &hdh_p->next;
            }
-         *hdh_pp = hh_dir->dyn_relocs;
+         *hdh_pp = eh_dir->dyn_relocs;
        }
 
-      hh_dir->dyn_relocs = hh_ind->dyn_relocs;
-      hh_ind->dyn_relocs = NULL;
+      eh_dir->dyn_relocs = eh_ind->dyn_relocs;
+      eh_ind->dyn_relocs = NULL;
     }
 
   if (eh_ind->root.type == bfd_link_hash_indirect
@@ -2440,23 +2435,6 @@ elf_metag_copy_indirect_symbol (struct bfd_link_info *info,
   _bfd_elf_link_hash_copy_indirect (info, eh_dir, eh_ind);
 }
 
-/* Find dynamic relocs for H that apply to read-only sections.  */
-
-static asection *
-readonly_dynrelocs (struct elf_link_hash_entry *h)
-{
-  struct elf_dyn_relocs *p;
-
-  for (p = metag_elf_hash_entry (h)->dyn_relocs; p != NULL; p = p->next)
-    {
-      asection *s = p->sec->output_section;
-
-      if (s != NULL && (s->flags & SEC_READONLY) != 0)
-       return p->sec;
-    }
-  return NULL;
-}
-
 /* 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
@@ -2532,7 +2510,7 @@ elf_metag_adjust_dynamic_symbol (struct bfd_link_info *info,
 
   /* If we don't find any dynamic relocs in read-only sections, then
      we'll be keeping the dynamic relocs and avoiding the copy reloc.  */
-  if (!readonly_dynrelocs (eh))
+  if (!_bfd_elf_readonly_dynrelocs (eh))
     {
       eh->non_got_ref = 0;
       return TRUE;
@@ -2580,7 +2558,6 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
 {
   struct bfd_link_info *info;
   struct elf_metag_link_hash_table *htab;
-  struct elf_metag_link_hash_entry *hh;
   struct elf_dyn_relocs *hdh_p;
 
   if (eh->root.type == bfd_link_hash_indirect)
@@ -2687,8 +2664,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
   else
     eh->got.offset = (bfd_vma) -1;
 
-  hh = (struct elf_metag_link_hash_entry *) eh;
-  if (hh->dyn_relocs == NULL)
+  if (eh->dyn_relocs == NULL)
     return TRUE;
 
   /* If this is a -Bsymbolic shared link, then we need to discard all
@@ -2702,7 +2678,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
        {
          struct elf_dyn_relocs **hdh_pp;
 
-         for (hdh_pp = &hh->dyn_relocs; (hdh_p = *hdh_pp) != NULL; )
+         for (hdh_pp = &eh->dyn_relocs; (hdh_p = *hdh_pp) != NULL; )
            {
              hdh_p->count -= hdh_p->pc_count;
              hdh_p->pc_count = 0;
@@ -2715,11 +2691,11 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
 
       /* Also discard relocs on undefined weak syms with non-default
         visibility.  */
-      if (hh->dyn_relocs != NULL
+      if (eh->dyn_relocs != NULL
          && eh->root.type == bfd_link_hash_undefweak)
        {
          if (ELF_ST_VISIBILITY (eh->other) != STV_DEFAULT)
-           hh->dyn_relocs = NULL;
+           eh->dyn_relocs = NULL;
 
          /* Make sure undefined weak symbols are output as a dynamic
             symbol in PIEs.  */
@@ -2758,14 +2734,14 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
            goto keep;
        }
 
-      hh->dyn_relocs = NULL;
+      eh->dyn_relocs = NULL;
       return TRUE;
 
     keep: ;
     }
 
   /* Finally, allocate space.  */
-  for (hdh_p = hh->dyn_relocs; hdh_p != NULL; hdh_p = hdh_p->next)
+  for (hdh_p = eh->dyn_relocs; hdh_p != NULL; hdh_p = hdh_p->next)
     {
       asection *sreloc = elf_section_data (hdh_p->sec)->sreloc;
       sreloc->size += hdh_p->count * sizeof (Elf32_External_Rela);
@@ -2785,7 +2761,7 @@ maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p)
   if (h->root.type == bfd_link_hash_indirect)
     return TRUE;
 
-  sec = readonly_dynrelocs (h);
+  sec = _bfd_elf_readonly_dynrelocs (h);
   if (sec != NULL)
     {
       struct bfd_link_info *info = (struct bfd_link_info *) info_p;
@@ -3459,7 +3435,7 @@ metag_type_of_stub (asection *input_sec,
 #define MOV_PC_A0_3    0xa3180ca0
 
 static bfd_boolean
-metag_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg ATTRIBUTE_UNUSED)
+metag_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
 {
   struct elf_metag_stub_hash_entry *hsh;
   asection *stub_sec;
@@ -3467,9 +3443,19 @@ metag_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg ATTRIBUTE_U
   bfd_byte *loc;
   bfd_vma sym_value;
   int size;
+  struct bfd_link_info *info;
 
   /* Massage our args to the form they really have.  */
   hsh = (struct elf_metag_stub_hash_entry *) gen_entry;
+  info = (struct bfd_link_info *) in_arg;
+
+  /* Fail if the target section could not be assigned to an output
+     section.  The user should fix his linker script.  */
+  if (hsh->target_section->output_section == NULL
+      && info->non_contiguous_regions)
+    info->callbacks->einfo (_("%F%P: Could not assign '%pA' to an output section. "
+                             "Retry without --enable-non-contiguous-regions.\n"),
+                           hsh->target_section);
 
   stub_sec = hsh->stub_sec;
 
This page took 0.027282 seconds and 4 git commands to generate.