From: Alan Modra Date: Fri, 24 Jan 2025 23:45:58 +0000 (+1030) Subject: Re: ld plugin bfd_make_readable leak X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=314b99ee71e37919a9e67b5caf4448d1db5f04b0;p=thirdparty%2Fbinutils-gdb.git Re: ld plugin bfd_make_readable leak Commit 3097045a18a8 runs into an abort in objalloc_free_block when the memory being bfd_release'd wasn't bfd_alloc'd. Fix that. * coffgen.c (_bfd_coff_free_cached_info): Don't release raw_syments when obj_coff_keep_raw_syms. * libcoff-in.h (obj_coff_keep_raw_syms): Define. (struct coff_tdata): Add keep_raw_syms. * peicode.h (pe_ILF_build_a_bfd): Set obj_coff_keep_raw_syms. * libcoff.h: Regenerate. --- diff --git a/bfd/coffgen.c b/bfd/coffgen.c index c4026e96afb..c734f058892 100644 --- a/bfd/coffgen.c +++ b/bfd/coffgen.c @@ -3299,11 +3299,13 @@ _bfd_coff_free_cached_info (bfd *abfd) /* Free raw syms, and any other data bfd_alloc'd after raw syms are read. */ - if (obj_raw_syments (abfd)) - bfd_release (abfd, obj_raw_syments (abfd)); - obj_raw_syments (abfd) = NULL; - obj_symbols (abfd) = NULL; - obj_convert (abfd) = NULL; + if (!obj_coff_keep_raw_syms (abfd) && obj_raw_syments (abfd)) + { + bfd_release (abfd, obj_raw_syments (abfd)); + obj_raw_syments (abfd) = NULL; + obj_symbols (abfd) = NULL; + obj_convert (abfd) = NULL; + } } return _bfd_generic_bfd_free_cached_info (abfd); diff --git a/bfd/libcoff-in.h b/bfd/libcoff-in.h index 51f964c4fd2..1410b08f6ae 100644 --- a/bfd/libcoff-in.h +++ b/bfd/libcoff-in.h @@ -40,6 +40,7 @@ extern "C" { #define obj_relocbase(bfd) (coff_data (bfd)->relocbase) #define obj_raw_syments(bfd) (coff_data (bfd)->raw_syments) #define obj_raw_syment_count(bfd) (coff_data (bfd)->raw_syment_count) +#define obj_coff_keep_raw_syms(bfd) (coff_data (bfd)->keep_raw_syms) #define obj_convert(bfd) (coff_data (bfd)->conversion_table) #define obj_conv_table_size(bfd) (coff_data (bfd)->conv_table_size) #define obj_coff_external_syms(bfd) (coff_data (bfd)->external_syms) @@ -91,6 +92,8 @@ typedef struct coff_tdata backend flag _bfd_coff_long_section_names. */ bool long_section_names; + /* If this is TRUE, raw_syments may not be released. */ + bool keep_raw_syms; /* If this is TRUE, the external_syms may not be freed. */ bool keep_syms; /* If this is TRUE, the strings may not be freed. */ diff --git a/bfd/libcoff.h b/bfd/libcoff.h index 947dbeb67a0..d0cfd09709a 100644 --- a/bfd/libcoff.h +++ b/bfd/libcoff.h @@ -44,6 +44,7 @@ extern "C" { #define obj_relocbase(bfd) (coff_data (bfd)->relocbase) #define obj_raw_syments(bfd) (coff_data (bfd)->raw_syments) #define obj_raw_syment_count(bfd) (coff_data (bfd)->raw_syment_count) +#define obj_coff_keep_raw_syms(bfd) (coff_data (bfd)->keep_raw_syms) #define obj_convert(bfd) (coff_data (bfd)->conversion_table) #define obj_conv_table_size(bfd) (coff_data (bfd)->conv_table_size) #define obj_coff_external_syms(bfd) (coff_data (bfd)->external_syms) @@ -95,6 +96,8 @@ typedef struct coff_tdata backend flag _bfd_coff_long_section_names. */ bool long_section_names; + /* If this is TRUE, raw_syments may not be released. */ + bool keep_raw_syms; /* If this is TRUE, the external_syms may not be freed. */ bool keep_syms; /* If this is TRUE, the strings may not be freed. */ diff --git a/bfd/peicode.h b/bfd/peicode.h index ad4f1963b9c..3a93e008799 100644 --- a/bfd/peicode.h +++ b/bfd/peicode.h @@ -1154,6 +1154,7 @@ pe_ILF_build_a_bfd (bfd * abfd, obj_raw_syments (abfd) = vars.native_syms; obj_raw_syment_count (abfd) = vars.sym_index; + obj_coff_keep_raw_syms (abfd) = true; obj_coff_external_syms (abfd) = (void *) vars.esym_table; obj_coff_keep_syms (abfd) = true;