* elf-eh-frame.c (ENSURE_NO_RELOCS): Disregard R_*_NONE relocs.
[deliverable/binutils-gdb.git] / bfd / elflink.h
index 079917ef75d5288c0c2925cd2c03b2b618eb3b28..c94519478288ee4a3848b0f748da3f61892096c0 100644 (file)
@@ -1938,19 +1938,17 @@ elf_link_add_object_symbols (abfd, info)
             might be needed here.  */
          if (isym->st_other != 0)
            {
+             unsigned char hvis, symvis, other;
+
+             /* Take the balance of OTHER from the definition.  */
+             other = (definition ? isym->st_other : h->other);
+             other &= ~ ELF_ST_VISIBILITY (-1);
+
              /* Combine visibilities, using the most constraining one.  */
-             unsigned char hvis   = ELF_ST_VISIBILITY (h->other);
-             unsigned char symvis = ELF_ST_VISIBILITY (isym->st_other);
-
-             if (symvis && (hvis > symvis || hvis == 0))
-               h->other = isym->st_other;
-
-             /* If neither has visibility, use the st_other of the
-                definition.  This is an arbitrary choice, since the
-                other bits have no general meaning.  */
-             if (!symvis && !hvis
-                 && (definition || h->other == 0))
-               h->other = isym->st_other;
+             hvis   = ELF_ST_VISIBILITY (h->other);
+             symvis = ELF_ST_VISIBILITY (isym->st_other);
+
+             h->other = other | (hvis > symvis ? hvis : symvis);
            }
 
          /* Set a flag in the hash table entry indicating the type of
@@ -2208,10 +2206,9 @@ elf_link_add_object_symbols (abfd, info)
        }
     }
 
-  /* If this is a non-traditional, non-relocateable link, try to
-     optimize the handling of the .stab/.stabstr sections.  */
+  /* If this is a non-traditional link, try to optimize the handling
+     of the .stab/.stabstr sections.  */
   if (! dynamic
-      && ! info->relocateable
       && ! info->traditional_format
       && info->hash->creator->flavour == bfd_target_elf_flavour
       && is_elf_hash_table (info)
@@ -2342,6 +2339,7 @@ elf_link_create_dynamic_sections (abfd, info)
          || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
          || ! bfd_set_section_alignment (abfd, s, 2))
        return false;
+      elf_hash_table (info)->eh_info.hdr_sec = s;
     }
 
   /* Create sections to hold version informations.  These are removed
@@ -4494,6 +4492,8 @@ struct elf_final_link_info
   size_t symbuf_count;
   /* Number of symbols which fit in symbuf.  */
   size_t symbuf_size;
+  /* And same for symshndxbuf.  */
+  size_t shndxbuf_size;
 };
 
 static boolean elf_link_output_sym
@@ -4669,8 +4669,9 @@ struct elf_link_sort_rela
   enum elf_reloc_type_class type;
   union
   {
-    Elf_Internal_Rel rel;
-    Elf_Internal_Rela rela;
+    /* We use these as arrays of size int_rels_per_ext_rel.  */
+    Elf_Internal_Rel rel[1];
+    Elf_Internal_Rela rela[1];
   } u;
 };
 
@@ -4690,13 +4691,13 @@ elf_link_sort_cmp1 (A, B)
     return 1;
   if (relativea > relativeb)
     return -1;
-  if (ELF_R_SYM (a->u.rel.r_info) < ELF_R_SYM (b->u.rel.r_info))
+  if (ELF_R_SYM (a->u.rel->r_info) < ELF_R_SYM (b->u.rel->r_info))
     return -1;
-  if (ELF_R_SYM (a->u.rel.r_info) > ELF_R_SYM (b->u.rel.r_info))
+  if (ELF_R_SYM (a->u.rel->r_info) > ELF_R_SYM (b->u.rel->r_info))
     return 1;
-  if (a->u.rel.r_offset < b->u.rel.r_offset)
+  if (a->u.rel->r_offset < b->u.rel->r_offset)
     return -1;
-  if (a->u.rel.r_offset > b->u.rel.r_offset)
+  if (a->u.rel->r_offset > b->u.rel->r_offset)
     return 1;
   return 0;
 }
@@ -4720,9 +4721,9 @@ elf_link_sort_cmp2 (A, B)
     return -1;
   if (copya > copyb)
     return 1;
-  if (a->u.rel.r_offset < b->u.rel.r_offset)
+  if (a->u.rel->r_offset < b->u.rel->r_offset)
     return -1;
-  if (a->u.rel.r_offset > b->u.rel.r_offset)
+  if (a->u.rel->r_offset > b->u.rel->r_offset)
     return 1;
   return 0;
 }
@@ -4740,6 +4741,7 @@ elf_link_sort_relocs (abfd, info, psec)
   size_t i, j, ret;
   struct elf_link_sort_rela *rela;
   struct elf_backend_data *bed = get_elf_backend_data (abfd);
+  int i2e = bed->s->int_rels_per_ext_rel;
 
   reldyn = bfd_get_section_by_name (abfd, ".rela.dyn");
   if (reldyn == NULL || reldyn->_raw_size == 0)
@@ -4763,7 +4765,23 @@ elf_link_sort_relocs (abfd, info, psec)
   if (size != reldyn->_raw_size)
     return 0;
 
-  rela = (struct elf_link_sort_rela *) bfd_zmalloc (sizeof (*rela) * count);
+  /* We waste some memory here when N = i2e is greater than 1, since
+     we allocate space for N * sizeof (*rela) where sizeof (*rela) +
+     (N - 1) * sizeof (Elf_Internal_Rel/Rela) would do.  Also, we use
+     rela[k] only when k is a multiple of N, and then we index the
+     array within the union, such that rela[k].u.rel[i], i < N, is the
+     (i+1)th internal relocation corresponding to the (k/N)th external
+     relocation.  This is done such that the relocation swap-in and
+     swap-out functions can gen pointers to arrays of internal
+     relocations that form a single external relocation.
+
+     If C permitted arrays of structures with dynamic sizes, we could
+     do better, but trying to avoid wasting space at the end of the
+     chunk from rela[k] to rela[k+N-1] would require us to allocate a
+     separate array of pointers and since most ports have N == 1, this
+     would be more wasteful.  */
+  rela = (struct elf_link_sort_rela *) bfd_zmalloc
+    (sizeof (*rela) * count * i2e);
   if (rela == NULL)
     {
       (*info->callbacks->warning)
@@ -4784,15 +4802,16 @@ elf_link_sort_relocs (abfd, info, psec)
 
            erel = (Elf_External_Rel *) o->contents;
            erelend = (Elf_External_Rel *) (o->contents + o->_raw_size);
-           s = rela + o->output_offset / sizeof (Elf_External_Rel);
-           for (; erel < erelend; erel++, s++)
+           s = rela + (o->output_offset / sizeof (Elf_External_Rel) * i2e);
+           for (; erel < erelend; erel++, s += i2e)
              {
                if (bed->s->swap_reloc_in)
-                 (*bed->s->swap_reloc_in) (abfd, (bfd_byte *) erel, &s->u.rel);
+                 (*bed->s->swap_reloc_in) (abfd, (bfd_byte *) erel,
+                                           s->u.rel);
                else
-                 elf_swap_reloc_in (abfd, erel, &s->u.rel);
+                 elf_swap_reloc_in (abfd, erel, s->u.rel);
 
-               s->type = (*bed->elf_backend_reloc_type_class) (&s->u.rela);
+               s->type = (*bed->elf_backend_reloc_type_class) (s->u.rela);
              }
          }
        else
@@ -4802,30 +4821,34 @@ elf_link_sort_relocs (abfd, info, psec)
 
            erela = (Elf_External_Rela *) o->contents;
            erelaend = (Elf_External_Rela *) (o->contents + o->_raw_size);
-           s = rela + o->output_offset / sizeof (Elf_External_Rela);
-           for (; erela < erelaend; erela++, s++)
+           s = rela + (o->output_offset / sizeof (Elf_External_Rela) * i2e);
+           for (; erela < erelaend; erela++, s += i2e)
              {
                if (bed->s->swap_reloca_in)
                  (*bed->s->swap_reloca_in) (dynobj, (bfd_byte *) erela,
-                                            &s->u.rela);
+                                            s->u.rela);
                else
-                 elf_swap_reloca_in (dynobj, erela, &s->u.rela);
+                 elf_swap_reloca_in (dynobj, erela, s->u.rela);
 
-               s->type = (*bed->elf_backend_reloc_type_class) (&s->u.rela);
+               s->type = (*bed->elf_backend_reloc_type_class) (s->u.rela);
              }
          }
       }
 
-  qsort (rela, (size_t) count, sizeof (*rela), elf_link_sort_cmp1);
-  for (ret = 0; ret < count && rela[ret].type == reloc_class_relative; ret++)
+  qsort (rela, (size_t) count, sizeof (*rela) * i2e, elf_link_sort_cmp1);
+  for (ret = 0; ret < count * i2e && rela[ret].type == reloc_class_relative;
+       ret += i2e)
     ;
-  for (i = ret, j = ret; i < count; i++)
+  for (i = ret, j = ret; i < count * i2e; i += i2e)
     {
-      if (ELF_R_SYM (rela[i].u.rel.r_info) != ELF_R_SYM (rela[j].u.rel.r_info))
+      if (ELF_R_SYM (rela[i].u.rel->r_info)
+         != ELF_R_SYM (rela[j].u.rel->r_info))
        j = i;
-      rela[i].offset = rela[j].u.rel.r_offset;
+      rela[i].offset = rela[j].u.rel->r_offset;
     }
-  qsort (rela + ret, (size_t) count - ret, sizeof (*rela), elf_link_sort_cmp2);
+  ret /= i2e;
+  qsort (rela + ret, (size_t) count - ret,
+        sizeof (*rela) * i2e, elf_link_sort_cmp2);
 
   for (o = dynobj->sections; o != NULL; o = o->next)
     if ((o->flags & (SEC_HAS_CONTENTS|SEC_LINKER_CREATED))
@@ -4839,14 +4862,14 @@ elf_link_sort_relocs (abfd, info, psec)
 
            erel = (Elf_External_Rel *) o->contents;
            erelend = (Elf_External_Rel *) (o->contents + o->_raw_size);
-           s = rela + o->output_offset / sizeof (Elf_External_Rel);
-           for (; erel < erelend; erel++, s++)
+           s = rela + (o->output_offset / sizeof (Elf_External_Rel) * i2e);
+           for (; erel < erelend; erel++, s += i2e)
              {
                if (bed->s->swap_reloc_out)
-                 (*bed->s->swap_reloc_out) (abfd, &s->u.rel,
+                 (*bed->s->swap_reloc_out) (abfd, s->u.rel,
                                             (bfd_byte *) erel);
                else
-                 elf_swap_reloc_out (abfd, &s->u.rel, erel);
+                 elf_swap_reloc_out (abfd, s->u.rel, erel);
              }
          }
        else
@@ -4856,14 +4879,14 @@ elf_link_sort_relocs (abfd, info, psec)
 
            erela = (Elf_External_Rela *) o->contents;
            erelaend = (Elf_External_Rela *) (o->contents + o->_raw_size);
-           s = rela + o->output_offset / sizeof (Elf_External_Rela);
-           for (; erela < erelaend; erela++, s++)
+           s = rela + (o->output_offset / sizeof (Elf_External_Rela) * i2e);
+           for (; erela < erelaend; erela++, s += i2e)
              {
                if (bed->s->swap_reloca_out)
-                 (*bed->s->swap_reloca_out) (dynobj, &s->u.rela,
+                 (*bed->s->swap_reloca_out) (dynobj, s->u.rela,
                                              (bfd_byte *) erela);
                else
-                 elf_swap_reloca_out (dynobj, &s->u.rela, erela);
+                 elf_swap_reloca_out (dynobj, s->u.rela, erela);
              }
          }
       }
@@ -4896,6 +4919,7 @@ elf_bfd_final_link (abfd, info)
   Elf_Internal_Sym elfsym;
   unsigned int i;
   Elf_Internal_Shdr *symtab_hdr;
+  Elf_Internal_Shdr *symtab_shndx_hdr;
   Elf_Internal_Shdr *symstrtab_hdr;
   struct elf_backend_data *bed = get_elf_backend_data (abfd);
   struct elf_outext_info eoinfo;
@@ -4949,6 +4973,7 @@ elf_bfd_final_link (abfd, info)
   finfo.symbuf = NULL;
   finfo.symshndxbuf = NULL;
   finfo.symbuf_count = 0;
+  finfo.shndxbuf_size = 0;
   finfo.first_tls_sec = NULL;
   for (o = abfd->sections; o != (asection *) NULL; o = o->next)
     if ((o->flags & SEC_THREAD_LOCAL) != 0
@@ -5169,9 +5194,7 @@ elf_bfd_final_link (abfd, info)
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   /* sh_name is set in prep_headers.  */
   symtab_hdr->sh_type = SHT_SYMTAB;
-  symtab_hdr->sh_flags = 0;
-  symtab_hdr->sh_addr = 0;
-  symtab_hdr->sh_size = 0;
+  /* sh_flags, sh_addr and sh_size all start off zero.  */
   symtab_hdr->sh_entsize = sizeof (Elf_External_Sym);
   /* sh_link is set in assign_section_numbers.  */
   /* sh_info is set below.  */
@@ -5198,9 +5221,11 @@ elf_bfd_final_link (abfd, info)
     goto error_return;
   if (elf_numsections (abfd) > SHN_LORESERVE)
     {
-      amt = finfo.symbuf_size;
+      /* Wild guess at number of output symbols.  realloc'd as needed.  */
+      amt = 2 * max_sym_count + elf_numsections (abfd) + 1000;
+      finfo.shndxbuf_size = amt;
       amt *= sizeof (Elf_External_Sym_Shndx);
-      finfo.symshndxbuf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
+      finfo.symshndxbuf = (Elf_External_Sym_Shndx *) bfd_zmalloc (amt);
       if (finfo.symshndxbuf == NULL)
        goto error_return;
     }
@@ -5260,7 +5285,7 @@ elf_bfd_final_link (abfd, info)
          if (! elf_link_output_sym (&finfo, (const char *) NULL,
                                     &elfsym, o))
            goto error_return;
-         if (i == SHN_LORESERVE)
+         if (i == SHN_LORESERVE - 1)
            i += SHN_HIRESERVE + 1 - SHN_LORESERVE;
        }
     }
@@ -5535,6 +5560,24 @@ elf_bfd_final_link (abfd, info)
   /* Now we know the size of the symtab section.  */
   off += symtab_hdr->sh_size;
 
+  symtab_shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
+  if (symtab_shndx_hdr->sh_name != 0)
+    {
+      symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX;
+      symtab_shndx_hdr->sh_entsize = sizeof (Elf_External_Sym_Shndx);
+      symtab_shndx_hdr->sh_addralign = sizeof (Elf_External_Sym_Shndx);
+      amt = bfd_get_symcount (abfd) * sizeof (Elf_External_Sym_Shndx);
+      symtab_shndx_hdr->sh_size = amt;
+
+      off = _bfd_elf_assign_file_position_for_section (symtab_shndx_hdr,
+                                                      off, true);
+
+      if (bfd_seek (abfd, symtab_shndx_hdr->sh_offset, SEEK_SET) != 0
+         || (bfd_bwrite ((PTR) finfo.symshndxbuf, amt, abfd) != amt))
+       return false;
+    }
+
+
   /* Finish up and write out the symbol string table (.strtab)
      section.  */
   symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr;
@@ -5809,17 +5852,10 @@ elf_bfd_final_link (abfd, info)
        goto error_return;
     }
 
-  if (info->eh_frame_hdr && elf_hash_table (info)->dynobj)
+  if (info->eh_frame_hdr)
     {
-      o = bfd_get_section_by_name (elf_hash_table (info)->dynobj,
-                                  ".eh_frame_hdr");
-      if (o
-         && (elf_section_data (o)->sec_info_type
-             == ELF_INFO_TYPE_EH_FRAME_HDR))
-       {
-         if (! _bfd_elf_write_section_eh_frame_hdr (abfd, o))
-           goto error_return;
-       }
+      if (! _bfd_elf_write_section_eh_frame_hdr (abfd, info))
+       goto error_return;
     }
 
   if (finfo.symstrtab != NULL)
@@ -5843,7 +5879,7 @@ elf_bfd_final_link (abfd, info)
   if (finfo.symbuf != NULL)
     free (finfo.symbuf);
   if (finfo.symshndxbuf != NULL)
-    free (finfo.symbuf);
+    free (finfo.symshndxbuf);
   for (o = abfd->sections; o != NULL; o = o->next)
     {
       if ((o->flags & SEC_RELOC) != 0
@@ -5877,7 +5913,7 @@ elf_bfd_final_link (abfd, info)
   if (finfo.symbuf != NULL)
     free (finfo.symbuf);
   if (finfo.symshndxbuf != NULL)
-    free (finfo.symbuf);
+    free (finfo.symshndxbuf);
   for (o = abfd->sections; o != NULL; o = o->next)
     {
       if ((o->flags & SEC_RELOC) != 0
@@ -5936,11 +5972,24 @@ elf_link_output_sym (finfo, name, elfsym, input_sec)
   dest = finfo->symbuf + finfo->symbuf_count;
   destshndx = finfo->symshndxbuf;
   if (destshndx != NULL)
-    destshndx += finfo->symbuf_count;
-  elf_swap_symbol_out (finfo->output_bfd, elfsym, (PTR) dest, (PTR) destshndx);
-  ++finfo->symbuf_count;
+    {
+      if (bfd_get_symcount (finfo->output_bfd) >= finfo->shndxbuf_size)
+       {
+         bfd_size_type amt;
+
+         amt = finfo->shndxbuf_size * sizeof (Elf_External_Sym_Shndx);
+         finfo->symshndxbuf = destshndx = bfd_realloc (destshndx, amt * 2);
+         if (destshndx == NULL)
+           return false;
+         memset ((char *) destshndx + amt, 0, amt);
+         finfo->shndxbuf_size *= 2;
+       }
+      destshndx += bfd_get_symcount (finfo->output_bfd);
+    }
 
-  ++ bfd_get_symcount (finfo->output_bfd);
+  elf_swap_symbol_out (finfo->output_bfd, elfsym, (PTR) dest, (PTR) destshndx);
+  finfo->symbuf_count += 1;
+  bfd_get_symcount (finfo->output_bfd) += 1;
 
   return true;
 }
@@ -5965,20 +6014,6 @@ elf_link_flush_output_syms (finfo)
        return false;
 
       hdr->sh_size += amt;
-
-      if (finfo->symshndxbuf != NULL)
-       {
-         hdr = &elf_tdata (finfo->output_bfd)->symtab_shndx_hdr;
-         pos = hdr->sh_offset + hdr->sh_size;
-         amt = finfo->symbuf_count * sizeof (Elf_External_Sym_Shndx);
-         if (bfd_seek (finfo->output_bfd, pos, SEEK_SET) != 0
-             || (bfd_bwrite ((PTR) finfo->symshndxbuf, amt, finfo->output_bfd)
-                 != amt))
-           return false;
-
-         hdr->sh_size += amt;
-       }
-
       finfo->symbuf_count = 0;
     }
 
@@ -6352,11 +6387,10 @@ elf_link_output_extsym (h, data)
       sym.st_info = ELF_ST_INFO (bindtype, ELF_ST_TYPE (sym.st_info));
     }
 
-  /* If a symbol is not defined locally, we clear the visibility
-     field.  */
+  /* If a symbol is not defined locally, we clear the visibility field.  */
   if (! finfo->info->relocateable
       && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
-    sym.st_other ^= ELF_ST_VISIBILITY (sym.st_other);
+    sym.st_other &= ~ ELF_ST_VISIBILITY (-1);
 
   /* If this symbol should be put in the .dynsym section, then put it
      there now.  We already know the symbol index.  We also fill in
@@ -6795,12 +6829,7 @@ elf_link_input_bfd (finfo, input_bfd)
             from discarded sections and section symbols from
             removed link-once sections.  Complain about relocs
             against discarded sections.  Zero relocs against removed
-            link-once sections.  We should really complain if
-            anything in the final link tries to use it, but
-            DWARF-based exception handling might have an entry in
-            .eh_frame to describe a routine in the linkonce section,
-            and it turns out to be hard to remove the .eh_frame
-            entry too.  FIXME.  */
+            link-once sections.  */
          if (!finfo->info->relocateable
              && !elf_section_ignore_discarded_relocs (o))
            {
@@ -6917,6 +6946,7 @@ elf_link_input_bfd (finfo, input_bfd)
            {
              Elf_Internal_Rela *irela;
              Elf_Internal_Rela *irelaend;
+             bfd_vma last_offset;
              struct elf_link_hash_entry **rel_hash;
              Elf_Internal_Shdr *input_rel_hdr, *input_rel_hdr2;
              unsigned int next_erel;
@@ -6937,6 +6967,9 @@ elf_link_input_bfd (finfo, input_bfd)
              rel_hash = (elf_section_data (o->output_section)->rel_hashes
                          + elf_section_data (o->output_section)->rel_count
                          + elf_section_data (o->output_section)->rel_count2);
+             last_offset = o->output_offset;
+             if (!finfo->info->relocateable)
+               last_offset += o->output_section->vma;
              for (next_erel = 0; irela < irelaend; irela++, next_erel++)
                {
                  unsigned long r_symndx;
@@ -6949,15 +6982,32 @@ elf_link_input_bfd (finfo, input_bfd)
                      next_erel = 0;
                    }
 
+                 irela->r_offset = _bfd_elf_section_offset (output_bfd,
+                                                            finfo->info, o,
+                                                            irela->r_offset);
+                 if (irela->r_offset >= (bfd_vma) -2)
+                   {
+                     /* This is a reloc for a deleted entry or somesuch.
+                        Turn it into an R_*_NONE reloc, at the same
+                        offset as the last reloc.  elf_eh_frame.c and
+                        elf_bfd_discard_info rely on reloc offsets
+                        being ordered.  */ 
+                     irela->r_offset = last_offset;
+                     irela->r_info = 0;
+                     irela->r_addend = 0;
+                     continue;
+                   }
+
                  irela->r_offset += o->output_offset;
 
                  /* Relocs in an executable have to be virtual addresses.  */
                  if (!finfo->info->relocateable)
                    irela->r_offset += o->output_section->vma;
 
-                 r_symndx = ELF_R_SYM (irela->r_info);
+                 last_offset = irela->r_offset;
 
-                 if (r_symndx == 0)
+                 r_symndx = ELF_R_SYM (irela->r_info);
+                 if (r_symndx == STN_UNDEF)
                    continue;
 
                  if (r_symndx >= locsymcount
@@ -7122,19 +7172,14 @@ elf_link_input_bfd (finfo, input_bfd)
            return false;
          break;
        case ELF_INFO_TYPE_MERGE:
-         if (! (_bfd_write_merged_section
-                (output_bfd, o, elf_section_data (o)->sec_info)))
+         if (! _bfd_write_merged_section (output_bfd, o,
+                                          elf_section_data (o)->sec_info))
            return false;
          break;
        case ELF_INFO_TYPE_EH_FRAME:
          {
-           asection *ehdrsec;
-
-           ehdrsec
-             = bfd_get_section_by_name (elf_hash_table (finfo->info)->dynobj,
-                                        ".eh_frame_hdr");
-           if (! (_bfd_elf_write_section_eh_frame (output_bfd, o, ehdrsec,
-                                                   contents)))
+           if (! _bfd_elf_write_section_eh_frame (output_bfd, finfo->info,
+                                                  o, contents))
              return false;
          }
          break;
@@ -8306,7 +8351,7 @@ elf_reloc_symbol_deleted_p (offset, cookie)
 
   for (; rcookie->rel < rcookie->relend; rcookie->rel++)
     {
-      unsigned long r_symndx = ELF_R_SYM (rcookie->rel->r_info);
+      unsigned long r_symndx;
 
       if (! rcookie->bad_symtab)
        if (rcookie->rel->r_offset > offset)
@@ -8314,6 +8359,10 @@ elf_reloc_symbol_deleted_p (offset, cookie)
       if (rcookie->rel->r_offset != offset)
        continue;
 
+      r_symndx = ELF_R_SYM (rcookie->rel->r_info);
+      if (r_symndx == SHN_UNDEF)
+       return true;
+
       if (r_symndx >= rcookie->locsymcount
          || ELF_ST_BIND (rcookie->locsyms[r_symndx].st_info) != STB_LOCAL)
        {
@@ -8365,24 +8414,18 @@ elf_bfd_discard_info (output_bfd, info)
      struct bfd_link_info *info;
 {
   struct elf_reloc_cookie cookie;
-  asection *stab, *eh, *ehdr;
+  asection *stab, *eh;
   Elf_Internal_Shdr *symtab_hdr;
   struct elf_backend_data *bed;
   bfd *abfd;
+  unsigned int count;
   boolean ret = false;
-  boolean strip = info->strip == strip_all || info->strip == strip_debugger;
 
-  if (info->relocateable
-      || info->traditional_format
+  if (info->traditional_format
       || info->hash->creator->flavour != bfd_target_elf_flavour
       || ! is_elf_hash_table (info))
     return false;
 
-  ehdr = NULL;
-  if (elf_hash_table (info)->dynobj != NULL)
-    ehdr = bfd_get_section_by_name (elf_hash_table (info)->dynobj,
-                                   ".eh_frame_hdr");
-
   for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next)
     {
       if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
@@ -8393,27 +8436,22 @@ elf_bfd_discard_info (output_bfd, info)
       if ((abfd->flags & DYNAMIC) != 0)
        continue;
 
-      eh = NULL;
-      if (ehdr)
-       {
-         eh = bfd_get_section_by_name (abfd, ".eh_frame");
-         if (eh && (eh->_raw_size == 0
-                    || bfd_is_abs_section (eh->output_section)))
-           eh = NULL;
-       }
+      eh = bfd_get_section_by_name (abfd, ".eh_frame");
+      if (eh != NULL
+         && (eh->_raw_size == 0
+             || bfd_is_abs_section (eh->output_section)))
+       eh = NULL;
 
-      stab = NULL;
-      if (!strip)
-       {
-         stab = bfd_get_section_by_name (abfd, ".stab");
-         if (stab && (stab->_raw_size == 0
-                      || bfd_is_abs_section (stab->output_section)))
-           stab = NULL;
-       }
-      if ((! stab
-          || elf_section_data(stab)->sec_info_type != ELF_INFO_TYPE_STABS)
-         && ! eh
-         && (strip || ! bed->elf_backend_discard_info))
+      stab = bfd_get_section_by_name (abfd, ".stab");
+      if (stab != NULL
+         && (stab->_raw_size == 0
+             || bfd_is_abs_section (stab->output_section)
+             || elf_section_data (stab)->sec_info_type != ELF_INFO_TYPE_STABS))
+       stab = NULL;
+
+      if (stab == NULL
+         && eh == NULL
+         && bed->elf_backend_discard_info == NULL)
        continue;
 
       symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
@@ -8422,8 +8460,7 @@ elf_bfd_discard_info (output_bfd, info)
       cookie.bad_symtab = elf_bad_symtab (abfd);
       if (cookie.bad_symtab)
        {
-         cookie.locsymcount =
-           symtab_hdr->sh_size / sizeof (Elf_External_Sym);
+         cookie.locsymcount = symtab_hdr->sh_size / sizeof (Elf_External_Sym);
          cookie.extsymoff = 0;
        }
       else
@@ -8442,16 +8479,19 @@ elf_bfd_discard_info (output_bfd, info)
            return false;
        }
 
-      if (stab)
+      if (stab != NULL)
        {
-         cookie.rels = (NAME(_bfd_elf,link_read_relocs)
-                        (abfd, stab, (PTR) NULL, (Elf_Internal_Rela *) NULL,
-                         info->keep_memory));
-         if (cookie.rels)
+         cookie.rels = NULL;
+         count = stab->reloc_count;
+         if (count != 0)
+           cookie.rels = (NAME(_bfd_elf,link_read_relocs)
+                          (abfd, stab, (PTR) NULL, (Elf_Internal_Rela *) NULL,
+                           info->keep_memory));
+         if (cookie.rels != NULL)
            {
              cookie.rel = cookie.rels;
-             cookie.relend =
-               cookie.rels + stab->reloc_count * bed->s->int_rels_per_ext_rel;
+             cookie.relend = cookie.rels;
+             cookie.relend += count * bed->s->int_rels_per_ext_rel;
              if (_bfd_discard_section_stabs (abfd, stab,
                                              elf_section_data (stab)->sec_info,
                                              elf_reloc_symbol_deleted_p,
@@ -8462,39 +8502,32 @@ elf_bfd_discard_info (output_bfd, info)
            }
        }
 
-      if (eh)
+      if (eh != NULL)
        {
          cookie.rels = NULL;
-         cookie.rel = NULL;
-         cookie.relend = NULL;
-         if (eh->reloc_count)
+         count = eh->reloc_count;
+         if (count != 0)
            cookie.rels = (NAME(_bfd_elf,link_read_relocs)
                           (abfd, eh, (PTR) NULL, (Elf_Internal_Rela *) NULL,
                            info->keep_memory));
-         if (cookie.rels)
-           {
-             cookie.rel = cookie.rels;
-             cookie.relend =
-               cookie.rels + eh->reloc_count * bed->s->int_rels_per_ext_rel;
-           }
-         if (_bfd_elf_discard_section_eh_frame (abfd, info, eh, ehdr,
+         cookie.rel = cookie.rels;
+         cookie.relend = cookie.rels;
+         if (cookie.rels != NULL)
+           cookie.relend += count * bed->s->int_rels_per_ext_rel;
+
+         if (_bfd_elf_discard_section_eh_frame (abfd, info, eh,
                                                 elf_reloc_symbol_deleted_p,
                                                 &cookie))
-           {
-             /* Relocs have been edited.  Ensure edited version is
-                used later in relocate_section.  */
-             elf_section_data (eh)->relocs = cookie.rels;
-             ret = true;
-           }
-         if (cookie.rels && elf_section_data (eh)->relocs != cookie.rels)
+           ret = true;
+
+         if (cookie.rels != NULL
+             && elf_section_data (eh)->relocs != cookie.rels)
            free (cookie.rels);
        }
 
-      if (bed->elf_backend_discard_info)
-       {
-         if (bed->elf_backend_discard_info (abfd, &cookie, info))
-           ret = true;
-       }
+      if (bed->elf_backend_discard_info != NULL
+         && (*bed->elf_backend_discard_info) (abfd, &cookie, info))
+       ret = true;
 
       if (cookie.locsyms != NULL
          && symtab_hdr->contents != (unsigned char *) cookie.locsyms)
@@ -8506,8 +8539,10 @@ elf_bfd_discard_info (output_bfd, info)
        }
     }
 
-  if (ehdr && _bfd_elf_discard_section_eh_frame_hdr (output_bfd, info, ehdr))
+  if (info->eh_frame_hdr
+      && _bfd_elf_discard_section_eh_frame_hdr (output_bfd, info))
     ret = true;
+
   return ret;
 }
 
This page took 0.033825 seconds and 4 git commands to generate.