[binutils-gdb] binary outsymbols

Alan Modra amodra@sourceware.org
Thu Jan 16 09:30:59 GMT 2025


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=6ca01b0bdd59b61cf94ed151c85f7dee9d240158

commit 6ca01b0bdd59b61cf94ed151c85f7dee9d240158
Author: Alan Modra <amodra@gmail.com>
Date:   Thu Jan 16 14:51:56 2025 +1030

    binary outsymbols
    
    This fixes leaks of outsymbols for various targets that use the
    generic linker.  The key fix here is to not generate output symbols
    for targets that won't ever write symbols, and of course to free
    outsymbols after they've been written in targets that do.  Target
    vector object_flags and section_flags are updated to better reflect
    target capabilities, in particular not setting HAS_SYMS or SEC_RELOC
    when the target does not support symbols or relocs.
    
            * binary.c (binary_vec): Update section_flags.
            * linker.c (generic_add_output_symbol): Don't add to
            outsymbols if !HAS_SYMS.
            * srec.c (srec_write_symbols): Free outsymbols on return.
            (srec_vec): Update object_flags and section_flags.
            (symbolsrec_vec): Likewise.
            * tekhex.c (tekhex_write_object_contents): Free outsymbols on
            return.
            (tekhex_vec): Update object_flags and section_flags.
            * verilog.c (verilog_vec): Likewise.

Diff:
---
 bfd/binary.c  |  4 ++--
 bfd/linker.c  |  3 +++
 bfd/srec.c    | 27 +++++++++++++++------------
 bfd/tekhex.c  | 17 +++++++++++------
 bfd/verilog.c |  6 ++----
 5 files changed, 33 insertions(+), 24 deletions(-)

diff --git a/bfd/binary.c b/bfd/binary.c
index 6a7a77b2401..7fe47b590de 100644
--- a/bfd/binary.c
+++ b/bfd/binary.c
@@ -321,8 +321,8 @@ const bfd_target binary_vec =
   BFD_ENDIAN_UNKNOWN,		/* byteorder */
   BFD_ENDIAN_UNKNOWN,		/* header_byteorder */
   EXEC_P,			/* object_flags */
-  (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE | SEC_DATA
-   | SEC_ROM | SEC_HAS_CONTENTS), /* section_flags */
+  (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
+   | SEC_ALLOC | SEC_LOAD),	/* section_flags */
   0,				/* symbol_leading_char */
   ' ',				/* ar_pad_char */
   16,				/* ar_max_namelen */
diff --git a/bfd/linker.c b/bfd/linker.c
index 7cf8611547d..8b3579dc658 100644
--- a/bfd/linker.c
+++ b/bfd/linker.c
@@ -1989,6 +1989,9 @@ _bfd_generic_final_link (bfd *abfd, struct bfd_link_info *info)
 static bool
 generic_add_output_symbol (bfd *output_bfd, size_t *psymalloc, asymbol *sym)
 {
+  if (!(bfd_applicable_file_flags (output_bfd) & HAS_SYMS))
+    return true;
+
   if (bfd_get_symcount (output_bfd) >= *psymalloc)
     {
       asymbol **newsyms;
diff --git a/bfd/srec.c b/bfd/srec.c
index e1d39e521fc..a7ccf232531 100644
--- a/bfd/srec.c
+++ b/bfd/srec.c
@@ -1082,7 +1082,7 @@ srec_write_symbols (bfd *abfd)
       if (bfd_write ("$$ ", 3, abfd) != 3
 	  || bfd_write (bfd_get_filename (abfd), len, abfd) != len
 	  || bfd_write ("\r\n", 2, abfd) != 2)
-	return false;
+	goto fail;
 
       for (i = 0; i < count; i++)
 	{
@@ -1099,7 +1099,7 @@ srec_write_symbols (bfd *abfd)
 	      len = strlen (s->name);
 	      if (bfd_write ("  ", 2, abfd) != 2
 		  || bfd_write (s->name, len, abfd) != len)
-		return false;
+		goto fail;
 
 	      sprintf (buf, " $%" PRIx64 "\r\n",
 		       (uint64_t) (s->value
@@ -1107,14 +1107,21 @@ srec_write_symbols (bfd *abfd)
 				   + s->section->output_offset));
 	      len = strlen (buf);
 	      if (bfd_write (buf, len, abfd) != len)
-		return false;
+		goto fail;
 	    }
 	}
       if (bfd_write ("$$ \r\n", 5, abfd) != 5)
-	return false;
+	goto fail;
     }
 
+  free (abfd->outsymbols);
+  abfd->outsymbols = NULL;
   return true;
+
+ fail:
+  free (abfd->outsymbols);
+  abfd->outsymbols = NULL;
+  return false;
 }
 
 static bool
@@ -1281,11 +1288,9 @@ const bfd_target srec_vec =
   bfd_target_srec_flavour,
   BFD_ENDIAN_UNKNOWN,		/* Target byte order.  */
   BFD_ENDIAN_UNKNOWN,		/* Target headers byte order.  */
-  (HAS_RELOC | EXEC_P |		/* Object flags.  */
-   HAS_LINENO | HAS_DEBUG |
-   HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+  EXEC_P,			/* Object flags.  */
   (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
-   | SEC_ALLOC | SEC_LOAD | SEC_RELOC),	/* Section flags.  */
+   | SEC_ALLOC | SEC_LOAD),	/* Section flags.  */
   0,				/* Leading underscore.  */
   ' ',				/* AR_pad_char.  */
   16,				/* AR_max_namelen.  */
@@ -1338,11 +1343,9 @@ const bfd_target symbolsrec_vec =
   bfd_target_srec_flavour,
   BFD_ENDIAN_UNKNOWN,		/* Target byte order.  */
   BFD_ENDIAN_UNKNOWN,		/* Target headers byte order.  */
-  (HAS_RELOC | EXEC_P |		/* Object flags.  */
-   HAS_LINENO | HAS_DEBUG |
-   HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+  EXEC_P | HAS_SYMS,		/* Object flags.  */
   (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
-   | SEC_ALLOC | SEC_LOAD | SEC_RELOC),	/* Section flags.  */
+   | SEC_ALLOC | SEC_LOAD),	/* Section flags.  */
   0,				/* Leading underscore.  */
   ' ',				/* AR_pad_char.  */
   16,				/* AR_max_namelen.  */
diff --git a/bfd/tekhex.c b/bfd/tekhex.c
index 01feeef8d4c..ef2bb25fe46 100644
--- a/bfd/tekhex.c
+++ b/bfd/tekhex.c
@@ -873,7 +873,7 @@ tekhex_write_object_contents (bfd *abfd)
 		case 'C':
 		case 'U':
 		  bfd_set_error (bfd_error_wrong_format);
-		  return false;
+		  goto fail;
 		}
 
 	      writesym (&dst, sym->name);
@@ -885,8 +885,15 @@ tekhex_write_object_contents (bfd *abfd)
 
   /* And the terminator.  */
   if (bfd_write ("%0781010\n", 9, abfd) != 9)
-    abort ();
+    goto fail;
+  free (abfd->outsymbols);
+  abfd->outsymbols = NULL;
   return true;
+
+ fail:
+  free (abfd->outsymbols);
+  abfd->outsymbols = NULL;
+  return false;
 }
 
 static int
@@ -986,11 +993,9 @@ const bfd_target tekhex_vec =
   bfd_target_tekhex_flavour,
   BFD_ENDIAN_UNKNOWN,		/* Target byte order.  */
   BFD_ENDIAN_UNKNOWN,		/* Target headers byte order.  */
-  (EXEC_P |			/* Object flags.  */
-   HAS_SYMS | HAS_LINENO | HAS_DEBUG |
-   HAS_RELOC | HAS_LOCALS | WP_TEXT | D_PAGED),
+  EXEC_P | HAS_SYMS,		/* Object flags.  */
   (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
-   | SEC_ALLOC | SEC_LOAD | SEC_RELOC),	/* Section flags.  */
+   | SEC_ALLOC | SEC_LOAD),	/* Section flags.  */
   0,				/* Leading underscore.  */
   ' ',				/* AR_pad_char.  */
   16,				/* AR_max_namelen.  */
diff --git a/bfd/verilog.c b/bfd/verilog.c
index 4930b858ba1..70cc7c69412 100644
--- a/bfd/verilog.c
+++ b/bfd/verilog.c
@@ -384,11 +384,9 @@ const bfd_target verilog_vec =
   bfd_target_verilog_flavour,
   BFD_ENDIAN_UNKNOWN,		/* Target byte order.  */
   BFD_ENDIAN_UNKNOWN,		/* Target headers byte order.  */
-  (HAS_RELOC | EXEC_P |		/* Object flags.  */
-   HAS_LINENO | HAS_DEBUG |
-   HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+  EXEC_P,			/* Object flags.  */
   (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
-   | SEC_ALLOC | SEC_LOAD | SEC_RELOC),	/* Section flags.  */
+   | SEC_ALLOC | SEC_LOAD),	/* Section flags.  */
   0,				/* Leading underscore.  */
   ' ',				/* AR_pad_char.  */
   16,				/* AR_max_namelen.  */


More information about the Binutils-cvs mailing list