objcopy: bfd_alloc orelocation
authorAlan Modra <amodra@gmail.com>
Mon, 4 Jul 2022 01:54:22 +0000 (11:24 +0930)
committerAlan Modra <amodra@gmail.com>
Mon, 4 Jul 2022 13:21:56 +0000 (22:51 +0930)
This fixes an inconsequential objcopy memory leak.  I'd normally
ignore reports of leaks like this one, that are merely one block or
fewer per section processed, since objcopy soon exits and frees all
memory.  However I thought it worth providing support for allocating
memory on a bfd objalloc in objcopy and other utils.

PR 29233
* bucomm.c (bfd_xalloc): New function.
* bucomm.h (bfd_xalloc): Declare.
* objcopy.c (copy_relocations_in_section): Use it to allocate
array of reloc pointers.  Rewrite code stripping relocs to do
without extra memory allocation.

binutils/bucomm.c
binutils/bucomm.h
binutils/objcopy.c

index 4395cb9f7f5df155a44b8d13e86df045a865ee18..583419055870559bd9f9b63638351976dac8a82d 100644 (file)
@@ -142,6 +142,19 @@ non_fatal (const char *format, ...)
   va_end (args);
 }
 
+/* Like xmalloc except that ABFD's objalloc memory is returned.
+   Use objalloc_free_block to free this memory and all more recently
+   allocated, or more usually, leave it to bfd_close to free.  */
+
+void *
+bfd_xalloc (bfd *abfd, size_t size)
+{
+  void *ret = bfd_alloc (abfd, size);
+  if (ret == NULL)
+    bfd_fatal (NULL);
+  return ret;
+}
+
 /* Set the default BFD target based on the configured target.  Doing
    this permits the binutils to be configured for a particular target,
    and linked against a shared BFD library which was configured for a
index 48b2c50aced103b14d3313527a7871f31fdaeee5..a1814cbbcc2a0fa8af77cfebfc7323ba93e446f6 100644 (file)
@@ -39,6 +39,8 @@ void fatal (const char *, ...) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
 
 void non_fatal (const char *, ...) ATTRIBUTE_PRINTF_1;
 
+void *bfd_xalloc (bfd *, size_t);
+
 void set_default_bfd_target (void);
 
 void list_matching_formats (char **);
index df87712df981520a0802017fbb94a1b5d1e59946..37435733d7624c48b07e414e1d6db9edc53e39da 100644 (file)
@@ -4336,14 +4336,13 @@ copy_relocations_in_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
        }
       else
        {
-         relpp = (arelent **) xmalloc (relsize);
+         relpp = bfd_xalloc (obfd, relsize);
          relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp);
          if (relcount < 0)
            {
              status = 1;
              bfd_nonfatal_message (NULL, ibfd, isection,
                                    _("relocation count is negative"));
-             free (relpp);
              return;
            }
        }
@@ -4352,34 +4351,24 @@ copy_relocations_in_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
        {
          /* Remove relocations which are not in
             keep_strip_specific_list.  */
-         arelent **temp_relpp;
-         long temp_relcount = 0;
+         arelent **w_relpp;
          long i;
 
-         temp_relpp = (arelent **) xmalloc (relsize);
-         for (i = 0; i < relcount; i++)
-           {
-             /* PR 17512: file: 9e907e0c.  */
-             if (relpp[i]->sym_ptr_ptr
-                 /* PR 20096 */
-                 && * relpp[i]->sym_ptr_ptr)
-               if (is_specified_symbol (bfd_asymbol_name (*relpp[i]->sym_ptr_ptr),
-                                        keep_specific_htab))
-                 temp_relpp [temp_relcount++] = relpp [i];
-           }
-         relcount = temp_relcount;
-         if (relpp != isection->orelocation)
-           free (relpp);
-         relpp = temp_relpp;
+         for (w_relpp = relpp, i = 0; i < relcount; i++)
+           /* PR 17512: file: 9e907e0c.  */
+           if (relpp[i]->sym_ptr_ptr
+               /* PR 20096 */
+               && *relpp[i]->sym_ptr_ptr
+               && is_specified_symbol (bfd_asymbol_name (*relpp[i]->sym_ptr_ptr),
+                                       keep_specific_htab))
+             *w_relpp++ = relpp[i];
+         relcount = w_relpp - relpp;
+         *w_relpp = 0;
        }
 
       bfd_set_reloc (obfd, osection, relcount == 0 ? NULL : relpp, relcount);
       if (relcount == 0)
-       {
-         osection->flags &= ~SEC_RELOC;
-         if (relpp != isection->orelocation)
-           free (relpp);
-       }
+       osection->flags &= ~SEC_RELOC;
     }
 }