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 --git a/bfd/binary.c b/bfd/binary.c index 6a7a77b..7fe47b5 100644 --- a/bfd/binary.c +++ b/bfd/binary.c
@@ -321,8 +321,8 @@ 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 7cf8611..8b3579d 100644 --- a/bfd/linker.c +++ b/bfd/linker.c
@@ -1989,6 +1989,9 @@ 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 e1d39e5..a7ccf23 100644 --- a/bfd/srec.c +++ b/bfd/srec.c
@@ -1082,7 +1082,7 @@ 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 @@ 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 @@ + 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 @@ 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 @@ 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 01feeef..ef2bb25 100644 --- a/bfd/tekhex.c +++ b/bfd/tekhex.c
@@ -873,7 +873,7 @@ case 'C': case 'U': bfd_set_error (bfd_error_wrong_format); - return false; + goto fail; } writesym (&dst, sym->name); @@ -885,8 +885,15 @@ /* 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 @@ 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 4930b85..70cc7c6 100644 --- a/bfd/verilog.c +++ b/bfd/verilog.c
@@ -384,11 +384,9 @@ 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. */