aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2024-06-29 17:44:12 +0930
committerAlan Modra <amodra@gmail.com>2024-06-30 14:41:37 +0930
commit4b8c2aaf2d37c6f2a2d21e208d5473d2e4f13df9 (patch)
treed8a5ec64ab6082de9904670447d825d32dd65ecd
parent6e46bdf64e3eb3be2bcb02f229a48b050b8431eb (diff)
downloadgdb-4b8c2aaf2d37c6f2a2d21e208d5473d2e4f13df9.zip
gdb-4b8c2aaf2d37c6f2a2d21e208d5473d2e4f13df9.tar.gz
gdb-4b8c2aaf2d37c6f2a2d21e208d5473d2e4f13df9.tar.bz2
Assertion `(data) <= (end)' failed in read_bases
* dwarf.c (skip_attribute): Don't increment data past end. Use SKIP_{S,U}LEB rather than READ_{S,U}LEB.
-rw-r--r--binutils/dwarf.c53
1 files changed, 29 insertions, 24 deletions
diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index d1699e7..972bb92 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -3574,15 +3574,15 @@ skip_attribute (unsigned long form,
int dwarf_version)
{
uint64_t temp;
- int64_t stemp;
+ size_t inc;
switch (form)
{
case DW_FORM_ref_addr:
- data += dwarf_version == 2 ? pointer_size : offset_size;
+ inc = dwarf_version == 2 ? pointer_size : offset_size;
break;
case DW_FORM_addr:
- data += pointer_size;
+ inc = pointer_size;
break;
case DW_FORM_strp_sup:
case DW_FORM_strp:
@@ -3590,44 +3590,44 @@ skip_attribute (unsigned long form,
case DW_FORM_sec_offset:
case DW_FORM_GNU_ref_alt:
case DW_FORM_GNU_strp_alt:
- data += offset_size;
+ inc = offset_size;
break;
case DW_FORM_ref1:
case DW_FORM_flag:
case DW_FORM_data1:
case DW_FORM_strx1:
case DW_FORM_addrx1:
- data += 1;
+ inc = 1;
break;
case DW_FORM_ref2:
case DW_FORM_data2:
case DW_FORM_strx2:
case DW_FORM_addrx2:
- data += 2;
+ inc = 2;
break;
case DW_FORM_strx3:
case DW_FORM_addrx3:
- data += 3;
+ inc = 3;
break;
case DW_FORM_ref_sup4:
case DW_FORM_ref4:
case DW_FORM_data4:
case DW_FORM_strx4:
case DW_FORM_addrx4:
- data += 4;
+ inc = 4;
break;
case DW_FORM_ref_sup8:
case DW_FORM_ref8:
case DW_FORM_data8:
case DW_FORM_ref_sig8:
- data += 8;
+ inc = 8;
break;
case DW_FORM_data16:
- data += 16;
+ inc = 16;
break;
case DW_FORM_sdata:
- READ_SLEB (stemp, data, end);
- break;
+ SKIP_SLEB (data, end);
+ return data;
case DW_FORM_GNU_str_index:
case DW_FORM_strx:
case DW_FORM_ref_udata:
@@ -3636,41 +3636,45 @@ skip_attribute (unsigned long form,
case DW_FORM_addrx:
case DW_FORM_loclistx:
case DW_FORM_rnglistx:
- READ_ULEB (temp, data, end);
- break;
-
+ SKIP_ULEB (data, end);
+ return data;
case DW_FORM_indirect:
while (form == DW_FORM_indirect)
READ_ULEB (form, data, end);
- return skip_attribute (form, data, end, pointer_size, offset_size, dwarf_version);
+ return skip_attribute (form, data, end, pointer_size, offset_size,
+ dwarf_version);
case DW_FORM_string:
- data += strnlen ((char *) data, end - data);
+ inc = strnlen ((char *) data, end - data);
break;
case DW_FORM_block:
case DW_FORM_exprloc:
READ_ULEB (temp, data, end);
- data += temp;
+ inc = temp;
break;
case DW_FORM_block1:
SAFE_BYTE_GET_AND_INC (temp, data, 1, end);
- data += temp;
+ inc = temp;
break;
case DW_FORM_block2:
SAFE_BYTE_GET_AND_INC (temp, data, 2, end);
- data += temp;
+ inc = temp;
break;
case DW_FORM_block4:
SAFE_BYTE_GET_AND_INC (temp, data, 4, end);
- data += temp;
+ inc = temp;
break;
case DW_FORM_implicit_const:
case DW_FORM_flag_present:
- break;
+ return data;
default:
warn (_("Unexpected form in top DIE\n"));
- break;
+ return data;
}
+ if (inc <= (size_t) (end - data))
+ data += inc;
+ else
+ data = end;
return data;
}
@@ -3701,7 +3705,8 @@ read_bases (abbrev_entry * entry,
else
warn (_("Unexpected form of DW_AT_rnglists_base in the top DIE\n"));
}
- else if (attr->attribute == DW_AT_addr_base || attr->attribute == DW_AT_GNU_addr_base)
+ else if (attr->attribute == DW_AT_addr_base
+ || attr->attribute == DW_AT_GNU_addr_base)
{
if (attr->form == DW_FORM_sec_offset)
{