bfd_get_relocated_section_contents allow NULL data buffer
authorAlan Modra <amodra@gmail.com>
Fri, 16 Dec 2022 11:07:29 +0000 (21:37 +1030)
committerAlan Modra <amodra@gmail.com>
Sat, 17 Dec 2022 08:14:42 +0000 (18:44 +1030)
This patch removes the bfd_malloc in default_indirect_link_order and
bfd_simple_get_relocated_section_contents, pushing the allocation down
to bfd_get_relocated_section_contents.  The idea is to make use of the
allocation done with sanity checking in bfd_get_full_section_contents,
which is called by bfd_generic_get_relocated_section_contents.

Doing this exposed a bug in bfd_get_full_section_contents.  With
relaxation it is possible that an input section rawsize is different
to the section size.  In that case we want to use the larger of
rawsize (the on-disk size for input sections) and size.

* reloc.c (bfd_generic_get_relocated_section_contents),
* reloc16.c (bfd_coff_reloc16_get_relocated_section_contents),
* coff-alpha.c (alpha_ecoff_get_relocated_section_contents),
* coff-sh.c (sh_coff_get_relocated_section_contents),
* elf-m10200.c (mn10200_elf_get_relocated_section_contents),
* elf-m10300.c (mn10300_elf_get_relocated_section_contents),
* elf32-avr.c (elf32_avr_get_relocated_section_contents),
* elf32-cr16.c (elf32_cr16_get_relocated_section_contents),
* elf32-crx.c (elf32_crx_get_relocated_section_contents),
* elf32-h8300.c (elf32_h8_get_relocated_section_contents),
* elf32-nds32.c (nds32_elf_get_relocated_section_contents),
* elf32-sh.c (sh_elf_get_relocated_section_contents),
* elfxx-mips.c (_bfd_elf_mips_get_relocated_section_contents):
Handle NULL data buffer.
* bfd.c (bfd_get_section_alloc_size): New function.
* bfd-in2.h: Regenerate.
* compress.c (bfd_get_full_section_contents): Correct section
malloc size.
* linker.c (default_indirect_link_order): Don't malloc memory
here before calling bfd_get_relocated_section_contents.
* simple.c (bfd_simple_get_relocated_section_contents): Likewise.

18 files changed:
bfd/bfd-in2.h
bfd/bfd.c
bfd/coff-alpha.c
bfd/coff-sh.c
bfd/compress.c
bfd/elf-m10200.c
bfd/elf-m10300.c
bfd/elf32-avr.c
bfd/elf32-cr16.c
bfd/elf32-crx.c
bfd/elf32-h8300.c
bfd/elf32-nds32.c
bfd/elf32-sh.c
bfd/elfxx-mips.c
bfd/linker.c
bfd/reloc.c
bfd/reloc16.c
bfd/simple.c

index 297ce1251681ab3875665177895edbbc0d60045b..f4d531f5bf8778c6e72aacf8fed18c941fa021d7 100644 (file)
@@ -6962,6 +6962,14 @@ bfd_get_section_limit (const bfd *abfd, const asection *sec)
           / bfd_octets_per_byte (abfd, sec));
 }
 
+static inline bfd_size_type
+bfd_get_section_alloc_size (const bfd *abfd, const asection *sec)
+{
+  if (abfd->direction != write_direction && sec->rawsize > sec->size)
+    return sec->rawsize;
+  return sec->size;
+}
+
 /* Functions to handle insertion and deletion of a bfd's sections.  These
    only handle the list pointers, ie. do not adjust section_count,
    target_index etc.  */
index 12cb4bca0ecdad57b6571d15a797749f0f934365..97ce2b104504d3f217afff431c084ef2c4c9c551 100644 (file)
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -518,6 +518,14 @@ CODE_FRAGMENT
 .         / bfd_octets_per_byte (abfd, sec));
 .}
 .
+.static inline bfd_size_type
+.bfd_get_section_alloc_size (const bfd *abfd, const asection *sec)
+.{
+.  if (abfd->direction != write_direction && sec->rawsize > sec->size)
+.    return sec->rawsize;
+.  return sec->size;
+.}
+.
 .{* Functions to handle insertion and deletion of a bfd's sections.  These
 .   only handle the list pointers, ie. do not adjust section_count,
 .   target_index etc.  *}
index ea217f77ace0761c9354eadf3d372cdbae0b8ef8..2ac47754aa1fc9171196a9ef5e74409fcfd63e6c 100644 (file)
@@ -745,6 +745,7 @@ alpha_ecoff_get_relocated_section_contents (bfd *abfd,
   if (reloc_size < 0)
     return NULL;
 
+  bfd_byte *orig_data = data;
   if (!bfd_get_full_section_contents (input_bfd, input_section, &data))
     return NULL;
 
@@ -756,7 +757,7 @@ alpha_ecoff_get_relocated_section_contents (bfd *abfd,
 
   reloc_vector = (arelent **) bfd_malloc (reloc_size);
   if (reloc_vector == NULL)
-    return NULL;
+    goto error_return;
 
   reloc_count = bfd_canonicalize_reloc (input_bfd, input_section,
                                        reloc_vector, symbols);
@@ -1138,6 +1139,8 @@ alpha_ecoff_get_relocated_section_contents (bfd *abfd,
 
  error_return:
   free (reloc_vector);
+  if (orig_data == NULL)
+    free (data);
   return NULL;
 }
 
index d030c47553973638b8a9325014011bc1eb76018c..c0f6fb42f6d57e443d65950bb888cd93dde4e97f 100644 (file)
@@ -2922,6 +2922,13 @@ sh_coff_get_relocated_section_contents (bfd *output_bfd,
                                                       relocatable,
                                                       symbols);
 
+  bfd_byte *orig_data = data;
+  if (data == NULL)
+    {
+      data = bfd_malloc (input_section->size);
+      if (data == NULL)
+       return NULL;
+    }
   memcpy (data, coff_section_data (input_bfd, input_section)->contents,
          (size_t) input_section->size);
 
@@ -2997,6 +3004,8 @@ sh_coff_get_relocated_section_contents (bfd *output_bfd,
   free (internal_relocs);
   free (internal_syms);
   free (sections);
+  if (orig_data == NULL)
+    free (data);
   return NULL;
 }
 
index 6a30af5f8e6089934372a355eded47f6de257b0a..86422ba01f48028cdc00eb54a92c9e953685e445 100644 (file)
@@ -720,7 +720,8 @@ DESCRIPTION
 bool
 bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
 {
-  bfd_size_type sz = bfd_get_section_limit_octets (abfd, sec);
+  bfd_size_type readsz = bfd_get_section_limit_octets (abfd, sec);
+  bfd_size_type allocsz = bfd_get_section_alloc_size (abfd, sec);
   bfd_byte *p = *ptr;
   bool ret;
   bfd_size_type save_size;
@@ -729,7 +730,7 @@ bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
   unsigned int compression_header_size;
   const unsigned int compress_status = sec->compress_status;
 
-  if (sz == 0)
+  if (allocsz == 0)
     {
       *ptr = NULL;
       return true;
@@ -744,7 +745,7 @@ bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
       _bfd_error_handler
        /* xgettext:c-format */
        (_("error: %pB(%pA) is too large (%#" PRIx64 " bytes)"),
-        abfd, sec, (uint64_t) sz);
+        abfd, sec, (uint64_t) readsz);
       return false;
     }
 
@@ -753,7 +754,7 @@ bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
     case COMPRESS_SECTION_NONE:
       if (p == NULL)
        {
-         p = (bfd_byte *) bfd_malloc (sz);
+         p = (bfd_byte *) bfd_malloc (allocsz);
          if (p == NULL)
            {
              /* PR 20801: Provide a more helpful error message.  */
@@ -761,12 +762,12 @@ bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
                _bfd_error_handler
                  /* xgettext:c-format */
                  (_("error: %pB(%pA) is too large (%#" PRIx64 " bytes)"),
-                 abfd, sec, (uint64_t) sz);
+                 abfd, sec, (uint64_t) allocsz);
              return false;
            }
        }
 
-      if (!bfd_get_section_contents (abfd, sec, p, 0, sz))
+      if (!bfd_get_section_contents (abfd, sec, p, 0, readsz))
        {
          if (*ptr != p)
            free (p);
@@ -799,7 +800,7 @@ bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
        goto fail_compressed;
 
       if (p == NULL)
-       p = (bfd_byte *) bfd_malloc (sz);
+       p = (bfd_byte *) bfd_malloc (allocsz);
       if (p == NULL)
        goto fail_compressed;
 
@@ -811,7 +812,7 @@ bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
       bool is_zstd = compress_status == DECOMPRESS_SECTION_ZSTD;
       if (!decompress_contents (
              is_zstd, compressed_buffer + compression_header_size,
-             sec->compressed_size - compression_header_size, p, sz))
+             sec->compressed_size - compression_header_size, p, readsz))
        {
          bfd_set_error (bfd_error_bad_value);
          if (p != *ptr)
@@ -830,14 +831,14 @@ bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
        return false;
       if (p == NULL)
        {
-         p = (bfd_byte *) bfd_malloc (sz);
+         p = (bfd_byte *) bfd_malloc (allocsz);
          if (p == NULL)
            return false;
          *ptr = p;
        }
       /* PR 17512; file: 5bc29788.  */
       if (p != sec->contents)
-       memcpy (p, sec->contents, sz);
+       memcpy (p, sec->contents, readsz);
       return true;
 
     default:
index cd13ec94c77dddcab80689206fe7a43b1c7fc21a..948da5d9bc8af119af94ab0cfb852a6a56bf386e 100644 (file)
@@ -1289,6 +1289,13 @@ mn10200_elf_get_relocated_section_contents (bfd *output_bfd,
 
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
 
+  bfd_byte *orig_data = data;
+  if (data == NULL)
+    {
+      data = bfd_malloc (input_section->size);
+      if (data == NULL)
+       return NULL;
+    }
   memcpy (data, elf_section_data (input_section)->this_hdr.contents,
          (size_t) input_section->size);
 
@@ -1360,6 +1367,8 @@ mn10200_elf_get_relocated_section_contents (bfd *output_bfd,
     free (isymbuf);
   if (elf_section_data (input_section)->relocs != internal_relocs)
     free (internal_relocs);
+  if (orig_data == NULL)
+    free (data);
   return NULL;
 }
 
index 3010b54cbf8ab62ef1482e7bb74eaefb6e8e6d45..687223d83afec2e5611a1cd6134d8e6e45c8462f 100644 (file)
@@ -4431,6 +4431,13 @@ mn10300_elf_get_relocated_section_contents (bfd *output_bfd,
 
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
 
+  bfd_byte *orig_data = data;
+  if (data == NULL)
+    {
+      data = bfd_malloc (input_section->size);
+      if (data == NULL)
+       return NULL;
+    }
   memcpy (data, elf_section_data (input_section)->this_hdr.contents,
          (size_t) input_section->size);
 
@@ -4500,6 +4507,8 @@ mn10300_elf_get_relocated_section_contents (bfd *output_bfd,
     free (isymbuf);
   if (internal_relocs != elf_section_data (input_section)->relocs)
     free (internal_relocs);
+  if (orig_data == NULL)
+    free (data);
   return NULL;
 }
 
index f8b89930ef5f3b33bf86956c80e37aae37d73d15..9ab73528c50b579bbb16ab405d3fe76cff734ec8 100644 (file)
@@ -3216,6 +3216,13 @@ elf32_avr_get_relocated_section_contents (bfd *output_bfd,
                                                       symbols);
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
 
+  bfd_byte *orig_data = data;
+  if (data == NULL)
+    {
+      data = bfd_malloc (input_section->size);
+      if (data == NULL)
+       return NULL;
+    }
   memcpy (data, elf_section_data (input_section)->this_hdr.contents,
          (size_t) input_section->size);
 
@@ -3285,6 +3292,8 @@ elf32_avr_get_relocated_section_contents (bfd *output_bfd,
     free (isymbuf);
   if (elf_section_data (input_section)->relocs != internal_relocs)
     free (internal_relocs);
+  if (orig_data == NULL)
+    free (data);
   return NULL;
 }
 
index 88d161eeef71bbdcbee8aa49c2c9bad165523b1e..555736cc2f818f1aaff2b5c9e26f3df488b9eaa0 100644 (file)
@@ -1481,6 +1481,13 @@ elf32_cr16_get_relocated_section_contents (bfd *output_bfd,
 
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
 
+  bfd_byte *orig_data = data;
+  if (data == NULL)
+    {
+      data = bfd_malloc (input_section->size);
+      if (data == NULL)
+       return NULL;
+    }
   memcpy (data, elf_section_data (input_section)->this_hdr.contents,
          (size_t) input_section->size);
 
@@ -1551,6 +1558,8 @@ elf32_cr16_get_relocated_section_contents (bfd *output_bfd,
     free (isymbuf);
   if (elf_section_data (input_section)->relocs != internal_relocs)
     free (internal_relocs);
+  if (orig_data == NULL)
+    free (data);
   return NULL;
 }
 
index cc6962f7b0e01dc9a7dc5e9720c28a55bae4889c..a7406c003add165a85b1823c89f808f7d31d743f 100644 (file)
@@ -742,6 +742,13 @@ elf32_crx_get_relocated_section_contents (bfd *output_bfd,
 
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
 
+  bfd_byte *orig_data = data;
+  if (data == NULL)
+    {
+      data = bfd_malloc (input_section->size);
+      if (data == NULL)
+       return NULL;
+    }
   memcpy (data, elf_section_data (input_section)->this_hdr.contents,
          (size_t) input_section->size);
 
@@ -813,6 +820,8 @@ elf32_crx_get_relocated_section_contents (bfd *output_bfd,
     free (isymbuf);
   if (elf_section_data (input_section)->relocs != internal_relocs)
     free (internal_relocs);
+  if (orig_data == NULL)
+    free (data);
   return NULL;
 }
 
index 6c65520d7204429bd468f090f7fb3f60ff1af440..5afb8a7ecacde2c30b28f5222ec3c2e538b6a91e 100644 (file)
@@ -1623,6 +1623,13 @@ elf32_h8_get_relocated_section_contents (bfd *output_bfd,
 
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
 
+  bfd_byte *orig_data = data;
+  if (data == NULL)
+    {
+      data = bfd_malloc (input_section->size);
+      if (data == NULL)
+       return NULL;
+    }
   memcpy (data, elf_section_data (input_section)->this_hdr.contents,
          (size_t) input_section->size);
 
@@ -1693,6 +1700,8 @@ elf32_h8_get_relocated_section_contents (bfd *output_bfd,
     free (isymbuf);
   if (elf_section_data (input_section)->relocs != internal_relocs)
     free (internal_relocs);
+  if (orig_data == NULL)
+    free (data);
   return NULL;
 }
 
index 35e0302ed7490ddfe60d0ebfac44dbfdce7c8b6a..5d22002d1b938cbd4bace2f81899a7be4fb3a822 100644 (file)
@@ -13100,6 +13100,7 @@ nds32_elf_get_relocated_section_contents (bfd *abfd,
     return NULL;
 
   /* Read in the section.  */
+  bfd_byte *orig_data = data;
   if (!nds32_get_section_contents (input_bfd, input_section, &data, false))
     return NULL;
 
@@ -13108,7 +13109,7 @@ nds32_elf_get_relocated_section_contents (bfd *abfd,
 
   reloc_vector = (arelent **) bfd_malloc (reloc_size);
   if (reloc_vector == NULL)
-    return NULL;
+    goto error_return;
 
   reloc_count = bfd_canonicalize_reloc (input_bfd, input_section,
                                        reloc_vector, symbols);
@@ -13202,6 +13203,8 @@ nds32_elf_get_relocated_section_contents (bfd *abfd,
 
  error_return:
   free (reloc_vector);
+  if (orig_data == NULL)
+    free (data);
   return NULL;
 }
 
index 73b861e18f3e2f180d9a7698472e63ce4e0b6d32..8ababcf519955862175dfa26944bffe6ea2ac9fd 100644 (file)
@@ -5085,6 +5085,13 @@ sh_elf_get_relocated_section_contents (bfd *output_bfd,
 
   symtab_hdr = &elf_symtab_hdr (input_bfd);
 
+  bfd_byte *orig_data = data;
+  if (data == NULL)
+    {
+      data = bfd_malloc (input_section->size);
+      if (data == NULL)
+       return NULL;
+    }
   memcpy (data, elf_section_data (input_section)->this_hdr.contents,
          (size_t) input_section->size);
 
@@ -5155,6 +5162,8 @@ sh_elf_get_relocated_section_contents (bfd *output_bfd,
     free (isymbuf);
   if (elf_section_data (input_section)->relocs != internal_relocs)
     free (internal_relocs);
+  if (orig_data == NULL)
+    free (data);
   return NULL;
 }
 
index f77ccde840935cbee3255d1ad7734a36268e1185..f0db5ff193b4567275f6c71a9a2f37e229f757b7 100644 (file)
@@ -13301,6 +13301,7 @@ _bfd_elf_mips_get_relocated_section_contents
     return NULL;
 
   /* Read in the section.  */
+  bfd_byte *orig_data = data;
   if (!bfd_get_full_section_contents (input_bfd, input_section, &data))
     return NULL;
 
@@ -13331,6 +13332,8 @@ _bfd_elf_mips_get_relocated_section_contents
          else
            hip = &hi->next;
        }
+      if (orig_data == NULL)
+       free (data);
       data = NULL;
       goto out;
     }
index 0c2e3c10a67aa335cd019e6a9baab5aa903b1499..df99ce9991ae8d1bf0919a83c8472903d02359fc 100644 (file)
@@ -2551,9 +2551,8 @@ default_indirect_link_order (bfd *output_bfd,
 {
   asection *input_section;
   bfd *input_bfd;
-  bfd_byte *contents = NULL;
+  bfd_byte *alloced = NULL;
   bfd_byte *new_contents;
-  bfd_size_type sec_size;
   file_ptr loc;
 
   BFD_ASSERT ((output_section->flags & SEC_HAS_CONTENTS) != 0);
@@ -2654,16 +2653,11 @@ default_indirect_link_order (bfd *output_bfd,
   else
     {
       /* Get and relocate the section contents.  */
-      sec_size = (input_section->rawsize > input_section->size
-                 ? input_section->rawsize
-                 : input_section->size);
-      contents = (bfd_byte *) bfd_malloc (sec_size);
-      if (contents == NULL && sec_size != 0)
-       goto error_return;
       new_contents = (bfd_get_relocated_section_contents
-                     (output_bfd, info, link_order, contents,
+                     (output_bfd, info, link_order, NULL,
                       bfd_link_relocatable (info),
                       _bfd_generic_link_get_symbols (input_bfd)));
+      alloced = new_contents;
       if (!new_contents)
        goto error_return;
     }
@@ -2675,11 +2669,11 @@ default_indirect_link_order (bfd *output_bfd,
                                  new_contents, loc, input_section->size))
     goto error_return;
 
-  free (contents);
+  free (alloced);
   return true;
 
  error_return:
-  free (contents);
+  free (alloced);
   return false;
 }
 
index 6446acc7a309b9b855b9fd598637ed06fab04a29..3b5520f7d2538eadcca94e17fb8f785c96b10c8f 100644 (file)
@@ -8532,6 +8532,7 @@ bfd_generic_get_relocated_section_contents (bfd *abfd,
     return NULL;
 
   /* Read in the section.  */
+  bfd_byte *orig_data = data;
   if (!bfd_get_full_section_contents (input_bfd, input_section, &data))
     return NULL;
 
@@ -8543,7 +8544,7 @@ bfd_generic_get_relocated_section_contents (bfd *abfd,
 
   reloc_vector = (arelent **) bfd_malloc (reloc_size);
   if (reloc_vector == NULL)
-    return NULL;
+    goto error_return;
 
   reloc_count = bfd_canonicalize_reloc (input_bfd,
                                        input_section,
@@ -8680,6 +8681,8 @@ bfd_generic_get_relocated_section_contents (bfd *abfd,
 
  error_return:
   free (reloc_vector);
+  if (orig_data == NULL)
+    free (data);
   return NULL;
 }
 
index 3ae8492a23bc0d47e9f2c324241da46e174a2a7b..7c8586cf19cb5c855069f9dc33c5ba09ce6740ac 100644 (file)
@@ -251,11 +251,11 @@ bfd_coff_reloc16_get_relocated_section_contents
   /* Get enough memory to hold the stuff.  */
   bfd *input_bfd = link_order->u.indirect.section->owner;
   asection *input_section = link_order->u.indirect.section;
-  long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section);
+  long reloc_size;
   arelent **reloc_vector;
   long reloc_count;
-  bfd_size_type sz;
 
+  reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section);
   if (reloc_size < 0)
     return NULL;
 
@@ -267,23 +267,26 @@ bfd_coff_reloc16_get_relocated_section_contents
                                                       symbols);
 
   /* Read in the section.  */
-  sz = input_section->rawsize ? input_section->rawsize : input_section->size;
-  if (!bfd_get_section_contents (input_bfd, input_section, data, 0, sz))
+  bfd_byte *orig_data = data;
+  if (!bfd_get_full_section_contents (input_bfd, input_section, &data))
     return NULL;
 
-  reloc_vector = (arelent **) bfd_malloc ((bfd_size_type) reloc_size);
-  if (!reloc_vector && reloc_size != 0)
+  if (data == NULL)
     return NULL;
 
+  if (reloc_size == 0)
+    return data;
+
+  reloc_vector = (arelent **) bfd_malloc (reloc_size);
+  if (reloc_vector == NULL)
+    goto error_return;
+
   reloc_count = bfd_canonicalize_reloc (input_bfd,
                                        input_section,
                                        reloc_vector,
                                        symbols);
   if (reloc_count < 0)
-    {
-      free (reloc_vector);
-      return NULL;
-    }
+    goto error_return;
 
   if (reloc_count > 0)
     {
@@ -324,6 +327,12 @@ bfd_coff_reloc16_get_relocated_section_contents
            }
        }
     }
-  free ((char *) reloc_vector);
+  free (reloc_vector);
   return data;
+
+ error_return:
+  free (reloc_vector);
+  if (orig_data == NULL)
+    free (data);
+  return NULL;
 }
index 67e326d4625c2df94256218ea042da74c27d1089..4c8b05832a565e54ed93a91b7350f85096ef0394 100644 (file)
@@ -209,7 +209,7 @@ bfd_simple_get_relocated_section_contents (bfd *abfd,
   struct bfd_link_info link_info;
   struct bfd_link_order link_order;
   struct bfd_link_callbacks callbacks;
-  bfd_byte *contents, *data;
+  bfd_byte *contents;
   struct saved_offsets saved_offsets;
   bfd *link_next;
 
@@ -257,28 +257,19 @@ bfd_simple_get_relocated_section_contents (bfd *abfd,
   link_order.size = sec->size;
   link_order.u.indirect.section = sec;
 
-  data = NULL;
   contents = NULL;
-  if (outbuf == NULL)
-    {
-      bfd_size_type amt = sec->rawsize > sec->size ? sec->rawsize : sec->size;
-      data = (bfd_byte *) bfd_malloc (amt);
-      if (data == NULL)
-       goto out1;
-      outbuf = data;
-    }
 
   saved_offsets.section_count = abfd->section_count;
   saved_offsets.sections = malloc (sizeof (*saved_offsets.sections)
                                   * saved_offsets.section_count);
   if (saved_offsets.sections == NULL)
-    goto out2;
+    goto out1;
   bfd_map_over_sections (abfd, simple_save_output_info, &saved_offsets);
 
   if (symbol_table == NULL)
     {
       if (!bfd_generic_link_read_symbols (abfd))
-       goto out3;
+       goto out2;
       symbol_table = _bfd_generic_link_get_symbols (abfd);
     }
 
@@ -288,12 +279,9 @@ bfd_simple_get_relocated_section_contents (bfd *abfd,
                                                 outbuf,
                                                 false,
                                                 symbol_table);
- out3:
+ out2:
   bfd_map_over_sections (abfd, simple_restore_output_info, &saved_offsets);
   free (saved_offsets.sections);
- out2:
-  if (contents == NULL)
-    free (data);
  out1:
   _bfd_generic_link_hash_table_free (abfd);
   abfd->link.next = link_next;