aboutsummaryrefslogtreecommitdiff
path: root/binutils/readelf.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2019-12-23 18:01:34 +1030
committerAlan Modra <amodra@gmail.com>2019-12-23 18:01:34 +1030
commitcd30bcef4a685ae4a67f8b4a793af0cf7230b9fc (patch)
treeae8ab56c2f996c81fb1d395fdad4e35f94c1e296 /binutils/readelf.c
parent27c1c4271a14cc2ebc27227212c19d4227ef212d (diff)
downloadgdb-cd30bcef4a685ae4a67f8b4a793af0cf7230b9fc.zip
gdb-cd30bcef4a685ae4a67f8b4a793af0cf7230b9fc.tar.gz
gdb-cd30bcef4a685ae4a67f8b4a793af0cf7230b9fc.tar.bz2
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.
Diffstat (limited to 'binutils/readelf.c')
-rw-r--r--binutils/readelf.c225
1 files changed, 71 insertions, 154 deletions
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 1d8f62b..0853c1f 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -749,17 +749,6 @@ find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
return find_section (filedata, name);
}
-/* Read an unsigned LEB128 encoded value from DATA.
- Set *LENGTH_RETURN to the number of bytes read. */
-
-static inline unsigned long
-read_uleb128 (unsigned char * data,
- unsigned int * length_return,
- const unsigned char * const end)
-{
- return read_leb128 (data, length_return, FALSE, end);
-}
-
/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
This OS has so many departures from the ELF standard that we test it at
many places. */
@@ -8782,7 +8771,7 @@ decode_arm_unwind_bytecode (Filedata * filedata,
}
else
{
- offset = read_uleb128 (buf, &len, buf + i + 1);
+ offset = read_leb128 (buf, buf + i + 1, FALSE, &len, NULL);
assert (len == i + 1);
offset = offset * 4 + 0x204;
printf ("vsp = vsp + %ld", offset);
@@ -9001,7 +8990,7 @@ decode_tic6x_unwind_bytecode (Filedata * filedata,
return FALSE;
}
- offset = read_uleb128 (buf, &len, buf + i + 1);
+ offset = read_leb128 (buf, buf + i + 1, FALSE, &len, NULL);
assert (len == i + 1);
offset = offset * 8 + 0x408;
printf (_("sp = sp + %ld"), offset);
@@ -14492,10 +14481,7 @@ display_tag_value (signed int tag,
}
else
{
- unsigned int len;
-
- val = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (val, p, end);
printf ("%ld (0x%lx)\n", val, val);
}
@@ -14510,17 +14496,14 @@ display_arc_attribute (unsigned char * p,
const unsigned char * const end)
{
unsigned int tag;
- unsigned int len;
unsigned int val;
- tag = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (tag, p, end);
switch (tag)
{
case Tag_ARC_PCS_config:
- val = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (val, p, end);
printf (" Tag_ARC_PCS_config: ");
switch (val)
{
@@ -14546,8 +14529,7 @@ display_arc_attribute (unsigned char * p,
break;
case Tag_ARC_CPU_base:
- val = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (val, p, end);
printf (" Tag_ARC_CPU_base: ");
switch (val)
{
@@ -14571,8 +14553,7 @@ display_arc_attribute (unsigned char * p,
break;
case Tag_ARC_CPU_variation:
- val = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (val, p, end);
printf (" Tag_ARC_CPU_variation: ");
switch (val)
{
@@ -14595,21 +14576,18 @@ display_arc_attribute (unsigned char * p,
break;
case Tag_ARC_ABI_rf16:
- val = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (val, p, end);
printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
break;
case Tag_ARC_ABI_osver:
- val = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (val, p, end);
printf (" Tag_ARC_ABI_osver: v%d\n", val);
break;
case Tag_ARC_ABI_pic:
case Tag_ARC_ABI_sda:
- val = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (val, p, end);
printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
: " Tag_ARC_ABI_pic: ");
switch (val)
@@ -14630,28 +14608,24 @@ display_arc_attribute (unsigned char * p,
break;
case Tag_ARC_ABI_tls:
- val = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (val, p, end);
printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
break;
case Tag_ARC_ABI_enumsize:
- val = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (val, p, end);
printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
_("smallest"));
break;
case Tag_ARC_ABI_exceptions:
- val = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (val, p, end);
printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
: _("default"));
break;
case Tag_ARC_ABI_double_size:
- val = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (val, p, end);
printf (" Tag_ARC_ABI_double_size: %d\n", val);
break;
@@ -14666,14 +14640,12 @@ display_arc_attribute (unsigned char * p,
break;
case Tag_ARC_ISA_mpy_option:
- val = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (val, p, end);
printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
break;
case Tag_ARC_ATR_version:
- val = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (val, p, end);
printf (" Tag_ARC_ATR_version: %d\n", val);
break;
@@ -14818,14 +14790,12 @@ display_arm_attribute (unsigned char * p,
const unsigned char * const end)
{
unsigned int tag;
- unsigned int len;
unsigned int val;
arm_attr_public_tag * attr;
unsigned i;
unsigned int type;
- tag = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (tag, p, end);
attr = NULL;
for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
{
@@ -14845,8 +14815,7 @@ display_arm_attribute (unsigned char * p,
switch (tag)
{
case 7: /* Tag_CPU_arch_profile. */
- val = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (val, p, end);
switch (val)
{
case 0: printf (_("None\n")); break;
@@ -14859,8 +14828,7 @@ display_arm_attribute (unsigned char * p,
break;
case 24: /* Tag_align_needed. */
- val = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (val, p, end);
switch (val)
{
case 0: printf (_("None\n")); break;
@@ -14878,8 +14846,7 @@ display_arm_attribute (unsigned char * p,
break;
case 25: /* Tag_align_preserved. */
- val = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (val, p, end);
switch (val)
{
case 0: printf (_("None\n")); break;
@@ -14898,8 +14865,7 @@ display_arm_attribute (unsigned char * p,
case 32: /* Tag_compatibility. */
{
- val = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (val, p, end);
printf (_("flag = %d, vendor = "), val);
if (p < end - 1)
{
@@ -14925,12 +14891,10 @@ display_arm_attribute (unsigned char * p,
break;
case 65: /* Tag_also_compatible_with. */
- val = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (val, p, end);
if (val == 6 /* Tag_CPU_arch. */)
{
- val = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (val, p, end);
if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
printf ("??? (%d)\n", val);
else
@@ -14955,8 +14919,7 @@ display_arm_attribute (unsigned char * p,
default:
assert (attr->type & 0x80);
- val = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (val, p, end);
type = attr->type & 0x7f;
if (val >= type)
printf ("??? (%d)\n", val);
@@ -14974,19 +14937,16 @@ display_gnu_attribute (unsigned char * p,
unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
const unsigned char * const end)
{
- int tag;
- unsigned int len;
+ unsigned int tag;
unsigned int val;
- tag = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (tag, p, end);
/* Tag_compatibility is the only generic GNU attribute defined at
present. */
if (tag == 32)
{
- val = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (val, p, end);
printf (_("flag = %d, vendor = "), val);
if (p == end)
@@ -15024,19 +14984,17 @@ display_power_gnu_attribute (unsigned char * p,
unsigned int tag,
const unsigned char * const end)
{
- unsigned int len;
unsigned int val;
if (tag == Tag_GNU_Power_ABI_FP)
{
- val = read_uleb128 (p, &len, end);
- p += len;
printf (" Tag_GNU_Power_ABI_FP: ");
- if (len == 0)
+ if (p == end)
{
printf (_("<corrupt>\n"));
return p;
}
+ READ_ULEB (val, p, end);
if (val > 15)
printf ("(%#x), ", val);
@@ -15077,14 +15035,13 @@ display_power_gnu_attribute (unsigned char * p,
if (tag == Tag_GNU_Power_ABI_Vector)
{
- val = read_uleb128 (p, &len, end);
- p += len;
printf (" Tag_GNU_Power_ABI_Vector: ");
- if (len == 0)
+ if (p == end)
{
printf (_("<corrupt>\n"));
return p;
}
+ READ_ULEB (val, p, end);
if (val > 3)
printf ("(%#x), ", val);
@@ -15109,14 +15066,13 @@ display_power_gnu_attribute (unsigned char * p,
if (tag == Tag_GNU_Power_ABI_Struct_Return)
{
- val = read_uleb128 (p, &len, end);
- p += len;
printf (" Tag_GNU_Power_ABI_Struct_Return: ");
- if (len == 0)
+ if (p == end)
{
printf (_("<corrupt>\n"));
return p;
}
+ READ_ULEB (val, p, end);
if (val > 2)
printf ("(%#x), ", val);
@@ -15147,14 +15103,12 @@ display_s390_gnu_attribute (unsigned char * p,
unsigned int tag,
const unsigned char * const end)
{
- unsigned int len;
- int val;
+ unsigned int val;
if (tag == Tag_GNU_S390_ABI_Vector)
{
- val = read_uleb128 (p, &len, end);
- p += len;
printf (" Tag_GNU_S390_ABI_Vector: ");
+ READ_ULEB (val, p, end);
switch (val)
{
@@ -15262,21 +15216,18 @@ display_sparc_gnu_attribute (unsigned char * p,
unsigned int tag,
const unsigned char * const end)
{
- unsigned int len;
- int val;
+ unsigned int val;
if (tag == Tag_GNU_Sparc_HWCAPS)
{
- val = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (val, p, end);
printf (" Tag_GNU_Sparc_HWCAPS: ");
display_sparc_hwcaps (val);
return p;
}
if (tag == Tag_GNU_Sparc_HWCAPS2)
{
- val = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (val, p, end);
printf (" Tag_GNU_Sparc_HWCAPS2: ");
display_sparc_hwcaps2 (val);
return p;
@@ -15330,26 +15281,20 @@ display_mips_gnu_attribute (unsigned char * p,
{
if (tag == Tag_GNU_MIPS_ABI_FP)
{
- unsigned int len;
unsigned int val;
- val = read_uleb128 (p, &len, end);
- p += len;
printf (" Tag_GNU_MIPS_ABI_FP: ");
-
+ READ_ULEB (val, p, end);
print_mips_fp_abi_value (val);
-
return p;
}
if (tag == Tag_GNU_MIPS_ABI_MSA)
{
- unsigned int len;
unsigned int val;
- val = read_uleb128 (p, &len, end);
- p += len;
printf (" Tag_GNU_MIPS_ABI_MSA: ");
+ READ_ULEB (val, p, end);
switch (val)
{
@@ -15374,18 +15319,15 @@ display_tic6x_attribute (unsigned char * p,
const unsigned char * const end)
{
unsigned int tag;
- unsigned int len;
- int val;
+ unsigned int val;
- tag = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (tag, p, end);
switch (tag)
{
case Tag_ISA:
- val = read_uleb128 (p, &len, end);
- p += len;
printf (" Tag_ISA: ");
+ READ_ULEB (val, p, end);
switch (val)
{
@@ -15417,9 +15359,8 @@ display_tic6x_attribute (unsigned char * p,
return p;
case Tag_ABI_wchar_t:
- val = read_uleb128 (p, &len, end);
- p += len;
printf (" Tag_ABI_wchar_t: ");
+ READ_ULEB (val, p, end);
switch (val)
{
case 0:
@@ -15438,9 +15379,8 @@ display_tic6x_attribute (unsigned char * p,
return p;
case Tag_ABI_stack_align_needed:
- val = read_uleb128 (p, &len, end);
- p += len;
printf (" Tag_ABI_stack_align_needed: ");
+ READ_ULEB (val, p, end);
switch (val)
{
case 0:
@@ -15456,8 +15396,7 @@ display_tic6x_attribute (unsigned char * p,
return p;
case Tag_ABI_stack_align_preserved:
- val = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (val, p, end);
printf (" Tag_ABI_stack_align_preserved: ");
switch (val)
{
@@ -15474,8 +15413,7 @@ display_tic6x_attribute (unsigned char * p,
return p;
case Tag_ABI_DSBT:
- val = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (val, p, end);
printf (" Tag_ABI_DSBT: ");
switch (val)
{
@@ -15492,8 +15430,7 @@ display_tic6x_attribute (unsigned char * p,
return p;
case Tag_ABI_PID:
- val = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (val, p, end);
printf (" Tag_ABI_PID: ");
switch (val)
{
@@ -15513,8 +15450,7 @@ display_tic6x_attribute (unsigned char * p,
return p;
case Tag_ABI_PIC:
- val = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (val, p, end);
printf (" Tag_ABI_PIC: ");
switch (val)
{
@@ -15531,8 +15467,7 @@ display_tic6x_attribute (unsigned char * p,
return p;
case Tag_ABI_array_object_alignment:
- val = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (val, p, end);
printf (" Tag_ABI_array_object_alignment: ");
switch (val)
{
@@ -15552,8 +15487,7 @@ display_tic6x_attribute (unsigned char * p,
return p;
case Tag_ABI_array_object_align_expected:
- val = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (val, p, end);
printf (" Tag_ABI_array_object_align_expected: ");
switch (val)
{
@@ -15574,8 +15508,7 @@ display_tic6x_attribute (unsigned char * p,
case Tag_ABI_compatibility:
{
- val = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (val, p, end);
printf (" Tag_ABI_compatibility: ");
printf (_("flag = %d, vendor = "), val);
if (p < end - 1)
@@ -15666,19 +15599,16 @@ static unsigned char *
display_msp430x_attribute (unsigned char * p,
const unsigned char * const end)
{
- unsigned int len;
unsigned int val;
unsigned int tag;
- tag = read_uleb128 (p, & len, end);
- p += len;
+ READ_ULEB (tag, p, end);
switch (tag)
{
case OFBA_MSPABI_Tag_ISA:
- val = read_uleb128 (p, &len, end);
- p += len;
printf (" Tag_ISA: ");
+ READ_ULEB (val, p, end);
switch (val)
{
case 0: printf (_("None\n")); break;
@@ -15689,9 +15619,8 @@ display_msp430x_attribute (unsigned char * p,
break;
case OFBA_MSPABI_Tag_Code_Model:
- val = read_uleb128 (p, &len, end);
- p += len;
printf (" Tag_Code_Model: ");
+ READ_ULEB (val, p, end);
switch (val)
{
case 0: printf (_("None\n")); break;
@@ -15702,9 +15631,8 @@ display_msp430x_attribute (unsigned char * p,
break;
case OFBA_MSPABI_Tag_Data_Model:
- val = read_uleb128 (p, &len, end);
- p += len;
printf (" Tag_Data_Model: ");
+ READ_ULEB (val, p, end);
switch (val)
{
case 0: printf (_("None\n")); break;
@@ -15737,8 +15665,7 @@ display_msp430x_attribute (unsigned char * p,
}
else
{
- val = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (val, p, end);
printf ("%d (0x%x)\n", val, val);
}
break;
@@ -15755,12 +15682,10 @@ display_msp430_gnu_attribute (unsigned char * p,
{
if (tag == Tag_GNU_MSP430_Data_Region)
{
- unsigned int len;
- int val;
+ unsigned int val;
- val = read_uleb128 (p, &len, end);
- p += len;
printf (" Tag_GNU_MSP430_Data_Region: ");
+ READ_ULEB (val, p, end);
switch (val)
{
@@ -15771,7 +15696,7 @@ display_msp430_gnu_attribute (unsigned char * p,
printf (_("Lower Region Only\n"));
break;
default:
- printf ("??? (%d)\n", val);
+ printf ("??? (%u)\n", val);
}
return p;
}
@@ -15780,7 +15705,7 @@ display_msp430_gnu_attribute (unsigned char * p,
struct riscv_attr_tag_t {
const char *name;
- int tag;
+ unsigned int tag;
};
static struct riscv_attr_tag_t riscv_attr_tag[] =
@@ -15799,14 +15724,12 @@ static unsigned char *
display_riscv_attribute (unsigned char *p,
const unsigned char * const end)
{
- unsigned int len;
- int val;
- int tag;
+ unsigned int val;
+ unsigned int tag;
struct riscv_attr_tag_t *attr = NULL;
unsigned i;
- tag = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (tag, p, end);
/* Find the name of attribute. */
for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
@@ -15828,13 +15751,11 @@ display_riscv_attribute (unsigned char *p,
case Tag_RISCV_priv_spec:
case Tag_RISCV_priv_spec_minor:
case Tag_RISCV_priv_spec_revision:
- val = read_uleb128 (p, &len, end);
- p += len;
- printf (_("%d\n"), val);
+ READ_ULEB (val, p, end);
+ printf (_("%u\n"), val);
break;
case Tag_RISCV_unaligned_access:
- val = read_uleb128 (p, &len, end);
- p += len;
+ READ_ULEB (val, p, end);
switch (val)
{
case 0:
@@ -15846,9 +15767,8 @@ display_riscv_attribute (unsigned char *p,
}
break;
case Tag_RISCV_stack_align:
- val = read_uleb128 (p, &len, end);
- p += len;
- printf (_("%d-bytes\n"), val);
+ READ_ULEB (val, p, end);
+ printf (_("%u-bytes\n"), val);
break;
case Tag_RISCV_arch:
p = display_tag_value (-1, p, end);
@@ -15967,7 +15887,7 @@ process_attributes (Filedata * filedata,
while (attr_len > 0 && p < contents + sect->sh_size)
{
int tag;
- int val;
+ unsigned int val;
bfd_vma size;
unsigned char * end;
@@ -16018,10 +15938,7 @@ process_attributes (Filedata * filedata,
do_numlist:
for (;;)
{
- unsigned int j;
-
- val = read_uleb128 (p, &j, end);
- p += j;
+ READ_ULEB (val, p, end);
if (val == 0)
break;
printf (" %d", val);