coffgrok access of u.auxent.x_sym.x_tagndx.p

u.auxent.x_sym.x_tagndx is a union.  The p field is only valid when
fix_tag is set.  This patch fixes code in coffgrok.c that accessed the
field without first checking fix_tag, and removes a whole lot of code
validating bogus pointers to prevent segfaults (which no longer
happen, I checked the referenced PR 17512 testcases).  The patch also
documents this in the fix_tag comment, makes is_sym a bitfield, and
sorts the selecter fields a little.

bfd/
	* coffcode.h (combined_entry_type): Make is_sym a bitfield.
	Sort and comment on union selectors.
	* libcoff.h: Regenerate.
binutils/
	* coffgrok.c (do_type): Make aux a combined_entry_type.  Test
	fix_tag before accessing u.auxent.x_sym.x_tagndx.p.  Remove
	now unnecessary pointer bounds checking.
This commit is contained in:
Alan Modra
2023-03-26 19:26:46 +10:30
parent 92479281c4
commit 695c322803
3 changed files with 40 additions and 60 deletions

View File

@@ -294,27 +294,30 @@ CODE_FRAGMENT
.typedef struct coff_ptr_struct
.{
. {* Remembers the offset from the first symbol in the file for
. this symbol. Generated by coff_renumber_symbols. *}
. this symbol. Generated by coff_renumber_symbols. *}
. unsigned int offset;
.
. {* Should the value of this symbol be renumbered. Used for
. XCOFF C_BSTAT symbols. Set by coff_slurp_symbol_table. *}
. unsigned int fix_value : 1;
. {* Selects between the elements of the union below. *}
. unsigned int is_sym : 1;
.
. {* Should the tag field of this symbol be renumbered.
. Created by coff_pointerize_aux. *}
. {* Selects between the elements of the x_sym.x_tagndx union. If set,
. p is valid and the field will be renumbered. *}
. unsigned int fix_tag : 1;
.
. {* Should the endidx field of this symbol be renumbered.
. Created by coff_pointerize_aux. *}
. {* Selects between the elements of the x_sym.x_fcnary.x_fcn.x_endndx
. union. If set, p is valid and the field will be renumbered. *}
. unsigned int fix_end : 1;
.
. {* Should the x_csect.x_scnlen field be renumbered.
. Created by coff_pointerize_aux. *}
. {* Selects between the elements of the x_csect.x_scnlen union. If set,
. p is valid and the field will be renumbered. *}
. unsigned int fix_scnlen : 1;
.
. {* Fix up an XCOFF C_BINCL/C_EINCL symbol. The value is the
. index into the line number entries. Set by coff_slurp_symbol_table. *}
. {* If set, u.syment.n_value contains a pointer to a symbol. The final
. value will be the offset field. Used for XCOFF C_BSTAT symbols. *}
. unsigned int fix_value : 1;
.
. {* If set, u.syment.n_value is an index into the line number entries.
. Used for XCOFF C_BINCL/C_EINCL symbols. *}
. unsigned int fix_line : 1;
.
. {* The container for the symbol structure as read and translated
@@ -325,9 +328,6 @@ CODE_FRAGMENT
. struct internal_syment syment;
. } u;
.
. {* Selector for the union above. *}
. bool is_sym;
.
. {* An extra pointer which can used by format based on COFF (like XCOFF)
. to provide extra information to their backend. *}
. void *extrap;