Revise sleb128 and uleb128 reader

This patch catches and reports errors when reading leb128 values,
addressing a FIXME in read_leb128.

	* dwarf.h (read_leb128): Update prototype.
	(report_leb_status): New inline function.
	(SKIP_ULEB, SKIP_SLEB, READ_ULEB, READ_SLEB): Define.
	* dwarf.c: Use above macros throughout file.  Formatting.
	(read_leb128): Reorder params.  Add status return param.
	Don't stop reading until finding terminator or end of data.
	Detect loss of significant bits.  Sign extend only on
	terminating byte.
	(read_sleb128, read_uleb128): Delete functions.
	(SKIP_ULEB, SKIP_SLEB, READ_ULEB, READ_SLEB): Delete macros.
	(read_and_print_leb128): Rewrite.
	(process_extended_line_op): Return a size_t.  Use size_t vars.
	Adjust to suit new macros.  Add proper name size to "data" when
	processing DW_LNE_define_file.
	(process_abbrev_section): Adjust to suit new macros.
	(decode_location_expression, skip_attr_bytes): Likewise.
	(get_type_signedness): Likewise.
	(read_and_display_attr_value): Likewise.  Consolidate block code.
	(process_debug_info): Adjust to suit new macros.
	(display_formatted_table, display_debug_lines_raw): Likewise.
	(display_debug_lines_decoded): Likewise.  Properly check for end
	of DW_LNS_extended_op.
	(display_debug_macinfo): Adjust to suit new macros.
	(get_line_filename_and_dirname, display_debug_macro): Likewise.
	(display_view_pair_list): Likewise.  Don't back off when hitting
	end of data.
	(display_loc_list): Adjust to suit new macros.
	(display_loclists_list, display_loc_list_dwo): Likewise.
	(display_debug_rnglists_list, read_cie): Likewise.
	(display_debug_frames): Likewise.
	* readelf.c: Use new ULEB macros throughout file.
	(read_uleb128): Delete.
	(decode_arm_unwind_bytecode): Use read_leb128.
	(decode_tic6x_unwind_bytecode): Likewise.
	(display_tag_value): Adjust to suit new macros.
	(display_arc_attribute, display_arm_attribute): Likewise.
	(display_gnu_attribute, display_power_gnu_attribute): Likewise.
	(display_s390_gnu_attribute, display_sparc_gnu_attribute): Likewise.
	(display_mips_gnu_attribute, display_tic6x_attribute): Likewise.
	(display_msp430x_attribute, display_msp430_gnu_attribute): Likewise.
	(display_riscv_attribute, process_attributes): Likewise.
This commit is contained in:
Alan Modra 2019-12-23 18:01:34 +10:30
parent 27c1c4271a
commit cd30bcef4a
4 changed files with 798 additions and 1030 deletions

View file

@ -248,9 +248,65 @@ extern void * xcalloc2 (size_t, size_t);
extern void * xcmalloc (size_t, size_t);
extern void * xcrealloc (void *, size_t, size_t);
extern dwarf_vma read_leb128 (unsigned char *, unsigned int *, bfd_boolean, const unsigned char * const);
/* A callback into the client. Returns TRUE if there is a
relocation against the given debug section at the given
offset. */
extern bfd_boolean reloc_at (struct dwarf_section *, dwarf_vma);
extern dwarf_vma read_leb128 (unsigned char *, const unsigned char *const,
bfd_boolean, unsigned int *, int *);
static inline void
report_leb_status (int status)
{
if ((status & 1) != 0)
error (_("LEB end of data\n"));
else if ((status & 2) != 0)
error (_("LEB value too large\n"));
}
#define SKIP_ULEB(start, end) \
do \
{ \
unsigned int _len; \
read_leb128 (start, end, FALSE, &_len, NULL); \
start += _len; \
} while (0)
#define SKIP_SLEB(start, end) \
do \
{ \
unsigned int _len; \
read_leb128 (start, end, TRUE, &_len, NULL); \
start += _len; \
} while (0)
#define READ_ULEB(var, start, end) \
do \
{ \
dwarf_vma _val; \
unsigned int _len; \
int _status; \
\
_val = read_leb128 (start, end, FALSE, &_len, &_status); \
start += _len; \
(var) = _val; \
if ((var) != _val) \
_status |= 2; \
report_leb_status (_status); \
} while (0)
#define READ_SLEB(var, start, end) \
do \
{ \
dwarf_signed_vma _val; \
unsigned int _len; \
int _status; \
\
_val = read_leb128 (start, end, TRUE, &_len, &_status); \
start += _len; \
(var) = _val; \
if ((var) != _val) \
_status |= 2; \
report_leb_status (_status); \
} while (0)