* config.bfd (arm-*-netbsdelf*): Add target.
[deliverable/binutils-gdb.git] / bfd / elf32-sh.c
index b91e8380c20fe86a5fef03d069597c08b122578f..1a711916bb07f9f8feb789894fb1bc9a24b91971 100644 (file)
@@ -134,8 +134,8 @@ static reloc_howto_type sh_elf_howto_table[] =
         complain_overflow_signed, /* complain_on_overflow */
         sh_elf_ignore_reloc,   /* special_function */
         "R_SH_REL32",          /* name */
-        false,                 /* partial_inplace */
-        0,                     /* src_mask */
+        true,                  /* partial_inplace */
+        0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
         true),                 /* pcrel_offset */
 
@@ -1023,6 +1023,7 @@ sh_elf_relax_section (abfd, sec, link_info, again)
      boolean *again;
 {
   Elf_Internal_Shdr *symtab_hdr;
+  Elf_Internal_Shdr *shndx_hdr;
   Elf_Internal_Rela *internal_relocs;
   Elf_Internal_Rela *free_relocs = NULL;
   boolean have_code;
@@ -1031,6 +1032,7 @@ sh_elf_relax_section (abfd, sec, link_info, again)
   bfd_byte *free_contents = NULL;
   Elf32_External_Sym *extsyms = NULL;
   Elf32_External_Sym *free_extsyms = NULL;
+  Elf_External_Sym_Shndx *shndx_buf = NULL;
 
   *again = false;
 
@@ -1045,6 +1047,7 @@ sh_elf_relax_section (abfd, sec, link_info, again)
     sec->_cooked_size = sec->_raw_size;
 
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+  shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
 
   internal_relocs = (_bfd_elf32_link_read_relocs
                     (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
@@ -1151,26 +1154,47 @@ sh_elf_relax_section (abfd, sec, link_info, again)
            extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
          else
            {
-             extsyms = (Elf32_External_Sym *) bfd_malloc (symtab_hdr->sh_size);
+             bfd_size_type amt;
+
+             amt = symtab_hdr->sh_info;
+             amt *= sizeof (Elf32_External_Sym);
+             extsyms = (Elf32_External_Sym *) bfd_malloc (amt);
              if (extsyms == NULL)
                goto error_return;
              free_extsyms = extsyms;
              if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
-                 || (bfd_bread (extsyms, symtab_hdr->sh_size, abfd)
-                     != symtab_hdr->sh_size))
+                 || bfd_bread ((PTR) extsyms, amt, abfd) != amt)
+               goto error_return;
+             symtab_hdr->contents = (bfd_byte *) extsyms;
+           }
+
+         if (shndx_hdr->sh_size != 0)
+           {
+             bfd_size_type amt;
+
+             amt = symtab_hdr->sh_info;
+             amt *= sizeof (Elf_External_Sym_Shndx);
+             shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
+             if (shndx_buf == NULL)
+               goto error_return;
+             if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
+                 || bfd_bread ((PTR) shndx_buf, amt, abfd) != amt)
                goto error_return;
+             shndx_hdr->contents = (bfd_byte *) shndx_buf;
            }
        }
 
       /* Get the value of the symbol referred to by the reloc.  */
       if (ELF32_R_SYM (irelfn->r_info) < symtab_hdr->sh_info)
        {
+         /* A local symbol.  */
+         Elf32_External_Sym *esym;
+         Elf_External_Sym_Shndx *shndx;
          Elf_Internal_Sym isym;
 
-         /* A local symbol.  */
-         bfd_elf32_swap_symbol_in (abfd,
-                                   extsyms + ELF32_R_SYM (irelfn->r_info),
-                                   &isym);
+         esym = extsyms + ELF32_R_SYM (irelfn->r_info);
+         shndx = shndx_buf + (shndx_buf ? ELF32_R_SYM (irelfn->r_info) : 0);
+         bfd_elf32_swap_symbol_in (abfd, esym, shndx, &isym);
 
          if (isym.st_shndx != _bfd_elf_section_from_bfd_section (abfd, sec))
            {
@@ -1236,7 +1260,6 @@ sh_elf_relax_section (abfd, sec, link_info, again)
       elf_section_data (sec)->this_hdr.contents = contents;
       free_contents = NULL;
 
-      symtab_hdr->contents = (bfd_byte *) extsyms;
       free_extsyms = NULL;
 
       /* Replace the jsr with a bsr.  */
@@ -1362,16 +1385,12 @@ sh_elf_relax_section (abfd, sec, link_info, again)
          elf_section_data (sec)->this_hdr.contents = contents;
          free_contents = NULL;
 
-         symtab_hdr->contents = (bfd_byte *) extsyms;
          free_extsyms = NULL;
        }
     }
 
   if (free_relocs != NULL)
-    {
-      free (free_relocs);
-      free_relocs = NULL;
-    }
+    free (free_relocs);
 
   if (free_contents != NULL)
     {
@@ -1382,19 +1401,21 @@ sh_elf_relax_section (abfd, sec, link_info, again)
          /* Cache the section contents for elf_link_input_bfd.  */
          elf_section_data (sec)->this_hdr.contents = contents;
        }
-      free_contents = NULL;
+    }
+
+  if (shndx_buf != NULL)
+    {
+      shndx_hdr->contents = NULL;
+      free (shndx_buf);
     }
 
   if (free_extsyms != NULL)
     {
       if (! link_info->keep_memory)
-       free (free_extsyms);
-      else
        {
-         /* Cache the symbols for elf_link_input_bfd.  */
-         symtab_hdr->contents = extsyms;
+         symtab_hdr->contents = NULL;
+         free (free_extsyms);
        }
-      free_extsyms = NULL;
     }
 
   return true;
@@ -1404,8 +1425,17 @@ sh_elf_relax_section (abfd, sec, link_info, again)
     free (free_relocs);
   if (free_contents != NULL)
     free (free_contents);
+  if (shndx_buf != NULL)
+    {
+      shndx_hdr->contents = NULL;
+      free (shndx_buf);
+    }
   if (free_extsyms != NULL)
-    free (free_extsyms);
+    {
+      symtab_hdr->contents = NULL;
+      free (free_extsyms);
+    }
+
   return false;
 }
 
@@ -1421,20 +1451,27 @@ sh_elf_relax_delete_bytes (abfd, sec, addr, count)
      int count;
 {
   Elf_Internal_Shdr *symtab_hdr;
+  Elf_Internal_Shdr *shndx_hdr;
   Elf32_External_Sym *extsyms;
-  int shndx, index;
+  unsigned int sec_shndx;
   bfd_byte *contents;
   Elf_Internal_Rela *irel, *irelend;
   Elf_Internal_Rela *irelalign;
   bfd_vma toaddr;
   Elf32_External_Sym *esym, *esymend;
-  struct elf_link_hash_entry *sym_hash;
+  Elf_External_Sym_Shndx *shndx_buf, *shndx;
+  struct elf_link_hash_entry **sym_hashes;
+  struct elf_link_hash_entry **end_hashes;
+  unsigned int symcount;
   asection *o;
 
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
 
-  shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
+  shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
+  shndx_buf = (Elf_External_Sym_Shndx *) shndx_hdr->contents;
+
+  sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
 
   contents = elf_section_data (sec)->this_hdr.contents;
 
@@ -1534,10 +1571,11 @@ sh_elf_relax_delete_bytes (abfd, sec, addr, count)
              range to be adjusted, and hence must be changed.  */
          if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
            {
-             bfd_elf32_swap_symbol_in (abfd,
-                                       extsyms + ELF32_R_SYM (irel->r_info),
-                                       &sym);
-             if (sym.st_shndx == shndx
+             esym = extsyms + ELF32_R_SYM (irel->r_info);
+             shndx = shndx_buf + (shndx_buf ? ELF32_R_SYM (irel->r_info) : 0);
+             bfd_elf32_swap_symbol_in (abfd, esym, shndx, &sym);
+
+             if (sym.st_shndx == sec_shndx
                  && (sym.st_value <= addr
                      || sym.st_value >= toaddr))
                {
@@ -1795,11 +1833,12 @@ sh_elf_relax_delete_bytes (abfd, sec, addr, count)
          if (ELF32_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
            continue;
 
-         bfd_elf32_swap_symbol_in (abfd,
-                                   extsyms + ELF32_R_SYM (irelscan->r_info),
-                                   &sym);
 
-         if (sym.st_shndx == shndx
+         esym = extsyms + ELF32_R_SYM (irelscan->r_info);
+         shndx = shndx_buf + (shndx_buf ? ELF32_R_SYM (irelscan->r_info) : 0);
+         bfd_elf32_swap_symbol_in (abfd, esym, shndx, &sym);
+
+         if (sym.st_shndx == sec_shndx
              && (sym.st_value <= addr
                  || sym.st_value >= toaddr))
            {
@@ -1836,40 +1875,40 @@ sh_elf_relax_delete_bytes (abfd, sec, addr, count)
     }
 
   /* Adjust the local symbols defined in this section.  */
+  shndx = shndx_buf;
   esym = extsyms;
   esymend = esym + symtab_hdr->sh_info;
-  for (; esym < esymend; esym++)
+  for (; esym < esymend; esym++, shndx = (shndx ? shndx + 1 : NULL))
     {
       Elf_Internal_Sym isym;
+      Elf_External_Sym_Shndx dummy;
 
-      bfd_elf32_swap_symbol_in (abfd, esym, &isym);
+      bfd_elf32_swap_symbol_in (abfd, esym, shndx, &isym);
 
-      if (isym.st_shndx == shndx
+      if (isym.st_shndx == sec_shndx
          && isym.st_value > addr
          && isym.st_value < toaddr)
        {
          isym.st_value -= count;
-         bfd_elf32_swap_symbol_out (abfd, &isym, esym);
+         bfd_elf32_swap_symbol_out (abfd, &isym, (PTR) esym, (PTR) &dummy);
        }
     }
 
   /* Now adjust the global symbols defined in this section.  */
-  esym = extsyms + symtab_hdr->sh_info;
-  esymend = extsyms + (symtab_hdr->sh_size / sizeof (Elf32_External_Sym));
-  for (index = 0; esym < esymend; esym++, index++)
+  symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+             - symtab_hdr->sh_info);
+  sym_hashes = elf_sym_hashes (abfd);
+  end_hashes = sym_hashes + symcount;
+  for (; sym_hashes < end_hashes; sym_hashes++)
     {
-      Elf_Internal_Sym isym;
-
-      bfd_elf32_swap_symbol_in (abfd, esym, &isym);
-      sym_hash = elf_sym_hashes (abfd)[index];
-      if (isym.st_shndx == shndx
-         && ((sym_hash)->root.type == bfd_link_hash_defined
-             || (sym_hash)->root.type == bfd_link_hash_defweak)
-         && (sym_hash)->root.u.def.section == sec
-         && (sym_hash)->root.u.def.value > addr
-         && (sym_hash)->root.u.def.value < toaddr)
+      struct elf_link_hash_entry *sym_hash = *sym_hashes;
+      if ((sym_hash->root.type == bfd_link_hash_defined
+          || sym_hash->root.type == bfd_link_hash_defweak)
+         && sym_hash->root.u.def.section == sec
+         && sym_hash->root.u.def.value > addr
+         && sym_hash->root.u.def.value < toaddr)
        {
-         (sym_hash)->root.u.def.value -= count;
+         sym_hash->root.u.def.value -= count;
        }
     }
 
@@ -2960,7 +2999,7 @@ sh_elf_discard_copies (h, ignore)
 static boolean
 sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                         contents, relocs, local_syms, local_sections)
-     bfd *output_bfd ATTRIBUTE_UNUSED;
+     bfd *output_bfd;
      struct bfd_link_info *info;
      bfd *input_bfd;
      asection *input_section;
@@ -3026,7 +3065,11 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
 
       howto = sh_elf_howto_table + r_type;
 
-      /* This is a final link.  */
+      /* For relocs that aren't partial_inplace, we get the addend from
+         the relocation.  */
+      if (! howto->partial_inplace)
+       addend = rel->r_addend;
+
       h = NULL;
       sym = NULL;
       sec = NULL;
@@ -3037,7 +3080,6 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
          relocation = (sec->output_section->vma
                        + sec->output_offset
                        + sym->st_value);
-
          if (info->relocateable)
            {
              /* This is a relocateable link.  We don't have to change
@@ -3046,10 +3088,64 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                 section symbol winds up in the output section.  */
              sym = local_syms + r_symndx;
              if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
-               goto final_link_relocate;
+               {
+                 if (! howto->partial_inplace)
+                   {
+                     /* For relocations with the addend in the
+                        relocation, we need just to update the addend.
+                        All real relocs are of type partial_inplace; this
+                        code is mostly for completeness.  */
+                     rel->r_addend += sec->output_offset + sym->st_value;
+
+                     continue;
+                   }
+
+                 /* Relocs of type partial_inplace need to pick up the
+                    contents in the contents and add the offset resulting
+                    from the changed location of the section symbol.
+                    Using _bfd_final_link_relocate (e.g. goto
+                    final_link_relocate) here would be wrong, because
+                    relocations marked pc_relative would get the current
+                    location subtracted, and we must only do that at the
+                    final link.  */
+                 r = _bfd_relocate_contents (howto, input_bfd,
+                                             sec->output_offset
+                                             + sym->st_value,
+                                             contents + rel->r_offset);
+                 goto relocation_done;
+               }
 
              continue;
            }
+         else if (! howto->partial_inplace)
+           {
+             relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel);
+             addend = rel->r_addend;
+           }
+         else if ((sec->flags & SEC_MERGE)
+                  && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+           {
+             asection *msec;
+
+             if (howto->rightshift || howto->src_mask != 0xffffffff)
+               {
+                 (*_bfd_error_handler)
+                   (_("%s(%s+0x%lx): %s relocation against SEC_MERGE section"),
+                    bfd_archive_filename (input_bfd),
+                    bfd_get_section_name (input_bfd, input_section),
+                    (long) rel->r_offset, howto->name);
+                 return false;
+               }
+
+              addend = bfd_get_32 (input_bfd, contents + rel->r_offset);
+              msec = sec;
+              addend =
+               _bfd_elf_rel_local_sym (output_bfd, sym, &msec, addend)
+               - relocation;
+             addend += msec->output_section->vma + msec->output_offset;
+             bfd_put_32 (input_bfd, addend, contents + rel->r_offset);
+             addend = 0;
+           }
        }
       else
        {
@@ -3187,6 +3283,7 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
        case R_SH_DIR32:
        case R_SH_REL32:
          if (info->shared
+             && r_symndx != 0
              && (input_section->flags & SEC_ALLOC) != 0
              && (r_type != R_SH_REL32
                  || (h != NULL
@@ -3224,22 +3321,11 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
 
              skip = false;
 
-             if (elf_section_data (input_section)->stab_info == NULL)
-               outrel.r_offset = rel->r_offset;
-             else
-               {
-                 bfd_vma off;
-
-                 off = (_bfd_stab_section_offset
-                        (output_bfd, &elf_hash_table (info)->stab_info,
-                         input_section,
-                         &elf_section_data (input_section)->stab_info,
-                         rel->r_offset));
-                 if (off == (bfd_vma) -1)
-                   skip = true;
-                 outrel.r_offset = off;
-               }
-
+             outrel.r_offset =
+               _bfd_elf_section_offset (output_bfd, info, input_section,
+                                        rel->r_offset);
+             if (outrel.r_offset == (bfd_vma) -1)
+               skip = true;
              outrel.r_offset += (input_section->output_section->vma
                                  + input_section->output_offset);
 
@@ -3253,7 +3339,8 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                  BFD_ASSERT (h != NULL && h->dynindx != -1);
                  relocate = false;
                  outrel.r_info = ELF32_R_INFO (h->dynindx, R_SH_REL32);
-                 outrel.r_addend = rel->r_addend;
+                 outrel.r_addend
+                   = bfd_get_32 (input_bfd, contents + rel->r_offset);
                }
              else
                {
@@ -3266,14 +3353,18 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                    {
                      relocate = true;
                      outrel.r_info = ELF32_R_INFO (0, R_SH_RELATIVE);
-                     outrel.r_addend = relocation + rel->r_addend;
+                     outrel.r_addend
+                       = relocation + bfd_get_32 (input_bfd,
+                                                  contents + rel->r_offset);
                    }
                  else
                    {
                      BFD_ASSERT (h->dynindx != -1);
                      relocate = false;
                      outrel.r_info = ELF32_R_INFO (h->dynindx, R_SH_DIR32);
-                     outrel.r_addend = relocation + rel->r_addend;
+                     outrel.r_addend
+                       = relocation + bfd_get_32 (input_bfd,
+                                                  contents + rel->r_offset);
                    }
                }
 
@@ -3290,8 +3381,6 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
              if (! relocate)
                continue;
            }
-         else if (r_type == R_SH_DIR32)
-           addend = rel->r_addend;
          goto final_link_relocate;
 
        case R_SH_GOT32:
@@ -3471,6 +3560,7 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
          }
        }
 
+    relocation_done:
       if (r != bfd_reloc_ok)
        {
          switch (r)
@@ -3520,11 +3610,14 @@ sh_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
      asymbol **symbols;
 {
   Elf_Internal_Shdr *symtab_hdr;
+  Elf_Internal_Shdr *shndx_hdr;
   asection *input_section = link_order->u.indirect.section;
   bfd *input_bfd = input_section->owner;
   asection **sections = NULL;
   Elf_Internal_Rela *internal_relocs = NULL;
   Elf32_External_Sym *external_syms = NULL;
+  Elf_External_Sym_Shndx *shndx_buf = NULL;
+  Elf_External_Sym_Shndx *shndx;
   Elf_Internal_Sym *internal_syms = NULL;
 
   /* We only need to handle the case of relaxing, or of having a
@@ -3537,6 +3630,7 @@ sh_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
                                                       symbols);
 
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+  shndx_hdr = &elf_tdata (input_bfd)->symtab_shndx_hdr;
 
   memcpy (data, elf_section_data (input_section)->this_hdr.contents,
          (size_t) input_section->_raw_size);
@@ -3547,19 +3641,31 @@ sh_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
       Elf_Internal_Sym *isymp;
       asection **secpp;
       Elf32_External_Sym *esym, *esymend;
-      bfd_size_type size;
+      bfd_size_type amt;
 
       if (symtab_hdr->contents != NULL)
        external_syms = (Elf32_External_Sym *) symtab_hdr->contents;
-      else
+      else if (symtab_hdr->sh_info != 0)
        {
-         size = symtab_hdr->sh_info;
-         size *= sizeof (Elf32_External_Sym);
-         external_syms = (Elf32_External_Sym *) bfd_malloc (size);
-         if (external_syms == NULL && size != 0)
+         amt = symtab_hdr->sh_info;
+         amt *= sizeof (Elf32_External_Sym);
+         external_syms = (Elf32_External_Sym *) bfd_malloc (amt);
+         if (external_syms == NULL)
            goto error_return;
          if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0
-             || bfd_bread (external_syms, size, input_bfd) != size)
+             || bfd_bread ((PTR) external_syms, amt, input_bfd) != amt)
+           goto error_return;
+       }
+
+      if (symtab_hdr->sh_info != 0 && shndx_hdr->sh_size != 0)
+       {
+         amt = symtab_hdr->sh_info;
+         amt *= sizeof (Elf_External_Sym_Shndx);
+         shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
+         if (shndx_buf == NULL)
+           goto error_return;
+         if (bfd_seek (input_bfd, shndx_hdr->sh_offset, SEEK_SET) != 0
+             || bfd_bread ((PTR) shndx_buf, amt, input_bfd) != amt)
            goto error_return;
        }
 
@@ -3569,41 +3675,35 @@ sh_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
       if (internal_relocs == NULL)
        goto error_return;
 
-      size = symtab_hdr->sh_info;
-      size *= sizeof (Elf_Internal_Sym);
-      internal_syms = (Elf_Internal_Sym *) bfd_malloc (size);
-      if (internal_syms == NULL && symtab_hdr->sh_info > 0)
+      amt = symtab_hdr->sh_info;
+      amt *= sizeof (Elf_Internal_Sym);
+      internal_syms = (Elf_Internal_Sym *) bfd_malloc (amt);
+      if (internal_syms == NULL && amt != 0)
        goto error_return;
 
-      size = symtab_hdr->sh_info;
-      size *= sizeof (asection *);
-      sections = (asection **) bfd_malloc (size);
-      if (sections == NULL && symtab_hdr->sh_info > 0)
+      amt = symtab_hdr->sh_info;
+      amt *= sizeof (asection *);
+      sections = (asection **) bfd_malloc (amt);
+      if (sections == NULL && amt != 0)
        goto error_return;
 
-      isymp = internal_syms;
-      secpp = sections;
-      esym = external_syms;
-      esymend = esym + symtab_hdr->sh_info;
-      for (; esym < esymend; ++esym, ++isymp, ++secpp)
+      for (isymp = internal_syms, secpp = sections, shndx = shndx_buf,
+            esym = external_syms, esymend = esym + symtab_hdr->sh_info;
+          esym < esymend;
+          ++esym, ++isymp, ++secpp, shndx = (shndx ? shndx + 1 : NULL))
        {
          asection *isec;
 
-         bfd_elf32_swap_symbol_in (input_bfd, esym, isymp);
+         bfd_elf32_swap_symbol_in (input_bfd, esym, shndx, isymp);
 
          if (isymp->st_shndx == SHN_UNDEF)
            isec = bfd_und_section_ptr;
-         else if (isymp->st_shndx > 0 && isymp->st_shndx < SHN_LORESERVE)
-           isec = bfd_section_from_elf_index (input_bfd, isymp->st_shndx);
          else if (isymp->st_shndx == SHN_ABS)
            isec = bfd_abs_section_ptr;
          else if (isymp->st_shndx == SHN_COMMON)
            isec = bfd_com_section_ptr;
          else
-           {
-             /* Who knows?  */
-             isec = NULL;
-           }
+           isec = bfd_section_from_elf_index (input_bfd, isymp->st_shndx);
 
          *secpp = isec;
        }
@@ -3615,16 +3715,14 @@ sh_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
 
       if (sections != NULL)
        free (sections);
-      sections = NULL;
       if (internal_syms != NULL)
        free (internal_syms);
-      internal_syms = NULL;
+      if (shndx_buf != NULL)
+       free (shndx_buf);
       if (external_syms != NULL && symtab_hdr->contents == NULL)
        free (external_syms);
-      external_syms = NULL;
       if (internal_relocs != elf_section_data (input_section)->relocs)
        free (internal_relocs);
-      internal_relocs = NULL;
     }
 
   return data;
@@ -3633,6 +3731,8 @@ sh_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
   if (internal_relocs != NULL
       && internal_relocs != elf_section_data (input_section)->relocs)
     free (internal_relocs);
+  if (shndx_buf != NULL)
+    free (shndx_buf);
   if (external_syms != NULL && symtab_hdr->contents == NULL)
     free (external_syms);
   if (internal_syms != NULL)
@@ -3675,12 +3775,9 @@ sh_elf_gc_mark_hook (abfd, info, rel, h, sym)
     }
   else
     {
-      if (!(elf_bad_symtab (abfd)
-           && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
-         && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
-                && sym->st_shndx != SHN_COMMON))
-       return bfd_section_from_elf_index (abfd, sym->st_shndx);
+      return bfd_section_from_elf_index (abfd, sym->st_shndx);
     }
+
   return NULL;
 }
 
This page took 0.033995 seconds and 4 git commands to generate.