Make coff backend data read-only

The bfd_coff_backend_data struct should be read-only, the only thing
preventing this is that objcopy writes to one of the fields,
_bfd_coff_long_section_names.  This patch creates a copy of the field
in bfd coff_obj_tdata, which makes more sense anyway.  When enabling
long section names the intent is to do so for a particular bfd, not
for all bfds that might happen to be using the target xvec.

bfd/
	* coffcode.h: Update coff long section name comment.
	(bfd_coff_set_long_section_names_allowed): Use macro accessor
	to set flag.
	(bfd_coff_set_long_section_names_disallowed): Tidy.
	(coff_backend_info): Return a const pointer.
	(bfd_coff_std_swap_table, ticoff0_swap_table, ticoff1_swap_table),
	(bigobj_swap_table): Make const.
	(bfd_coff_long_section_names): Use tdata copy.
	(coff_mkobject): Set long_section_names from coff_backend_info.
	* coff-go32.c (_bfd_go32_mkobject): Likewise.
	* peicode.h (pe_mkobject): Likewise.
	* coff-sh.c (bfd_coff_small_swap_table): Make const.
	* libcoff-in.h (struct coff_tdata): Add long_section_names,
	reorder fields.
	* libcoff.h: Regenerate.
binutils/
	* objcopy.c (set_long_section_mode): Move earlier in file.
	(copy_object): Call set_long_section_mode here, after setting
	output format.
	(copy_file): Don't call set_long_section_mode.
This commit is contained in:
Alan Modra
2023-01-06 18:59:20 +10:30
parent bb391cb24d
commit 22a95e1a37
7 changed files with 72 additions and 53 deletions

View File

@ -80,6 +80,9 @@ _bfd_go32_mkobject (bfd * abfd)
coff_data (abfd)->go32 = true; coff_data (abfd)->go32 = true;
bfd_coff_long_section_names (abfd)
= coff_backend_info (abfd)->_bfd_coff_long_section_names;
return true; return true;
} }

View File

@ -3079,7 +3079,7 @@ coff_small_new_section_hook (bfd *abfd, asection *section)
/* This is copied from bfd_coff_std_swap_table so that we can change /* This is copied from bfd_coff_std_swap_table so that we can change
the default section alignment power. */ the default section alignment power. */
static bfd_coff_backend_data bfd_coff_small_swap_table = static const bfd_coff_backend_data bfd_coff_small_swap_table =
{ {
coff_swap_aux_in, coff_swap_sym_in, coff_swap_lineno_in, coff_swap_aux_in, coff_swap_sym_in, coff_swap_lineno_in,
coff_swap_aux_out, coff_swap_sym_out, coff_swap_aux_out, coff_swap_sym_out,

View File

@ -134,9 +134,10 @@ SUBSUBSECTION
in output BFDs at runtime; if it is false, as it will be by default in output BFDs at runtime; if it is false, as it will be by default
when generating an executable image, long section names are truncated; when generating an executable image, long section names are truncated;
if true, the long section names extension is employed. The hook if true, the long section names extension is employed. The hook
points to a function that allows the value of the flag to be altered points to a function that allows the value of a copy of the flag
at runtime, on formats that support long section names at all; on in coff object tdata to be altered at runtime, on formats that
other formats it points to a stub that returns an error indication. support long section names at all; on other formats it points
to a stub that returns an error indication.
With input BFDs, the flag is set according to whether any long section With input BFDs, the flag is set according to whether any long section
names are detected while reading the section headers. For a completely names are detected while reading the section headers. For a completely
@ -462,15 +463,14 @@ static bool ticoff1_bad_format_hook
static bool static bool
bfd_coff_set_long_section_names_allowed (bfd *abfd, int enable) bfd_coff_set_long_section_names_allowed (bfd *abfd, int enable)
{ {
coff_backend_info (abfd)->_bfd_coff_long_section_names = enable; bfd_coff_long_section_names (abfd) = enable;
return true; return true;
} }
#else /* !defined (COFF_LONG_SECTION_NAMES) */ #else /* !defined (COFF_LONG_SECTION_NAMES) */
static bool static bool
bfd_coff_set_long_section_names_disallowed (bfd *abfd, int enable) bfd_coff_set_long_section_names_disallowed (bfd *abfd ATTRIBUTE_UNUSED,
int enable ATTRIBUTE_UNUSED)
{ {
(void) abfd;
(void) enable;
return false; return false;
} }
#endif /* defined (COFF_LONG_SECTION_NAMES) */ #endif /* defined (COFF_LONG_SECTION_NAMES) */
@ -1541,7 +1541,7 @@ Special entry points for gdb to swap in coff symbol table parts:
.} bfd_coff_backend_data; .} bfd_coff_backend_data;
. .
.#define coff_backend_info(abfd) \ .#define coff_backend_info(abfd) \
. ((bfd_coff_backend_data *) (abfd)->xvec->backend_data) . ((const bfd_coff_backend_data *) (abfd)->xvec->backend_data)
. .
.#define bfd_coff_swap_aux_in(a,e,t,c,ind,num,i) \ .#define bfd_coff_swap_aux_in(a,e,t,c,ind,num,i) \
. ((coff_backend_info (a)->_bfd_coff_swap_aux_in) (a,e,t,c,ind,num,i)) . ((coff_backend_info (a)->_bfd_coff_swap_aux_in) (a,e,t,c,ind,num,i))
@ -1584,7 +1584,7 @@ Special entry points for gdb to swap in coff symbol table parts:
.#define bfd_coff_long_filenames(abfd) \ .#define bfd_coff_long_filenames(abfd) \
. (coff_backend_info (abfd)->_bfd_coff_long_filenames) . (coff_backend_info (abfd)->_bfd_coff_long_filenames)
.#define bfd_coff_long_section_names(abfd) \ .#define bfd_coff_long_section_names(abfd) \
. (coff_backend_info (abfd)->_bfd_coff_long_section_names) . (coff_data (abfd)->long_section_names)
.#define bfd_coff_set_long_section_names(abfd, enable) \ .#define bfd_coff_set_long_section_names(abfd, enable) \
. ((coff_backend_info (abfd)->_bfd_coff_set_long_section_names) (abfd, enable)) . ((coff_backend_info (abfd)->_bfd_coff_set_long_section_names) (abfd, enable))
.#define bfd_coff_default_section_alignment_power(abfd) \ .#define bfd_coff_default_section_alignment_power(abfd) \
@ -2067,6 +2067,9 @@ coff_mkobject (bfd * abfd)
coff->relocbase = 0; coff->relocbase = 0;
coff->local_toc_sym_map = 0; coff->local_toc_sym_map = 0;
bfd_coff_long_section_names (abfd)
= coff_backend_info (abfd)->_bfd_coff_long_section_names;
/* make_abs_section(abfd);*/ /* make_abs_section(abfd);*/
return true; return true;
@ -5445,7 +5448,7 @@ coff_final_link_postscript (bfd * abfd ATTRIBUTE_UNUSED,
#define coff_SWAP_scnhdr_in coff_swap_scnhdr_in #define coff_SWAP_scnhdr_in coff_swap_scnhdr_in
#endif #endif
static bfd_coff_backend_data bfd_coff_std_swap_table ATTRIBUTE_UNUSED = static const bfd_coff_backend_data bfd_coff_std_swap_table ATTRIBUTE_UNUSED =
{ {
coff_SWAP_aux_in, coff_SWAP_sym_in, coff_SWAP_lineno_in, coff_SWAP_aux_in, coff_SWAP_sym_in, coff_SWAP_lineno_in,
coff_SWAP_aux_out, coff_SWAP_sym_out, coff_SWAP_aux_out, coff_SWAP_sym_out,
@ -5486,7 +5489,7 @@ static bfd_coff_backend_data bfd_coff_std_swap_table ATTRIBUTE_UNUSED =
#ifdef TICOFF #ifdef TICOFF
/* COFF0 differs in file/section header size and relocation entry size. */ /* COFF0 differs in file/section header size and relocation entry size. */
static bfd_coff_backend_data ticoff0_swap_table = static const bfd_coff_backend_data ticoff0_swap_table =
{ {
coff_SWAP_aux_in, coff_SWAP_sym_in, coff_SWAP_lineno_in, coff_SWAP_aux_in, coff_SWAP_sym_in, coff_SWAP_lineno_in,
coff_SWAP_aux_out, coff_SWAP_sym_out, coff_SWAP_aux_out, coff_SWAP_sym_out,
@ -5528,7 +5531,7 @@ static bfd_coff_backend_data ticoff0_swap_table =
#ifdef TICOFF #ifdef TICOFF
/* COFF1 differs in section header size. */ /* COFF1 differs in section header size. */
static bfd_coff_backend_data ticoff1_swap_table = static const bfd_coff_backend_data ticoff1_swap_table =
{ {
coff_SWAP_aux_in, coff_SWAP_sym_in, coff_SWAP_lineno_in, coff_SWAP_aux_in, coff_SWAP_sym_in, coff_SWAP_lineno_in,
coff_SWAP_aux_out, coff_SWAP_sym_out, coff_SWAP_aux_out, coff_SWAP_sym_out,
@ -5789,7 +5792,7 @@ coff_bigobj_swap_aux_out (bfd * abfd,
return AUXESZ; return AUXESZ;
} }
static bfd_coff_backend_data bigobj_swap_table = static const bfd_coff_backend_data bigobj_swap_table =
{ {
coff_bigobj_swap_aux_in, coff_bigobj_swap_sym_in, coff_SWAP_lineno_in, coff_bigobj_swap_aux_in, coff_bigobj_swap_sym_in, coff_SWAP_lineno_in,
coff_bigobj_swap_aux_out, coff_bigobj_swap_sym_out, coff_bigobj_swap_aux_out, coff_bigobj_swap_sym_out,

View File

@ -79,21 +79,34 @@ typedef struct coff_tdata
/* The unswapped external symbols. May be NULL. Read by /* The unswapped external symbols. May be NULL. Read by
_bfd_coff_get_external_symbols. */ _bfd_coff_get_external_symbols. */
void * external_syms; void * external_syms;
/* If this is TRUE, the external_syms may not be freed. */
bool keep_syms;
/* The string table. May be NULL. Read by /* The string table. May be NULL. Read by
_bfd_coff_read_string_table. */ _bfd_coff_read_string_table. */
char *strings; char *strings;
/* The length of the strings table. For error checking. */ /* The length of the strings table. For error checking. */
bfd_size_type strings_len; bfd_size_type strings_len;
/* Set if long section names are supported. A writable copy of the COFF
backend flag _bfd_coff_long_section_names. */
bool long_section_names;
/* If this is TRUE, the external_syms may not be freed. */
bool keep_syms;
/* If this is TRUE, the strings may not be freed. */ /* If this is TRUE, the strings may not be freed. */
bool keep_strings; bool keep_strings;
/* If this is TRUE, the strings have been written out already. */ /* If this is TRUE, the strings have been written out already. */
bool strings_written; bool strings_written;
/* Is this a GO32 coff file? */
bool go32;
/* Is this a PE format coff file? */ /* Is this a PE format coff file? */
int pe; int pe;
/* Copy of some of the f_flags bits in the COFF filehdr structure,
used by ARM code. */
flagword flags;
/* Used by the COFF backend linker. */ /* Used by the COFF backend linker. */
struct coff_link_hash_entry **sym_hashes; struct coff_link_hash_entry **sym_hashes;
@ -111,13 +124,6 @@ typedef struct coff_tdata
/* The timestamp from the COFF file header. */ /* The timestamp from the COFF file header. */
long timestamp; long timestamp;
/* Copy of some of the f_flags bits in the COFF filehdr structure,
used by ARM code. */
flagword flags;
/* Is this a GO32 coff file? */
bool go32;
/* A stub (extra data prepended before the COFF image) and its size. /* A stub (extra data prepended before the COFF image) and its size.
Used by coff-go32-exe, it contains executable data that loads the Used by coff-go32-exe, it contains executable data that loads the
COFF object into memory. */ COFF object into memory. */

View File

@ -83,21 +83,34 @@ typedef struct coff_tdata
/* The unswapped external symbols. May be NULL. Read by /* The unswapped external symbols. May be NULL. Read by
_bfd_coff_get_external_symbols. */ _bfd_coff_get_external_symbols. */
void * external_syms; void * external_syms;
/* If this is TRUE, the external_syms may not be freed. */
bool keep_syms;
/* The string table. May be NULL. Read by /* The string table. May be NULL. Read by
_bfd_coff_read_string_table. */ _bfd_coff_read_string_table. */
char *strings; char *strings;
/* The length of the strings table. For error checking. */ /* The length of the strings table. For error checking. */
bfd_size_type strings_len; bfd_size_type strings_len;
/* Set if long section names are supported. A writable copy of the COFF
backend flag _bfd_coff_long_section_names. */
bool long_section_names;
/* If this is TRUE, the external_syms may not be freed. */
bool keep_syms;
/* If this is TRUE, the strings may not be freed. */ /* If this is TRUE, the strings may not be freed. */
bool keep_strings; bool keep_strings;
/* If this is TRUE, the strings have been written out already. */ /* If this is TRUE, the strings have been written out already. */
bool strings_written; bool strings_written;
/* Is this a GO32 coff file? */
bool go32;
/* Is this a PE format coff file? */ /* Is this a PE format coff file? */
int pe; int pe;
/* Copy of some of the f_flags bits in the COFF filehdr structure,
used by ARM code. */
flagword flags;
/* Used by the COFF backend linker. */ /* Used by the COFF backend linker. */
struct coff_link_hash_entry **sym_hashes; struct coff_link_hash_entry **sym_hashes;
@ -115,13 +128,6 @@ typedef struct coff_tdata
/* The timestamp from the COFF file header. */ /* The timestamp from the COFF file header. */
long timestamp; long timestamp;
/* Copy of some of the f_flags bits in the COFF filehdr structure,
used by ARM code. */
flagword flags;
/* Is this a GO32 coff file? */
bool go32;
/* A stub (extra data prepended before the COFF image) and its size. /* A stub (extra data prepended before the COFF image) and its size.
Used by coff-go32-exe, it contains executable data that loads the Used by coff-go32-exe, it contains executable data that loads the
COFF object into memory. */ COFF object into memory. */
@ -841,7 +847,7 @@ typedef struct
} bfd_coff_backend_data; } bfd_coff_backend_data;
#define coff_backend_info(abfd) \ #define coff_backend_info(abfd) \
((bfd_coff_backend_data *) (abfd)->xvec->backend_data) ((const bfd_coff_backend_data *) (abfd)->xvec->backend_data)
#define bfd_coff_swap_aux_in(a,e,t,c,ind,num,i) \ #define bfd_coff_swap_aux_in(a,e,t,c,ind,num,i) \
((coff_backend_info (a)->_bfd_coff_swap_aux_in) (a,e,t,c,ind,num,i)) ((coff_backend_info (a)->_bfd_coff_swap_aux_in) (a,e,t,c,ind,num,i))
@ -884,7 +890,7 @@ typedef struct
#define bfd_coff_long_filenames(abfd) \ #define bfd_coff_long_filenames(abfd) \
(coff_backend_info (abfd)->_bfd_coff_long_filenames) (coff_backend_info (abfd)->_bfd_coff_long_filenames)
#define bfd_coff_long_section_names(abfd) \ #define bfd_coff_long_section_names(abfd) \
(coff_backend_info (abfd)->_bfd_coff_long_section_names) (coff_data (abfd)->long_section_names)
#define bfd_coff_set_long_section_names(abfd, enable) \ #define bfd_coff_set_long_section_names(abfd, enable) \
((coff_backend_info (abfd)->_bfd_coff_set_long_section_names) (abfd, enable)) ((coff_backend_info (abfd)->_bfd_coff_set_long_section_names) (abfd, enable))
#define bfd_coff_default_section_alignment_power(abfd) \ #define bfd_coff_default_section_alignment_power(abfd) \

View File

@ -292,6 +292,10 @@ pe_mkobject (bfd * abfd)
pe->dos_message[15] = 0x0; pe->dos_message[15] = 0x0;
memset (& pe->pe_opthdr, 0, sizeof pe->pe_opthdr); memset (& pe->pe_opthdr, 0, sizeof pe->pe_opthdr);
bfd_coff_long_section_names (abfd)
= coff_backend_info (abfd)->_bfd_coff_long_section_names;
return true; return true;
} }

View File

@ -2610,6 +2610,19 @@ check_new_section_flags (flagword flags, bfd * abfd, const char * secname)
return flags; return flags;
} }
static void
set_long_section_mode (bfd *output_bfd, bfd *input_bfd, enum long_section_name_handling style)
{
/* This is only relevant to Coff targets. */
if (bfd_get_flavour (output_bfd) == bfd_target_coff_flavour)
{
if (style == KEEP
&& bfd_get_flavour (input_bfd) == bfd_target_coff_flavour)
style = bfd_coff_long_section_names (input_bfd) ? ENABLE : DISABLE;
bfd_coff_set_long_section_names (output_bfd, style != DISABLE);
}
}
/* Copy object file IBFD onto OBFD. /* Copy object file IBFD onto OBFD.
Returns TRUE upon success, FALSE otherwise. */ Returns TRUE upon success, FALSE otherwise. */
@ -2660,6 +2673,9 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
return false; return false;
} }
/* This is a no-op on non-Coff targets. */
set_long_section_mode (obfd, ibfd, long_section_names);
/* Set the Verilog output endianness based upon the input file's /* Set the Verilog output endianness based upon the input file's
endianness. We may not be producing verilog format output, endianness. We may not be producing verilog format output,
but testing this just adds extra code this is not really but testing this just adds extra code this is not really
@ -3765,19 +3781,6 @@ copy_archive (bfd *ibfd, bfd *obfd, const char *output_target,
free (dir); free (dir);
} }
static void
set_long_section_mode (bfd *output_bfd, bfd *input_bfd, enum long_section_name_handling style)
{
/* This is only relevant to Coff targets. */
if (bfd_get_flavour (output_bfd) == bfd_target_coff_flavour)
{
if (style == KEEP
&& bfd_get_flavour (input_bfd) == bfd_target_coff_flavour)
style = bfd_coff_long_section_names (input_bfd) ? ENABLE : DISABLE;
bfd_coff_set_long_section_names (output_bfd, style != DISABLE);
}
}
/* The top-level control. */ /* The top-level control. */
static void static void
@ -3885,9 +3888,6 @@ copy_file (const char *input_filename, const char *output_filename, int ofd,
gnu_debuglink_filename = NULL; gnu_debuglink_filename = NULL;
} }
/* This is a no-op on non-Coff targets. */
set_long_section_mode (obfd, ibfd, long_section_names);
copy_archive (ibfd, obfd, output_target, force_output_target, input_arch); copy_archive (ibfd, obfd, output_target, force_output_target, input_arch);
} }
else if (bfd_check_format_matches (ibfd, bfd_object, &obj_matching)) else if (bfd_check_format_matches (ibfd, bfd_object, &obj_matching))
@ -3913,9 +3913,6 @@ copy_file (const char *input_filename, const char *output_filename, int ofd,
return; return;
} }
/* This is a no-op on non-Coff targets. */
set_long_section_mode (obfd, ibfd, long_section_names);
if (! copy_object (ibfd, obfd, input_arch)) if (! copy_object (ibfd, obfd, input_arch))
status = 1; status = 1;