aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2013-03-26 22:51:12 +0000
committerNick Clifton <nickc@redhat.com>2013-03-26 22:51:12 +0000
commit0c5882475c48596b92ed08a7ccfa6347d44f8f65 (patch)
treee9b58739300cb048fec1568190619ba858760253
parent2c619be216c9fb729c2696fa10957732290b041a (diff)
downloadgdb-0c5882475c48596b92ed08a7ccfa6347d44f8f65.zip
gdb-0c5882475c48596b92ed08a7ccfa6347d44f8f65.tar.gz
gdb-0c5882475c48596b92ed08a7ccfa6347d44f8f65.tar.bz2
PR binutils/15205
* dwarf.c (SAFE_BYTE_GET): New macro - checks remaining buffer space before calling byte_get. (SAFE_BYTE_GET_AND_INC): New macro. (SAFE_SIGNED_BYTE_GET): New macro. (SAFE_SIGNED_BYTE_GET_AND_INC): New macro. (SAFE_BYTE_GET64): New macro. (process_extened_line_op): Use new macros. Use strnlen when appropriate. (fetch_indirect_string): Likewise. (get_FORM_name): Likewise. (decode_location_expression): Likewise. (read_and_display_attr_value): Likewise. (process_debug_info): Likewise. (display_debug_lines_raw): Likewise. (display_debug_lines_decoded): Likewise. (display_debug_pubnames): Likewise. (display_debug_macinfo): Likewise. (get_line_filename_and_dirname): Likewise. (display_debug_macro): Likewise. (display_loc_list): Likewise. (display_loc_list_dwo): Likewise. (display_debug_aranges): Likewise. (display_debug_ranges): Likewise. (frame_display_row): Likewise. (display_debug_frames): Likewise.
-rw-r--r--binutils/ChangeLog29
-rw-r--r--binutils/dwarf.c578
2 files changed, 330 insertions, 277 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index ebede02..35233c1 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,32 @@
+2013-03-26 Nick Clifton <nickc@redhat.com>
+
+ PR binutils/15205
+ * dwarf.c (SAFE_BYTE_GET): New macro - checks remaining buffer
+ space before calling byte_get.
+ (SAFE_BYTE_GET_AND_INC): New macro.
+ (SAFE_SIGNED_BYTE_GET): New macro.
+ (SAFE_SIGNED_BYTE_GET_AND_INC): New macro.
+ (SAFE_BYTE_GET64): New macro.
+ (process_extened_line_op): Use new macros. Use strnlen when
+ appropriate.
+ (fetch_indirect_string): Likewise.
+ (get_FORM_name): Likewise.
+ (decode_location_expression): Likewise.
+ (read_and_display_attr_value): Likewise.
+ (process_debug_info): Likewise.
+ (display_debug_lines_raw): Likewise.
+ (display_debug_lines_decoded): Likewise.
+ (display_debug_pubnames): Likewise.
+ (display_debug_macinfo): Likewise.
+ (get_line_filename_and_dirname): Likewise.
+ (display_debug_macro): Likewise.
+ (display_loc_list): Likewise.
+ (display_loc_list_dwo): Likewise.
+ (display_debug_aranges): Likewise.
+ (display_debug_ranges): Likewise.
+ (frame_display_row): Likewise.
+ (display_debug_frames): Likewise.
+
2013-03-25 Nick Clifton <nickc@redhat.com>
PR binutils/15202
diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index 4a11aa5..24a5906 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -278,6 +278,73 @@ read_uleb128 (unsigned char * data,
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;
@@ -346,7 +413,7 @@ process_extended_line_op (unsigned char * data,
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;
@@ -358,7 +425,7 @@ process_extended_line_op (unsigned char * data,
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)));
@@ -478,13 +545,13 @@ process_extended_line_op (unsigned char * data,
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;
@@ -492,10 +559,10 @@ fetch_indirect_string (dwarf_vma offset)
{
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 *
@@ -757,10 +824,17 @@ get_FORM_name (unsigned long form)
}
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));
@@ -779,6 +853,7 @@ decode_location_expression (unsigned char * data,
unsigned op;
unsigned int bytes_read;
dwarf_vma uvalue;
+ dwarf_signed_vma svalue;
unsigned char *end = data + length;
int need_frame_base = 0;
@@ -789,44 +864,47 @@ decode_location_expression (unsigned char * data,
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",
@@ -848,7 +926,8 @@ decode_location_expression (unsigned char * data,
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");
@@ -907,8 +986,8 @@ decode_location_expression (unsigned char * data,
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");
@@ -929,8 +1008,8 @@ decode_location_expression (unsigned char * data,
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:
@@ -1069,10 +1148,12 @@ decode_location_expression (unsigned char * data,
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");
@@ -1085,18 +1166,16 @@ decode_location_expression (unsigned char * data,
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
@@ -1109,16 +1188,13 @@ decode_location_expression (unsigned char * data,
}
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");
@@ -1145,7 +1221,7 @@ decode_location_expression (unsigned char * data,
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;
@@ -1181,20 +1257,17 @@ decode_location_expression (unsigned char * data,
}
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);
@@ -1212,8 +1285,8 @@ decode_location_expression (unsigned char * data,
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:
@@ -1226,7 +1299,8 @@ decode_location_expression (unsigned char * data,
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));
@@ -1244,9 +1318,9 @@ decode_location_expression (unsigned char * data,
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);
@@ -1363,6 +1437,12 @@ read_and_display_attr_value (unsigned long attribute,
unsigned char * orig_data = data;
unsigned int bytes_read;
+ if (data == end)
+ {
+ warn (_("corrupt attribute\n"));
+ return data;
+ }
+
switch (form)
{
default:
@@ -1370,31 +1450,23 @@ read_and_display_attr_value (unsigned long attribute,
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:
@@ -1404,19 +1476,17 @@ read_and_display_attr_value (unsigned long attribute,
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:
@@ -1495,25 +1565,28 @@ read_and_display_attr_value (unsigned long attribute,
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:
@@ -1523,34 +1596,34 @@ read_and_display_attr_value (unsigned long attribute,
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:
@@ -1588,7 +1661,7 @@ read_and_display_attr_value (unsigned long attribute,
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)));
}
@@ -2045,11 +2118,11 @@ process_debug_info (struct dwarf_section *section,
/* 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)
@@ -2127,13 +2200,11 @@ process_debug_info (struct dwarf_section *section,
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;
}
@@ -2143,15 +2214,13 @@ process_debug_info (struct dwarf_section *section,
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)
{
@@ -2164,15 +2233,12 @@ process_debug_info (struct dwarf_section *section,
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)
@@ -2498,14 +2564,12 @@ display_debug_lines_raw (struct dwarf_section *section,
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;
}
@@ -2524,8 +2588,7 @@ display_debug_lines_raw (struct dwarf_section *section,
}
/* 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)
@@ -2534,14 +2597,13 @@ display_debug_lines_raw (struct dwarf_section *section,
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"));
@@ -2550,14 +2612,11 @@ display_debug_lines_raw (struct dwarf_section *section,
}
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;
@@ -2600,7 +2659,7 @@ display_debug_lines_raw (struct dwarf_section *section,
{
printf (" %s\n", data);
- data += strlen ((char *) data) + 1;
+ data += strnlen ((char *) data, end - data) + 1;
}
}
@@ -2622,7 +2681,7 @@ display_debug_lines_raw (struct dwarf_section *section,
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)));
@@ -2792,8 +2851,7 @@ display_debug_lines_raw (struct dwarf_section *section,
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"),
@@ -2874,14 +2932,12 @@ display_debug_lines_decoded (struct dwarf_section *section,
(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;
}
@@ -2899,8 +2955,7 @@ display_debug_lines_decoded (struct dwarf_section *section,
}
/* 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)
@@ -2910,14 +2965,12 @@ display_debug_lines_decoded (struct dwarf_section *section,
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"));
@@ -2926,14 +2979,11 @@ display_debug_lines_decoded (struct dwarf_section *section,
}
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;
@@ -2955,7 +3005,7 @@ display_debug_lines_decoded (struct dwarf_section *section,
while (*data != 0)
{
- data += strlen ((char *) data) + 1;
+ data += strnlen ((char *) data, end - data) + 1;
n_directories++;
}
@@ -2967,7 +3017,8 @@ display_debug_lines_decoded (struct dwarf_section *section,
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++;
}
}
@@ -2985,7 +3036,7 @@ display_debug_lines_decoded (struct dwarf_section *section,
/* 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);
@@ -3005,7 +3056,8 @@ display_debug_lines_decoded (struct dwarf_section *section,
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,
@@ -3030,6 +3082,7 @@ display_debug_lines_decoded (struct dwarf_section *section,
{
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
@@ -3103,8 +3156,9 @@ display_debug_lines_decoded (struct dwarf_section *section,
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:
@@ -3231,8 +3285,7 @@ display_debug_lines_decoded (struct dwarf_section *section,
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;
@@ -3388,12 +3441,10 @@ display_debug_pubnames (struct dwarf_section *section,
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;
}
@@ -3403,11 +3454,8 @@ display_debug_pubnames (struct dwarf_section *section,
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
@@ -3415,8 +3463,7 @@ display_debug_pubnames (struct dwarf_section *section,
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;
@@ -3446,13 +3493,13 @@ display_debug_pubnames (struct dwarf_section *section,
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);
@@ -3477,7 +3524,7 @@ display_debug_macinfo (struct dwarf_section *section,
while (curr < end)
{
unsigned int lineno;
- const char *string;
+ const unsigned char *string;
op = (enum dwarf_macinfo_record_type) *curr;
curr++;
@@ -3505,8 +3552,8 @@ display_debug_macinfo (struct dwarf_section *section,
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;
@@ -3514,8 +3561,8 @@ display_debug_macinfo (struct dwarf_section *section,
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;
@@ -3526,8 +3573,8 @@ display_debug_macinfo (struct dwarf_section *section,
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);
}
@@ -3562,13 +3609,12 @@ get_line_filename_and_dirname (dwarf_vma line_offset,
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;
}
@@ -3579,28 +3625,29 @@ get_line_filename_and_dirname (dwarf_vma line_offset,
}
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);
@@ -3611,12 +3658,12 @@ get_line_filename_and_dirname (dwarf_vma line_offset,
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;
@@ -3642,13 +3689,11 @@ display_debug_macro (struct dwarf_section *section,
{
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"),
@@ -3656,7 +3701,7 @@ display_debug_macro (struct dwarf_section *section,
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"),
@@ -3665,15 +3710,17 @@ display_debug_macro (struct dwarf_section *section,
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)
@@ -3681,7 +3728,7 @@ display_debug_macro (struct dwarf_section *section,
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;
@@ -3692,7 +3739,9 @@ display_debug_macro (struct dwarf_section *section,
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)
@@ -3734,7 +3783,7 @@ display_debug_macro (struct dwarf_section *section,
return 0;
}
- op = byte_get (curr++, 1);
+ SAFE_BYTE_GET_AND_INC (op, curr, 1, end);
if (op == 0)
break;
@@ -3774,8 +3823,8 @@ display_debug_macro (struct dwarf_section *section,
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;
@@ -3783,8 +3832,8 @@ display_debug_macro (struct dwarf_section *section,
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;
@@ -3792,8 +3841,7 @@ display_debug_macro (struct dwarf_section *section,
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);
@@ -3802,16 +3850,14 @@ display_debug_macro (struct dwarf_section *section,
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;
@@ -3819,8 +3865,7 @@ display_debug_macro (struct dwarf_section *section,
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;
@@ -3828,15 +3873,13 @@ display_debug_macro (struct dwarf_section *section,
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;
@@ -3862,8 +3905,11 @@ display_debug_macro (struct dwarf_section *section,
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);
@@ -3965,10 +4011,8 @@ display_loc_list (struct dwarf_section *section,
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)
{
@@ -3993,8 +4037,7 @@ display_loc_list (struct dwarf_section *section,
break;
}
- length = byte_get (start, 2);
- start += 2;
+ SAFE_BYTE_GET_AND_INC (length, start, 2, section_end);
if (start + length > section_end)
{
@@ -4076,8 +4119,7 @@ display_loc_list_dwo (struct dwarf_section *section,
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. */
@@ -4103,16 +4145,13 @@ display_loc_list_dwo (struct dwarf_section *section,
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:
@@ -4128,9 +4167,7 @@ display_loc_list_dwo (struct dwarf_section *section,
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"),
@@ -4432,13 +4469,10 @@ display_debug_aranges (struct dwarf_section *section,
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;
}
@@ -4448,11 +4482,8 @@ display_debug_aranges (struct dwarf_section *section,
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
@@ -4460,11 +4491,8 @@ display_debug_aranges (struct dwarf_section *section,
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)
{
@@ -4514,13 +4542,8 @@ display_debug_aranges (struct dwarf_section *section,
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);
@@ -4761,12 +4784,10 @@ display_debug_ranges (struct dwarf_section *section,
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);
@@ -5028,7 +5049,7 @@ frame_display_row (Frame_Chunk *fc, int *need_col_headers, int *max_regs)
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
@@ -5066,8 +5087,8 @@ display_debug_frames (struct dwarf_section *section,
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",
@@ -5077,8 +5098,7 @@ display_debug_frames (struct dwarf_section *section,
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;
}
@@ -5095,7 +5115,8 @@ display_debug_frames (struct dwarf_section *section,
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))
{
@@ -5122,8 +5143,8 @@ display_debug_frames (struct dwarf_section *section,
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
@@ -5135,7 +5156,7 @@ display_debug_frames (struct dwarf_section *section,
fc->data_factor = SLEB ();
if (version == 1)
{
- fc->ra = GET (1);
+ GET (fc->ra, 1);
}
else
{
@@ -5263,14 +5284,17 @@ display_debug_frames (struct dwarf_section *section,
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 ();
@@ -5497,7 +5521,7 @@ display_debug_frames (struct dwarf_section *section,
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
@@ -5508,7 +5532,7 @@ display_debug_frames (struct dwarf_section *section,
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
@@ -5519,7 +5543,7 @@ display_debug_frames (struct dwarf_section *section,
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
@@ -5782,7 +5806,7 @@ display_debug_frames (struct dwarf_section *section,
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