return read_leb128 (data, length_return, FALSE, end);
}
+#define SAFE_BYTE_GET(VAL, PTR, AMOUNT, END) \
+ do \
+ { \
+ unsigned int amount = (AMOUNT); \
+ if (((PTR) + amount) >= (END)) \
+ { \
+ if ((PTR) < (END)) \
+ amount = (END) - (PTR); \
+ else \
+ amount = 0; \
+ } \
+ if (amount) \
+ VAL = byte_get ((PTR), amount); \
+ else \
+ VAL = 0; \
+ } \
+ while (0)
+
+#define SAFE_BYTE_GET_AND_INC(VAL, PTR, AMOUNT, END) \
+ do \
+ { \
+ SAFE_BYTE_GET (VAL, PTR, AMOUNT, END); \
+ PTR += AMOUNT; \
+ } \
+ while (0)
+
+#define SAFE_SIGNED_BYTE_GET(VAL, PTR, AMOUNT, END) \
+ do \
+ { \
+ unsigned int amount = (AMOUNT); \
+ if (((PTR) + amount) >= (END)) \
+ { \
+ if ((PTR) < (END)) \
+ amount = (END) - (PTR); \
+ else \
+ amount = 0; \
+ } \
+ if (amount) \
+ VAL = byte_get_signed ((PTR), amount); \
+ else \
+ VAL = 0; \
+ } \
+ while (0)
+
+#define SAFE_SIGNED_BYTE_GET_AND_INC(VAL, PTR, AMOUNT, END) \
+ do \
+ { \
+ SAFE_SIGNED_BYTE_GET (VAL, PTR, AMOUNT, END); \
+ PTR += AMOUNT; \
+ } \
+ while (0)
+
+#define SAFE_BYTE_GET64(PTR, HIGH, LOW, END) \
+ do \
+ { \
+ if (((PTR) + 8) < (END)) \
+ { \
+ byte_get_64 ((PTR), (HIGH), (LOW)); \
+ } \
+ else \
+ { \
+ PTR = END; \
+ * (LOW) = * (HIGH) = 0; \
+ } \
+ } \
+ while (0)
+
typedef struct State_Machine_Registers
{
dwarf_vma address;
break;
case DW_LNE_set_address:
- adr = byte_get (data, len - bytes_read - 1);
+ SAFE_BYTE_GET (adr, data, len - bytes_read - 1, end);
printf (_("set Address to 0x%s\n"), dwarf_vmatoa ("x", adr));
state_machine_regs.address = adr;
state_machine_regs.op_index = 0;
printf (" %d\t", ++state_machine_regs.last_file_entry);
name = data;
- data += strlen ((char *) data) + 1;
+ data += strnlen ((char *) data, end - data) + 1;
printf ("%s\t", dwarf_vmatoa ("u", read_uleb128 (data, & bytes_read, end)));
data += bytes_read;
printf ("%s\t", dwarf_vmatoa ("u", read_uleb128 (data, & bytes_read, end)));
return len;
}
-static const char *
+static const unsigned char *
fetch_indirect_string (dwarf_vma offset)
{
struct dwarf_section *section = &debug_displays [str].section;
if (section->start == NULL)
- return _("<no .debug_str section>");
+ return (const unsigned char *) _("<no .debug_str section>");
/* DWARF sections under Mach-O have non-zero addresses. */
offset -= section->address;
{
warn (_("DW_FORM_strp offset too big: %s\n"),
dwarf_vmatoa ("x", offset));
- return _("<offset is too big>");
+ return (const unsigned char *) _("<offset is too big>");
}
- return (const char *) section->start + offset;
+ return (const unsigned char *) section->start + offset;
}
static const char *
}
static unsigned char *
-display_block (unsigned char *data, dwarf_vma length)
+display_block (unsigned char *data,
+ dwarf_vma length,
+ const unsigned char * const end)
{
+ dwarf_vma maxlen;
+
printf (_(" %s byte block: "), dwarf_vmatoa ("u", length));
+ maxlen = (dwarf_vma) (end - data);
+ length = length > maxlen ? maxlen : length;
+
while (length --)
printf ("%lx ", (unsigned long) byte_get (data++, 1));
unsigned op;
unsigned int bytes_read;
dwarf_vma uvalue;
+ dwarf_signed_vma svalue;
unsigned char *end = data + length;
int need_frame_base = 0;
switch (op)
{
case DW_OP_addr:
- printf ("DW_OP_addr: %s",
- dwarf_vmatoa ("x", byte_get (data, pointer_size)));
- data += pointer_size;
+ SAFE_BYTE_GET_AND_INC (uvalue, data, pointer_size, end);
+ printf ("DW_OP_addr: %s", dwarf_vmatoa ("x", uvalue));
break;
case DW_OP_deref:
printf ("DW_OP_deref");
break;
case DW_OP_const1u:
- printf ("DW_OP_const1u: %lu", (unsigned long) byte_get (data++, 1));
+ SAFE_BYTE_GET_AND_INC (uvalue, data, 1, end);
+ printf ("DW_OP_const1u: %lu", (unsigned long) uvalue);
break;
case DW_OP_const1s:
- printf ("DW_OP_const1s: %ld", (long) byte_get_signed (data++, 1));
+ SAFE_SIGNED_BYTE_GET_AND_INC (svalue, data, 1, end);
+ printf ("DW_OP_const1s: %ld", (long) svalue);
break;
case DW_OP_const2u:
- printf ("DW_OP_const2u: %lu", (unsigned long) byte_get (data, 2));
- data += 2;
+ SAFE_BYTE_GET_AND_INC (uvalue, data, 1, end);
+ printf ("DW_OP_const2u: %lu", (unsigned long) uvalue);
break;
case DW_OP_const2s:
- printf ("DW_OP_const2s: %ld", (long) byte_get_signed (data, 2));
- data += 2;
+ SAFE_SIGNED_BYTE_GET_AND_INC (svalue, data, 2, end);
+ printf ("DW_OP_const2s: %ld", (long) svalue);
break;
case DW_OP_const4u:
- printf ("DW_OP_const4u: %lu", (unsigned long) byte_get (data, 4));
- data += 4;
+ SAFE_BYTE_GET_AND_INC (uvalue, data, 4, end);
+ printf ("DW_OP_const4u: %lu", (unsigned long) uvalue);
break;
case DW_OP_const4s:
- printf ("DW_OP_const4s: %ld", (long) byte_get_signed (data, 4));
- data += 4;
+ SAFE_SIGNED_BYTE_GET_AND_INC (svalue, data, 4, end);
+ printf ("DW_OP_const4s: %ld", (long) svalue);
break;
case DW_OP_const8u:
- printf ("DW_OP_const8u: %lu %lu", (unsigned long) byte_get (data, 4),
- (unsigned long) byte_get (data + 4, 4));
- data += 8;
+ SAFE_BYTE_GET_AND_INC (uvalue, data, 4, end);
+ printf ("DW_OP_const8u: %lu ", (unsigned long) uvalue);
+ SAFE_BYTE_GET_AND_INC (uvalue, data, 4, end);
+ printf ("%lu", (unsigned long) uvalue);
break;
case DW_OP_const8s:
- printf ("DW_OP_const8s: %ld %ld", (long) byte_get (data, 4),
- (long) byte_get (data + 4, 4));
- data += 8;
+ SAFE_SIGNED_BYTE_GET_AND_INC (svalue, data, 4, end);
+ printf ("DW_OP_const8s: %ld ", (long) svalue);
+ SAFE_SIGNED_BYTE_GET_AND_INC (svalue, data, 4, end);
+ printf ("%ld", (long) svalue);
break;
case DW_OP_constu:
printf ("DW_OP_constu: %s",
printf ("DW_OP_over");
break;
case DW_OP_pick:
- printf ("DW_OP_pick: %ld", (unsigned long) byte_get (data++, 1));
+ SAFE_BYTE_GET_AND_INC (uvalue, data, 1, end);
+ printf ("DW_OP_pick: %ld", (unsigned long) uvalue);
break;
case DW_OP_swap:
printf ("DW_OP_swap");
printf ("DW_OP_xor");
break;
case DW_OP_bra:
- printf ("DW_OP_bra: %ld", (long) byte_get_signed (data, 2));
- data += 2;
+ SAFE_SIGNED_BYTE_GET_AND_INC (svalue, data, 2, end);
+ printf ("DW_OP_bra: %ld", (long) svalue);
break;
case DW_OP_eq:
printf ("DW_OP_eq");
printf ("DW_OP_ne");
break;
case DW_OP_skip:
- printf ("DW_OP_skip: %ld", (long) byte_get_signed (data, 2));
- data += 2;
+ SAFE_SIGNED_BYTE_GET_AND_INC (svalue, data, 2, end);
+ printf ("DW_OP_skip: %ld", (long) svalue);
break;
case DW_OP_lit0:
data += bytes_read;
break;
case DW_OP_deref_size:
- printf ("DW_OP_deref_size: %ld", (long) byte_get (data++, 1));
+ SAFE_BYTE_GET_AND_INC (uvalue, data, 1, end);
+ printf ("DW_OP_deref_size: %ld", (long) uvalue);
break;
case DW_OP_xderef_size:
- printf ("DW_OP_xderef_size: %ld", (long) byte_get (data++, 1));
+ SAFE_BYTE_GET_AND_INC (uvalue, data, 1, end);
+ printf ("DW_OP_xderef_size: %ld", (long) uvalue);
break;
case DW_OP_nop:
printf ("DW_OP_nop");
case DW_OP_call2:
/* XXX: Strictly speaking for 64-bit DWARF3 files
this ought to be an 8-byte wide computation. */
+ SAFE_SIGNED_BYTE_GET_AND_INC (svalue, data, 2, end);
printf ("DW_OP_call2: <0x%s>",
- dwarf_vmatoa ("x", (dwarf_signed_vma) byte_get (data, 2)
- + cu_offset));
- data += 2;
+ dwarf_vmatoa ("x", svalue + cu_offset));
break;
case DW_OP_call4:
/* XXX: Strictly speaking for 64-bit DWARF3 files
this ought to be an 8-byte wide computation. */
+ SAFE_SIGNED_BYTE_GET_AND_INC (svalue, data, 4, end);
printf ("DW_OP_call4: <0x%s>",
- dwarf_vmatoa ("x", (dwarf_signed_vma) byte_get (data, 4)
- + cu_offset));
- data += 4;
+ dwarf_vmatoa ("x", svalue + cu_offset));
break;
case DW_OP_call_ref:
/* XXX: Strictly speaking for 64-bit DWARF3 files
}
if (dwarf_version == 2)
{
- printf ("DW_OP_call_ref: <0x%s>",
- dwarf_vmatoa ("x", byte_get (data, pointer_size)));
- data += pointer_size;
+ SAFE_BYTE_GET_AND_INC (uvalue, data, pointer_size, end);
}
else
{
- printf ("DW_OP_call_ref: <0x%s>",
- dwarf_vmatoa ("x", byte_get (data, offset_size)));
- data += offset_size;
+ SAFE_BYTE_GET_AND_INC (uvalue, data, offset_size, end);
}
+ printf ("DW_OP_call_ref: <0x%s>", dwarf_vmatoa ("x", uvalue));
break;
case DW_OP_form_tls_address:
printf ("DW_OP_form_tls_address");
printf ("DW_OP_implicit_value");
uvalue = read_uleb128 (data, &bytes_read, end);
data += bytes_read;
- display_block (data, uvalue);
+ display_block (data, uvalue, end);
data += uvalue;
break;
}
if (dwarf_version == 2)
{
- printf ("DW_OP_GNU_implicit_pointer: <0x%s> %s",
- dwarf_vmatoa ("x", byte_get (data, pointer_size)),
- dwarf_vmatoa ("d", read_sleb128 (data + pointer_size,
- &bytes_read, end)));
- data += pointer_size + bytes_read;
+ SAFE_BYTE_GET_AND_INC (uvalue, data, pointer_size, end);
}
else
{
- printf ("DW_OP_GNU_implicit_pointer: <0x%s> %s",
- dwarf_vmatoa ("x", byte_get (data, offset_size)),
- dwarf_vmatoa ("d", read_sleb128 (data + offset_size,
- &bytes_read, end)));
- data += offset_size + bytes_read;
+ SAFE_BYTE_GET_AND_INC (uvalue, data, offset_size, end);
}
+ printf ("DW_OP_GNU_implicit_pointer: <0x%s> %s",
+ dwarf_vmatoa ("x", uvalue),
+ dwarf_vmatoa ("d", read_sleb128 (data,
+ &bytes_read, end)));
+ data += bytes_read;
break;
case DW_OP_GNU_entry_value:
uvalue = read_uleb128 (data, &bytes_read, end);
data += bytes_read;
printf ("DW_OP_GNU_const_type: <0x%s> ",
dwarf_vmatoa ("x", cu_offset + uvalue));
- uvalue = byte_get (data++, 1);
- display_block (data, uvalue);
+ SAFE_BYTE_GET_AND_INC (uvalue, data, 1, end);
+ display_block (data, uvalue, end);
data += uvalue;
break;
case DW_OP_GNU_regval_type:
printf (" <0x%s>", dwarf_vmatoa ("x", cu_offset + uvalue));
break;
case DW_OP_GNU_deref_type:
- printf ("DW_OP_GNU_deref_type: %ld", (long) byte_get (data++, 1));
+ SAFE_BYTE_GET_AND_INC (uvalue, data, 1, end);
+ printf ("DW_OP_GNU_deref_type: %ld", (long) uvalue);
uvalue = read_uleb128 (data, &bytes_read, end);
data += bytes_read;
printf (" <0x%s>", dwarf_vmatoa ("x", cu_offset + uvalue));
dwarf_vmatoa ("x", uvalue ? cu_offset + uvalue : 0));
break;
case DW_OP_GNU_parameter_ref:
+ SAFE_BYTE_GET_AND_INC (uvalue, data, 4, end);
printf ("DW_OP_GNU_parameter_ref: <0x%s>",
- dwarf_vmatoa ("x", cu_offset + byte_get (data, 4)));
- data += 4;
+ dwarf_vmatoa ("x", cu_offset + uvalue));
break;
case DW_OP_GNU_addr_index:
uvalue = read_uleb128 (data, &bytes_read, end);
unsigned char * orig_data = data;
unsigned int bytes_read;
+ if (data == end)
+ {
+ warn (_("corrupt attribute\n"));
+ return data;
+ }
+
switch (form)
{
default:
case DW_FORM_ref_addr:
if (dwarf_version == 2)
- {
- uvalue = byte_get (data, pointer_size);
- data += pointer_size;
- }
+ SAFE_BYTE_GET_AND_INC (uvalue, data, pointer_size, end);
else if (dwarf_version == 3 || dwarf_version == 4)
- {
- uvalue = byte_get (data, offset_size);
- data += offset_size;
- }
+ SAFE_BYTE_GET_AND_INC (uvalue, data, offset_size, end);
else
error (_("Internal error: DWARF version is not 2, 3 or 4.\n"));
break;
case DW_FORM_addr:
- uvalue = byte_get (data, pointer_size);
- data += pointer_size;
+ SAFE_BYTE_GET_AND_INC (uvalue, data, pointer_size, end);
break;
case DW_FORM_strp:
case DW_FORM_sec_offset:
case DW_FORM_GNU_ref_alt:
case DW_FORM_GNU_strp_alt:
- uvalue = byte_get (data, offset_size);
- data += offset_size;
+ SAFE_BYTE_GET_AND_INC (uvalue, data, offset_size, end);
break;
case DW_FORM_flag_present:
case DW_FORM_ref1:
case DW_FORM_flag:
case DW_FORM_data1:
- uvalue = byte_get (data++, 1);
+ SAFE_BYTE_GET_AND_INC (uvalue, data, 1, end);
break;
case DW_FORM_ref2:
case DW_FORM_data2:
- uvalue = byte_get (data, 2);
- data += 2;
+ SAFE_BYTE_GET_AND_INC (uvalue, data, 2, end);
break;
case DW_FORM_ref4:
case DW_FORM_data4:
- uvalue = byte_get (data, 4);
- data += 4;
+ SAFE_BYTE_GET_AND_INC (uvalue, data, 4, end);
break;
case DW_FORM_sdata:
dwarf_vma high_bits;
char buf[64];
- byte_get_64 (data, &high_bits, &uvalue);
+ SAFE_BYTE_GET64 (data, &high_bits, &uvalue, end);
+
printf (" 0x%s",
dwarf_vmatoa64 (high_bits, uvalue, buf, sizeof (buf)));
}
+
if ((do_loc || do_debug_loc || do_debug_ranges)
&& num_debug_info_entries == 0)
{
if (sizeof (uvalue) == 8)
- uvalue = byte_get (data, 8);
+ SAFE_BYTE_GET (uvalue, data, 8, end);
else
error (_("DW_FORM_data8 is unsupported when sizeof (dwarf_vma) != 8\n"));
}
+
data += 8;
break;
case DW_FORM_string:
if (!do_loc)
- printf (" %s", data);
- data += strlen ((char *) data) + 1;
+ printf (" %.*s", end - data, data);
+ data += strnlen ((char *) data, end - data) + 1;
break;
case DW_FORM_block:
if (do_loc)
data = block_start + uvalue;
else
- data = display_block (block_start, uvalue);
+ data = display_block (block_start, uvalue, end);
break;
case DW_FORM_block1:
- uvalue = byte_get (data, 1);
+ SAFE_BYTE_GET (uvalue, data, 1, end);
block_start = data + 1;
if (do_loc)
data = block_start + uvalue;
else
- data = display_block (block_start, uvalue);
+ data = display_block (block_start, uvalue, end);
break;
case DW_FORM_block2:
- uvalue = byte_get (data, 2);
+ SAFE_BYTE_GET (uvalue, data, 2, end);
block_start = data + 2;
if (do_loc)
data = block_start + uvalue;
else
- data = display_block (block_start, uvalue);
+ data = display_block (block_start, uvalue, end);
break;
case DW_FORM_block4:
- uvalue = byte_get (data, 4);
+ SAFE_BYTE_GET (uvalue, data, 4, end);
block_start = data + 4;
if (do_loc)
data = block_start + uvalue;
else
- data = display_block (block_start, uvalue);
+ data = display_block (block_start, uvalue, end);
break;
case DW_FORM_strp:
dwarf_vma high_bits;
char buf[64];
- byte_get_64 (data, &high_bits, &uvalue);
+ SAFE_BYTE_GET64 (data, &high_bits, &uvalue, end);
printf (" signature: 0x%s",
dwarf_vmatoa64 (high_bits, uvalue, buf, sizeof (buf)));
}
/* Read the first 4 bytes. For a 32-bit DWARF section, this
will be the length. For a 64-bit DWARF section, it'll be
the escape code 0xffffffff followed by an 8 byte length. */
- length = byte_get (section_begin, 4);
+ SAFE_BYTE_GET (length, section_begin, 4, end);
if (length == 0xffffffff)
{
- length = byte_get (section_begin + 4, 8);
+ SAFE_BYTE_GET (length, section_begin + 4, 8, end);
section_begin += length + 12;
}
else if (length >= 0xfffffff0 && length < 0xffffffff)
hdrptr = start;
- compunit.cu_length = byte_get (hdrptr, 4);
- hdrptr += 4;
+ SAFE_BYTE_GET_AND_INC (compunit.cu_length, hdrptr, 4, end);
if (compunit.cu_length == 0xffffffff)
{
- compunit.cu_length = byte_get (hdrptr, 8);
- hdrptr += 8;
+ SAFE_BYTE_GET_AND_INC (compunit.cu_length, hdrptr, 8, end);
offset_size = 8;
initial_length_size = 12;
}
initial_length_size = 4;
}
- compunit.cu_version = byte_get (hdrptr, 2);
- hdrptr += 2;
+ SAFE_BYTE_GET_AND_INC (compunit.cu_version, hdrptr, 2, end);
cu_offset = start - section_begin;
this_set = find_cu_tu_set_v2 (cu_offset, do_types);
- compunit.cu_abbrev_offset = byte_get (hdrptr, offset_size);
- hdrptr += offset_size;
+ SAFE_BYTE_GET_AND_INC (compunit.cu_abbrev_offset, hdrptr, offset_size, end);
if (this_set == NULL)
{
abbrev_size = this_set->section_sizes [DW_SECT_ABBREV];
}
- compunit.cu_pointer_size = byte_get (hdrptr, 1);
- hdrptr += 1;
+ SAFE_BYTE_GET_AND_INC (compunit.cu_pointer_size, hdrptr, 1, end);
if (do_types)
{
- byte_get_64 (hdrptr, &signature_high, &signature_low);
- hdrptr += 8;
- type_offset = byte_get (hdrptr, offset_size);
- hdrptr += offset_size;
+ SAFE_BYTE_GET64 (hdrptr, &signature_high, &signature_low, end);
+ SAFE_BYTE_GET_AND_INC (type_offset, hdrptr, offset_size, end);
}
if ((do_loc || do_debug_loc || do_debug_ranges)
hdroff = hdrptr - start;
/* Check the length of the block. */
- linfo.li_length = byte_get (hdrptr, 4);
- hdrptr += 4;
+ SAFE_BYTE_GET_AND_INC (linfo.li_length, hdrptr, 4, end);
if (linfo.li_length == 0xffffffff)
{
/* This section is 64-bit DWARF 3. */
- linfo.li_length = byte_get (hdrptr, 8);
- hdrptr += 8;
+ SAFE_BYTE_GET_AND_INC (linfo.li_length, hdrptr, 8, end);
offset_size = 8;
initial_length_size = 12;
}
}
/* Check its version number. */
- linfo.li_version = byte_get (hdrptr, 2);
- hdrptr += 2;
+ SAFE_BYTE_GET_AND_INC (linfo.li_version, hdrptr, 2, end);
if (linfo.li_version != 2
&& linfo.li_version != 3
&& linfo.li_version != 4)
return 0;
}
- linfo.li_prologue_length = byte_get (hdrptr, offset_size);
- hdrptr += offset_size;
- linfo.li_min_insn_length = byte_get (hdrptr, 1);
- hdrptr++;
+ SAFE_BYTE_GET_AND_INC (linfo.li_prologue_length, hdrptr, offset_size, end);
+ SAFE_BYTE_GET_AND_INC (linfo.li_min_insn_length, hdrptr, 1, end);
+
if (linfo.li_version >= 4)
{
- linfo.li_max_ops_per_insn = byte_get (hdrptr, 1);
- hdrptr++;
+ SAFE_BYTE_GET_AND_INC (linfo.li_max_ops_per_insn, hdrptr, 1, end);
+
if (linfo.li_max_ops_per_insn == 0)
{
warn (_("Invalid maximum operations per insn.\n"));
}
else
linfo.li_max_ops_per_insn = 1;
- linfo.li_default_is_stmt = byte_get (hdrptr, 1);
- hdrptr++;
- linfo.li_line_base = byte_get (hdrptr, 1);
- hdrptr++;
- linfo.li_line_range = byte_get (hdrptr, 1);
- hdrptr++;
- linfo.li_opcode_base = byte_get (hdrptr, 1);
- hdrptr++;
+
+ SAFE_BYTE_GET_AND_INC (linfo.li_default_is_stmt, hdrptr, 1, end);
+ SAFE_BYTE_GET_AND_INC (linfo.li_line_base, hdrptr, 1, end);
+ SAFE_BYTE_GET_AND_INC (linfo.li_line_range, hdrptr, 1, end);
+ SAFE_BYTE_GET_AND_INC (linfo.li_opcode_base, hdrptr, 1, end);
/* Sign extend the line base field. */
linfo.li_line_base <<= 24;
{
printf (" %s\n", data);
- data += strlen ((char *) data) + 1;
+ data += strnlen ((char *) data, end - data) + 1;
}
}
printf (" %d\t", ++state_machine_regs.last_file_entry);
name = data;
- data += strlen ((char *) data) + 1;
+ data += strnlen ((char *) data, end - data) + 1;
printf ("%s\t",
dwarf_vmatoa ("u", read_uleb128 (data, & bytes_read, end)));
break;
case DW_LNS_fixed_advance_pc:
- uladv = byte_get (data, 2);
- data += 2;
+ SAFE_BYTE_GET_AND_INC (uladv, data, 2, end);
state_machine_regs.address += uladv;
state_machine_regs.op_index = 0;
printf (_(" Advance PC by fixed size amount %s to 0x%s\n"),
(section 6.2.4 in the Dwarf3 doc). */
/* Get the length of this CU's line number information block. */
- linfo.li_length = byte_get (hdrptr, 4);
- hdrptr += 4;
+ SAFE_BYTE_GET_AND_INC (linfo.li_length, hdrptr, 4, end);
if (linfo.li_length == 0xffffffff)
{
/* This section is 64-bit DWARF 3. */
- linfo.li_length = byte_get (hdrptr, 8);
- hdrptr += 8;
+ SAFE_BYTE_GET_AND_INC (linfo.li_length, hdrptr, 8, end);
offset_size = 8;
initial_length_size = 12;
}
}
/* Get this CU's Line Number Block version number. */
- linfo.li_version = byte_get (hdrptr, 2);
- hdrptr += 2;
+ SAFE_BYTE_GET_AND_INC (linfo.li_version, hdrptr, 2, end);
if (linfo.li_version != 2
&& linfo.li_version != 3
&& linfo.li_version != 4)
return 0;
}
- linfo.li_prologue_length = byte_get (hdrptr, offset_size);
- hdrptr += offset_size;
- linfo.li_min_insn_length = byte_get (hdrptr, 1);
- hdrptr++;
+ SAFE_BYTE_GET_AND_INC (linfo.li_prologue_length, hdrptr, offset_size, end);
+ SAFE_BYTE_GET_AND_INC (linfo.li_min_insn_length, hdrptr, 1, end);
+
if (linfo.li_version >= 4)
{
- linfo.li_max_ops_per_insn = byte_get (hdrptr, 1);
- hdrptr++;
+ SAFE_BYTE_GET_AND_INC (linfo.li_max_ops_per_insn, hdrptr, 1, end);
if (linfo.li_max_ops_per_insn == 0)
{
warn (_("Invalid maximum operations per insn.\n"));
}
else
linfo.li_max_ops_per_insn = 1;
- linfo.li_default_is_stmt = byte_get (hdrptr, 1);
- hdrptr++;
- linfo.li_line_base = byte_get (hdrptr, 1);
- hdrptr++;
- linfo.li_line_range = byte_get (hdrptr, 1);
- hdrptr++;
- linfo.li_opcode_base = byte_get (hdrptr, 1);
- hdrptr++;
+
+ SAFE_BYTE_GET_AND_INC (linfo.li_default_is_stmt, hdrptr, 1, end);
+ SAFE_BYTE_GET_AND_INC (linfo.li_line_base, hdrptr, 1, end);
+ SAFE_BYTE_GET_AND_INC (linfo.li_line_range, hdrptr, 1, end);
+ SAFE_BYTE_GET_AND_INC (linfo.li_opcode_base, hdrptr, 1, end);
/* Sign extend the line base field. */
linfo.li_line_base <<= 24;
while (*data != 0)
{
- data += strlen ((char *) data) + 1;
+ data += strnlen ((char *) data, end - data) + 1;
n_directories++;
}
while (*ptr_directory_table != 0)
{
directory_table[i] = ptr_directory_table;
- ptr_directory_table += strlen ((char *) ptr_directory_table) + 1;
+ ptr_directory_table += strnlen ((char *) ptr_directory_table,
+ ptr_directory_table - end) + 1;
i++;
}
}
/* Skip Name, directory index, last modification time and length
of file. */
- data += strlen ((char *) data) + 1;
+ data += strnlen ((char *) data, end - data) + 1;
read_uleb128 (data, & bytes_read, end);
data += bytes_read;
read_uleb128 (data, & bytes_read, end);
unsigned int bytes_read;
file_table[i].name = ptr_file_name_table;
- ptr_file_name_table += strlen ((char *) ptr_file_name_table) + 1;
+ ptr_file_name_table += strnlen ((char *) ptr_file_name_table,
+ end - ptr_file_name_table) + 1;
/* We are not interested in directory, time or size. */
file_table[i].directory_index = read_uleb128 (ptr_file_name_table,
{
unsigned int ix = file_table[0].directory_index;
const char *directory = ix ? (char *)directory_table[ix - 1] : ".";
+
if (do_wide || strlen (directory) < 76)
printf (_("CU: %s/%s:\n"), directory, file_table[0].name);
else
reset_state_machine (linfo.li_default_is_stmt);
break;
case DW_LNE_set_address:
- state_machine_regs.address =
- byte_get (op_code_data, ext_op_code_len - bytes_read - 1);
+ SAFE_BYTE_GET_AND_INC (state_machine_regs.address,
+ op_code_data, ext_op_code_len - bytes_read - 1,
+ end);
state_machine_regs.op_index = 0;
break;
case DW_LNE_define_file:
break;
case DW_LNS_fixed_advance_pc:
- uladv = byte_get (data, 2);
- data += 2;
+ SAFE_BYTE_GET_AND_INC (uladv, data, 2, end);
state_machine_regs.address += uladv;
state_machine_regs.op_index = 0;
break;
data = start;
- names.pn_length = byte_get (data, 4);
- data += 4;
+ SAFE_BYTE_GET_AND_INC (names.pn_length, data, 4, end);
if (names.pn_length == 0xffffffff)
{
- names.pn_length = byte_get (data, 8);
- data += 8;
+ SAFE_BYTE_GET_AND_INC (names.pn_length, data, 8, end);
offset_size = 8;
initial_length_size = 12;
}
initial_length_size = 4;
}
- names.pn_version = byte_get (data, 2);
- data += 2;
-
- names.pn_offset = byte_get (data, offset_size);
- data += offset_size;
+ SAFE_BYTE_GET_AND_INC (names.pn_version, data, 2, end);
+ SAFE_BYTE_GET_AND_INC (names.pn_offset, data, offset_size, end);
if (num_debug_info_entries != DEBUG_INFO_UNAVAILABLE
&& num_debug_info_entries > 0
warn (_(".debug_info offset of 0x%lx in %s section does not point to a CU header.\n"),
(unsigned long) names.pn_offset, section->name);
- names.pn_size = byte_get (data, offset_size);
- data += offset_size;
+ SAFE_BYTE_GET_AND_INC (names.pn_size, data, offset_size, end);
start += names.pn_length + initial_length_size;
do
{
- offset = byte_get (data, offset_size);
+ SAFE_BYTE_GET (offset, data, offset_size, end);
if (offset != 0)
{
data += offset_size;
printf (" %-6lx\t%s\n", offset, data);
- data += strlen ((char *) data) + 1;
+ data += strnlen ((char *) data, end - data) + 1;
}
}
while (offset != 0);
while (curr < end)
{
unsigned int lineno;
- const char *string;
+ const unsigned char *string;
op = (enum dwarf_macinfo_record_type) *curr;
curr++;
case DW_MACINFO_define:
lineno = read_uleb128 (curr, & bytes_read, end);
curr += bytes_read;
- string = (char *) curr;
- curr += strlen (string) + 1;
+ string = curr;
+ curr += strnlen ((char *) string, end - string) + 1;
printf (_(" DW_MACINFO_define - lineno : %d macro : %s\n"),
lineno, string);
break;
case DW_MACINFO_undef:
lineno = read_uleb128 (curr, & bytes_read, end);
curr += bytes_read;
- string = (char *) curr;
- curr += strlen (string) + 1;
+ string = curr;
+ curr += strnlen ((char *) string, end - string) + 1;
printf (_(" DW_MACINFO_undef - lineno : %d macro : %s\n"),
lineno, string);
break;
constant = read_uleb128 (curr, & bytes_read, end);
curr += bytes_read;
- string = (char *) curr;
- curr += strlen (string) + 1;
+ string = curr;
+ curr += strnlen ((char *) string, end - string) + 1;
printf (_(" DW_MACINFO_vendor_ext - constant : %d string : %s\n"),
constant, string);
}
hdrptr = section->start + line_offset;
end = section->start + section->size;
- length = byte_get (hdrptr, 4);
- hdrptr += 4;
+
+ SAFE_BYTE_GET_AND_INC (length, hdrptr, 4, end);
if (length == 0xffffffff)
{
/* This section is 64-bit DWARF 3. */
- length = byte_get (hdrptr, 8);
- hdrptr += 8;
+ SAFE_BYTE_GET_AND_INC (length, hdrptr, 8, end);
offset_size = 8;
initial_length_size = 12;
}
}
if (length + initial_length_size > section->size)
return NULL;
- version = byte_get (hdrptr, 2);
- hdrptr += 2;
+
+ SAFE_BYTE_GET_AND_INC (version, hdrptr, 2, end);
if (version != 2 && version != 3 && version != 4)
return NULL;
hdrptr += offset_size + 1;/* Skip prologue_length and min_insn_length. */
if (version >= 4)
hdrptr++; /* Skip max_ops_per_insn. */
hdrptr += 3; /* Skip default_is_stmt, line_base, line_range. */
- opcode_base = byte_get (hdrptr, 1);
+
+ SAFE_BYTE_GET_AND_INC (opcode_base, hdrptr, 1, end);
if (opcode_base == 0)
return NULL;
- hdrptr++;
+
hdrptr += opcode_base - 1;
dirtable = hdrptr;
/* Skip over dirname table. */
while (*hdrptr != '\0')
- hdrptr += strlen ((char *) hdrptr) + 1;
+ hdrptr += strnlen ((char *) hdrptr, end - hdrptr) + 1;
hdrptr++; /* Skip the NUL at the end of the table. */
/* Now skip over preceding filename table entries. */
for (; *hdrptr != '\0' && fileidx > 1; fileidx--)
{
- hdrptr += strlen ((char *) hdrptr) + 1;
+ hdrptr += strnlen ((char *) hdrptr, end - hdrptr) + 1;
read_uleb128 (hdrptr, &bytes_read, end);
hdrptr += bytes_read;
read_uleb128 (hdrptr, &bytes_read, end);
if (hdrptr == end || *hdrptr == '\0')
return NULL;
file_name = hdrptr;
- hdrptr += strlen ((char *) hdrptr) + 1;
+ hdrptr += strnlen ((char *) hdrptr, end - hdrptr) + 1;
diridx = read_uleb128 (hdrptr, &bytes_read, end);
if (diridx == 0)
return file_name;
for (; *dirtable != '\0' && diridx > 1; diridx--)
- dirtable += strlen ((char *) dirtable) + 1;
+ dirtable += strnlen ((char *) dirtable, end - dirtable) + 1;
if (*dirtable == '\0')
return NULL;
*dir_name = dirtable;
{
unsigned int lineno, version, flags;
unsigned int offset_size = 4;
- const char *string;
+ const unsigned char *string;
dwarf_vma line_offset = 0, sec_offset = curr - start, offset;
unsigned char **extended_ops = NULL;
- version = byte_get (curr, 2);
- curr += 2;
-
+ SAFE_BYTE_GET_AND_INC (version, curr, 2, end);
if (version != 4)
{
error (_("Only GNU extension to DWARF 4 of %s is currently supported.\n"),
return 0;
}
- flags = byte_get (curr++, 1);
+ SAFE_BYTE_GET_AND_INC (flags, curr, 1, end);
if (flags & 1)
offset_size = 8;
printf (_(" Offset: 0x%lx\n"),
printf (_(" Offset size: %d\n"), offset_size);
if (flags & 2)
{
- line_offset = byte_get (curr, offset_size);
- curr += offset_size;
+ SAFE_BYTE_GET_AND_INC (line_offset, curr, offset_size, end);
printf (_(" Offset into .debug_line: 0x%lx\n"),
(unsigned long) line_offset);
}
if (flags & 4)
{
- unsigned int i, count = byte_get (curr++, 1), op;
+ unsigned int i, count, op;
dwarf_vma nargs, n;
+
+ SAFE_BYTE_GET_AND_INC (count, curr, 1, end);
+
memset (extended_op_buf, 0, sizeof (extended_op_buf));
extended_ops = extended_op_buf;
if (count)
printf (_(" Extension opcode arguments:\n"));
for (i = 0; i < count; i++)
{
- op = byte_get (curr++, 1);
+ SAFE_BYTE_GET_AND_INC (op, curr, 1, end);
extended_ops[op] = curr;
nargs = read_uleb128 (curr, &bytes_read, end);
curr += bytes_read;
printf (_(" DW_MACRO_GNU_%02x arguments: "), op);
for (n = 0; n < nargs; n++)
{
- unsigned int form = byte_get (curr++, 1);
+ unsigned int form;
+
+ SAFE_BYTE_GET_AND_INC (form, curr, 1, end);
printf ("%s%s", get_FORM_name (form),
n == nargs - 1 ? "\n" : ", ");
switch (form)
return 0;
}
- op = byte_get (curr++, 1);
+ SAFE_BYTE_GET_AND_INC (op, curr, 1, end);
if (op == 0)
break;
case DW_MACRO_GNU_define:
lineno = read_uleb128 (curr, &bytes_read, end);
curr += bytes_read;
- string = (char *) curr;
- curr += strlen (string) + 1;
+ string = curr;
+ curr += strnlen ((char *) string, end - string) + 1;
printf (_(" DW_MACRO_GNU_define - lineno : %d macro : %s\n"),
lineno, string);
break;
case DW_MACRO_GNU_undef:
lineno = read_uleb128 (curr, &bytes_read, end);
curr += bytes_read;
- string = (char *) curr;
- curr += strlen (string) + 1;
+ string = curr;
+ curr += strnlen ((char *) string, end - string) + 1;
printf (_(" DW_MACRO_GNU_undef - lineno : %d macro : %s\n"),
lineno, string);
break;
case DW_MACRO_GNU_define_indirect:
lineno = read_uleb128 (curr, &bytes_read, end);
curr += bytes_read;
- offset = byte_get (curr, offset_size);
- curr += offset_size;
+ SAFE_BYTE_GET_AND_INC (offset, curr, offset_size, end);
string = fetch_indirect_string (offset);
printf (_(" DW_MACRO_GNU_define_indirect - lineno : %d macro : %s\n"),
lineno, string);
case DW_MACRO_GNU_undef_indirect:
lineno = read_uleb128 (curr, &bytes_read, end);
curr += bytes_read;
- offset = byte_get (curr, offset_size);
- curr += offset_size;
+ SAFE_BYTE_GET_AND_INC (offset, curr, offset_size, end);
string = fetch_indirect_string (offset);
printf (_(" DW_MACRO_GNU_undef_indirect - lineno : %d macro : %s\n"),
lineno, string);
break;
case DW_MACRO_GNU_transparent_include:
- offset = byte_get (curr, offset_size);
- curr += offset_size;
+ SAFE_BYTE_GET_AND_INC (offset, curr, offset_size, end);
printf (_(" DW_MACRO_GNU_transparent_include - offset : 0x%lx\n"),
(unsigned long) offset);
break;
case DW_MACRO_GNU_define_indirect_alt:
lineno = read_uleb128 (curr, &bytes_read, end);
curr += bytes_read;
- offset = byte_get (curr, offset_size);
- curr += offset_size;
+ SAFE_BYTE_GET_AND_INC (offset, curr, offset_size, end);
printf (_(" DW_MACRO_GNU_define_indirect_alt - lineno : %d macro offset : 0x%lx\n"),
lineno, (unsigned long) offset);
break;
case DW_MACRO_GNU_undef_indirect_alt:
lineno = read_uleb128 (curr, &bytes_read, end);
curr += bytes_read;
- offset = byte_get (curr, offset_size);
- curr += offset_size;
+ SAFE_BYTE_GET_AND_INC (offset, curr, offset_size, end);
printf (_(" DW_MACRO_GNU_undef_indirect_alt - lineno : %d macro offset : 0x%lx\n"),
lineno, (unsigned long) offset);
break;
case DW_MACRO_GNU_transparent_include_alt:
- offset = byte_get (curr, offset_size);
- curr += offset_size;
+ SAFE_BYTE_GET_AND_INC (offset, curr, offset_size, end);
printf (_(" DW_MACRO_GNU_transparent_include_alt - offset : 0x%lx\n"),
(unsigned long) offset);
break;
printf (_(" DW_MACRO_GNU_%02x -"), op);
for (n = 0; n < nargs; n++)
{
+ int val;
+
+ SAFE_BYTE_GET_AND_INC (val, desc, 1, end);
curr
- = read_and_display_attr_value (0, byte_get (desc++, 1),
+ = read_and_display_attr_value (0, val,
curr, end, 0, 0, offset_size,
version, NULL, 0, NULL,
NULL);
the -1 escape value. Sign extension into the top 32 bits of a 32-bit
address will not affect the values that we display since we always show
hex values, and always the bottom 32-bits. */
- begin = byte_get_signed (start, pointer_size);
- start += pointer_size;
- end = byte_get_signed (start, pointer_size);
- start += pointer_size;
+ SAFE_BYTE_GET_AND_INC (begin, start, pointer_size, section_end);
+ SAFE_BYTE_GET_AND_INC (end, start, pointer_size, section_end);
if (begin == 0 && end == 0)
{
break;
}
- length = byte_get (start, 2);
- start += 2;
+ SAFE_BYTE_GET_AND_INC (length, start, 2, section_end);
if (start + length > section_end)
{
break;
}
- entry_type = byte_get (start, 1);
- start++;
+ SAFE_BYTE_GET_AND_INC (entry_type, start, 1, section_end);
switch (entry_type)
{
case 0: /* A terminating entry. */
idx = read_uleb128 (start, &bytes_read, section_end);
start += bytes_read;
print_addr_index (idx, 8);
- idx = byte_get (start, 4);
- start += 4;
+ SAFE_BYTE_GET_AND_INC (idx, start, 4, section_end);
printf ("%08x ", idx);
break;
case 4: /* An offset pair entry. */
- idx = byte_get (start, 4);
- start += 4;
+ SAFE_BYTE_GET_AND_INC (idx, start, 4, section_end);
printf ("%08x ", idx);
- idx = byte_get (start, 4);
- start += 4;
+ SAFE_BYTE_GET_AND_INC (idx, start, 4, section_end);
printf ("%08x ", idx);
break;
default:
break;
}
- length = byte_get (start, 2);
- start += 2;
-
+ SAFE_BYTE_GET_AND_INC (length, start, 2, section_end);
if (start + length > section_end)
{
warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
hdrptr = start;
- arange.ar_length = byte_get (hdrptr, 4);
- hdrptr += 4;
-
+ SAFE_BYTE_GET_AND_INC (arange.ar_length, hdrptr, 4, end);
if (arange.ar_length == 0xffffffff)
{
- arange.ar_length = byte_get (hdrptr, 8);
- hdrptr += 8;
+ SAFE_BYTE_GET_AND_INC (arange.ar_length, hdrptr, 8, end);
offset_size = 8;
initial_length_size = 12;
}
initial_length_size = 4;
}
- arange.ar_version = byte_get (hdrptr, 2);
- hdrptr += 2;
-
- arange.ar_info_offset = byte_get (hdrptr, offset_size);
- hdrptr += offset_size;
+ SAFE_BYTE_GET_AND_INC (arange.ar_version, hdrptr, 2, end);
+ SAFE_BYTE_GET_AND_INC (arange.ar_info_offset, hdrptr, offset_size, end);
if (num_debug_info_entries != DEBUG_INFO_UNAVAILABLE
&& num_debug_info_entries > 0
warn (_(".debug_info offset of 0x%lx in %s section does not point to a CU header.\n"),
(unsigned long) arange.ar_info_offset, section->name);
- arange.ar_pointer_size = byte_get (hdrptr, 1);
- hdrptr += 1;
-
- arange.ar_segment_size = byte_get (hdrptr, 1);
- hdrptr += 1;
+ SAFE_BYTE_GET_AND_INC (arange.ar_pointer_size, hdrptr, 1, end);
+ SAFE_BYTE_GET_AND_INC (arange.ar_segment_size, hdrptr, 1, end);
if (arange.ar_version != 2 && arange.ar_version != 3)
{
while (addr_ranges + 2 * address_size <= start)
{
- address = byte_get (addr_ranges, address_size);
-
- addr_ranges += address_size;
-
- length = byte_get (addr_ranges, address_size);
-
- addr_ranges += address_size;
+ SAFE_BYTE_GET_AND_INC (address, addr_ranges, address_size, end);
+ SAFE_BYTE_GET_AND_INC (length, addr_ranges, address_size, end);
printf (" ");
print_dwarf_vma (address, address_size);
top 32 bits of a 32-bit address will not affect the values
that we display since we always show hex values, and always
the bottom 32-bits. */
- begin = byte_get_signed (start, pointer_size);
- start += pointer_size;
+ SAFE_BYTE_GET_AND_INC (begin, start, pointer_size, finish);
if (start >= finish)
break;
- end = byte_get_signed (start, pointer_size);
- start += pointer_size;
+ SAFE_SIGNED_BYTE_GET_AND_INC (end, start, pointer_size, finish);
printf (" %8.8lx ", offset);
printf ("\n");
}
-#define GET(N) byte_get (start, N); start += N
+#define GET(VAR, N) SAFE_BYTE_GET_AND_INC (VAR, start, N, end);
#define LEB() read_uleb128 (start, & length_return, end); start += length_return
#define SLEB() read_sleb128 (start, & length_return, end); start += length_return
int initial_length_size;
saved_start = start;
- length = byte_get (start, 4); start += 4;
+ SAFE_BYTE_GET_AND_INC (length, start, 4, end);
if (length == 0)
{
printf ("\n%08lx ZERO terminator\n\n",
if (length == 0xffffffff)
{
- length = byte_get (start, 8);
- start += 8;
+ SAFE_BYTE_GET_AND_INC (length, start, 8, end);
offset_size = 8;
initial_length_size = 12;
}
length, (unsigned long)(saved_start - section_start));
block_end = end;
}
- cie_id = byte_get (start, offset_size); start += offset_size;
+
+ SAFE_BYTE_GET_AND_INC (cie_id, start, offset_size, end);
if (is_eh ? (cie_id == 0) : (cie_id == DW_CIE_ID))
{
if (version >= 4)
{
- fc->ptr_size = GET (1);
- fc->segment_size = GET (1);
+ GET (fc->ptr_size, 1);
+ GET (fc->segment_size, 1);
eh_addr_size = fc->ptr_size;
}
else
fc->data_factor = SLEB ();
if (version == 1)
{
- fc->ra = GET (1);
+ GET (fc->ra, 1);
}
else
{
segment_selector = 0;
if (fc->segment_size)
{
- segment_selector = byte_get (start, fc->segment_size);
- start += fc->segment_size;
+ SAFE_BYTE_GET_AND_INC (segment_selector, start, fc->segment_size, end);
}
fc->pc_begin = get_encoded_value (start, fc->fde_encoding, section);
start += encoded_ptr_size;
- fc->pc_range = byte_get (start, encoded_ptr_size);
- start += encoded_ptr_size;
+ /* FIXME: It appears that sometimes the final pc_range value is
+ encoded in less than encoded_ptr_size bytes. See the x86_64
+ run of the "objcopy on compressed debug sections" test for an
+ example of this. */
+ SAFE_BYTE_GET_AND_INC (fc->pc_range, start, encoded_ptr_size, end);
+
if (cie->augmentation[0] == 'z')
{
augmentation_data_len = LEB ();
break;
case DW_CFA_advance_loc1:
- ofs = byte_get (start, 1); start += 1;
+ SAFE_BYTE_GET_AND_INC (ofs, start, 1, end);
if (do_debug_frames_interp)
frame_display_row (fc, &need_col_headers, &max_regs);
else
break;
case DW_CFA_advance_loc2:
- ofs = byte_get (start, 2); start += 2;
+ SAFE_BYTE_GET_AND_INC (ofs, start, 2, end);
if (do_debug_frames_interp)
frame_display_row (fc, &need_col_headers, &max_regs);
else
break;
case DW_CFA_advance_loc4:
- ofs = byte_get (start, 4); start += 4;
+ SAFE_BYTE_GET_AND_INC (ofs, start, 4, end);
if (do_debug_frames_interp)
frame_display_row (fc, &need_col_headers, &max_regs);
else
break;
case DW_CFA_MIPS_advance_loc8:
- ofs = byte_get (start, 8); start += 8;
+ SAFE_BYTE_GET_AND_INC (ofs, start, 8, end);
if (do_debug_frames_interp)
frame_display_row (fc, &need_col_headers, &max_regs);
else