return val;
}
-#if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
-#ifndef __MINGW32__
-#define DWARF_VMA_FMT "ll"
-#define DWARF_VMA_FMT_LONG "%16.16llx"
+#if defined HAVE_LONG_LONG && SIZEOF_LONG_LONG > SIZEOF_LONG
+# ifndef __MINGW32__
+# define DWARF_VMA_FMT "ll"
+# define DWARF_VMA_FMT_LONG "%16.16llx"
+# else
+# define DWARF_VMA_FMT "I64"
+# define DWARF_VMA_FMT_LONG "%016I64x"
+# endif
#else
-#define DWARF_VMA_FMT "I64"
-#define DWARF_VMA_FMT_LONG "%016I64x"
-#endif
-#else
-#define DWARF_VMA_FMT "l"
-#define DWARF_VMA_FMT_LONG "%16.16lx"
+# define DWARF_VMA_FMT "l"
+# define DWARF_VMA_FMT_LONG "%16.16lx"
#endif
/* Convert a dwarf vma value into a string. Returns a pointer to a static
case DW_OP_GNU_entry_value:
uvalue = read_uleb128 (data, &bytes_read, end);
data += bytes_read;
+ /* PR 17531: file: 0cc9cd00. */
+ if (uvalue > (dwarf_vma) (end - data))
+ uvalue = end - data;
printf ("DW_OP_GNU_entry_value: (");
if (decode_location_expression (data, pointer_size, offset_size,
dwarf_version, uvalue,
/* DWARF 5 values. */
case DW_LANG_Go: printf ("(Go)"); break;
case DW_LANG_C_plus_plus_11: printf ("(C++11)"); break;
- case DW_LANG_C11: printf ("(ANSI C11)"); break;
+ case DW_LANG_C11: printf ("(C11)"); break;
case DW_LANG_C_plus_plus_14: printf ("(C++14)"); break;
/* MIPS extension. */
case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break;
/* PR 17512: file:002-117414-0.004. */
if (* end_of_sequence > end)
{
- warn (_("Line length %lld extends beyond end of section\n"), linfo->li_length);
+ warn (_("Line length %s extends beyond end of section\n"),
+ dwarf_vmatoa ("u", linfo->li_length));
* end_of_sequence = end;
return NULL;
}
end_of_sequence = end;
standard_opcodes = NULL;
linfo = saved_linfo;
+ /* PR 17531: file: 0522b371. */
+ if (linfo.li_line_range == 0)
+ {
+ warn (_("Partial .debug_line. section encountered without a prior full .debug_line section"));
+ return 0;
+ }
reset_state_machine (linfo.li_default_is_stmt);
}
else
warn (_("Line range of 0 is invalid, using 1 instead\n"));
linfo.li_line_range = 1;
}
-
+
reset_state_machine (linfo.li_default_is_stmt);
/* Display the contents of the Opcodes table. */
end_of_sequence = end;
standard_opcodes = NULL;
linfo = saved_linfo;
+ /* PR 17531: file: 0522b371. */
+ if (linfo.li_line_range == 0)
+ {
+ warn (_("Partial .debug_line. section encountered without a prior full .debug_line section"));
+ return 0;
+ }
reset_state_machine (linfo.li_default_is_stmt);
}
else
& end_of_sequence)) == NULL)
return 0;
+ /* PR 17531: file: 0522b371. */
+ if (linfo.li_line_range == 0)
+ {
+ warn (_("Line range of 0 is invalid, using 1 instead\n"));
+ linfo.li_line_range = 1;
+ }
reset_state_machine (linfo.li_default_is_stmt);
/* Save a pointer to the contents of the Opcodes table. */
SAFE_BYTE_GET_AND_INC (names.pn_size, data, offset_size, end);
- start += names.pn_length + initial_length_size;
+ /* PR 17531: file: 7615b6b2. */
+ if ((dwarf_signed_vma) names.pn_length < 0)
+ {
+ warn (_("Negative length for public name: 0x%lx\n"), (long) names.pn_length);
+ start = end;
+ }
+ else
+ start += names.pn_length + initial_length_size;
+
+ printf (_(" Length: %ld\n"),
+ (long) names.pn_length);
+ printf (_(" Version: %d\n"),
+ names.pn_version);
+ printf (_(" Offset into .debug_info section: 0x%lx\n"),
+ (unsigned long) names.pn_offset);
+ printf (_(" Size of area in .debug_info section: %ld\n"),
+ (long) names.pn_size);
if (names.pn_version != 2 && names.pn_version != 3)
{
continue;
}
- printf (_(" Length: %ld\n"),
- (long) names.pn_length);
- printf (_(" Version: %d\n"),
- names.pn_version);
- printf (_(" Offset into .debug_info section: 0x%lx\n"),
- (unsigned long) names.pn_offset);
- printf (_(" Size of area in .debug_info section: %ld\n"),
- (long) names.pn_size);
-
if (is_gnu)
printf (_("\n Offset Kind Name\n"));
else
if (fc->ncols == 0)
return -1;
+ /* PR 17512: file: 2844a11d. */
+ if (fc->ncols > 1024)
+ {
+ error (_("Unfeasibly large register number: %u\n"), reg);
+ fc->ncols = 0;
+ /* FIXME: 1024 is an arbitrary limit. Increase it if
+ we ever encounter a valid binary that exceeds it. */
+ return -1;
+ }
+
fc->col_type = (short int *) xcrealloc (fc->col_type, fc->ncols,
sizeof (short int));
fc->col_offset = (int *) xcrealloc (fc->col_offset, fc->ncols, sizeof (int));
if (augmentation_data_len)
{
- unsigned char *p, *q;
+ unsigned char *p;
+ unsigned char *q;
+ unsigned char *qend;
+
p = (unsigned char *) fc->augmentation + 1;
q = augmentation_data;
+ qend = q + augmentation_data_len;
+
+ /* PR 17531: file: 015adfaa. */
+ if (qend < q)
+ {
+ warn (_("Negative augmentation data length: 0x%lx"), augmentation_data_len);
+ augmentation_data_len = 0;
+ }
while (p < end && q < augmentation_data + augmentation_data_len)
{
break;
p++;
}
+
+ if (q < qend)
+ {
+ warn (_("Not enough augmentation data (%lx bytes still needed)\n"),
+ (augmentation_data + augmentation_data_len) - q);
+ augmentation_data_len = q - augmentation_data;
+ }
}
*p_cie = fc;
mreg = max_regs > 0 ? max_regs - 1 : 0;
if (mreg < fc->ra)
mreg = fc->ra;
- frame_need_space (fc, mreg);
+ if (frame_need_space (fc, mreg) < 0)
+ break;
if (fc->fde_encoding)
encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
mreg = max_regs > 0 ? max_regs - 1 : 0;
if (mreg < cie->ra)
mreg = cie->ra;
- frame_need_space (cie, mreg);
+ if (frame_need_space (cie, mreg) < 0)
+ {
+ warn (_("Invalid max register\n"));
+ break;
+ }
if (cie->fde_encoding)
encoded_ptr_size
= size_of_encoded_value (cie->fde_encoding);
fc->ncols = 0;
fc->col_type = (short int *) xmalloc (sizeof (short int));
fc->col_offset = (int *) xmalloc (sizeof (int));
- frame_need_space (fc, max_regs > 0 ? max_regs - 1 : 0);
+ if (frame_need_space (fc, max_regs > 0 ? max_regs - 1 : 0) < 0)
+ {
+ warn (_("Invalid max register\n"));
+ break;
+ }
cie = fc;
fc->augmentation = "";
fc->fde_encoding = 0;
fc->cfa_reg = cie->cfa_reg;
fc->cfa_offset = cie->cfa_offset;
fc->ra = cie->ra;
- frame_need_space (fc, max_regs > 0 ? max_regs - 1: 0);
+ if (frame_need_space (fc, max_regs > 0 ? max_regs - 1: 0) < 0)
+ {
+ warn (_("Invalid max register\n"));
+ break;
+ }
fc->fde_encoding = cie->fde_encoding;
}
augmentation_data = start;
start += augmentation_data_len;
/* PR 17512: file: 722-8446-0.004. */
- if (start >= end)
+ if (start >= end || ((signed long) augmentation_data_len) < 0)
{
warn (_("Corrupt augmentation data length: %lx\n"),
augmentation_data_len);
break;
case DW_CFA_restore_extended:
reg = LEB ();
- frame_need_space (fc, reg);
if (frame_need_space (fc, reg) >= 0)
fc->col_type[reg] = DW_CFA_undefined;
break;
fc->cfa_reg = rs->cfa_reg;
fc->ra = rs->ra;
fc->cfa_exp = rs->cfa_exp;
- frame_need_space (fc, rs->ncols - 1);
+ if (frame_need_space (fc, rs->ncols - 1) < 0)
+ {
+ warn (_("Invalid column number in saved frame state"));
+ fc->ncols = 0;
+ break;
+ }
memcpy (fc->col_type, rs->col_type, rs->ncols * sizeof (* rs->col_type));
memcpy (fc->col_offset, rs->col_offset,
rs->ncols * sizeof (* rs->col_offset));
case DW_CFA_def_cfa_expression:
ul = LEB ();
- if (start >= block_end || start + ul > block_end)
+ if (start >= block_end || start + ul > block_end || start + ul < start)
{
printf (_(" DW_CFA_def_cfa_expression: <corrupt len %lu>\n"), ul);
break;
if (reg >= (unsigned int) fc->ncols)
reg_prefix = bad_reg;
/* PR 17512: file: 069-133014-0.006. */
- if (start >= block_end || start + ul > block_end)
+ /* PR 17512: file: 98c02eb4. */
+ if (start >= block_end || start + ul > block_end || start + ul < start)
{
printf (_(" DW_CFA_expression: <corrupt len %lu>\n"), ul);
break;
ul = LEB ();
if (reg >= (unsigned int) fc->ncols)
reg_prefix = bad_reg;
- if (start >= block_end || start + ul > block_end)
+ if (start >= block_end || start + ul > block_end || start + ul < start)
{
printf (" DW_CFA_val_expression: <corrupt len %lu>\n", ul);
break;
return 0;
}
+ /* PR 17531: file: 418d0a8a. */
+ if (tu_list_offset < cu_list_offset)
+ {
+ warn (_("TU offset (%x) is less than CU offset (%x)\n"),
+ tu_list_offset, cu_list_offset);
+ return 0;
+ }
+
cu_list_elements = (tu_list_offset - cu_list_offset) / 8;
+
+ if (address_table_offset < tu_list_offset)
+ {
+ warn (_("Address table offset (%x) is less than TU offset (%x)\n"),
+ address_table_offset, tu_list_offset);
+ return 0;
+ }
+
tu_list_elements = (address_table_offset - tu_list_offset) / 8;
+
+ /* PR 17531: file: 18a47d3d. */
+ if (symbol_table_offset < address_table_offset)
+ {
+ warn (_("Symbol table offset (%xl) is less then Address table offset (%x)\n"),
+ symbol_table_offset, address_table_offset);
+ return 0;
+ }
+
address_table_size = symbol_table_offset - address_table_offset;
+
+ if (constant_pool_offset < symbol_table_offset)
+ {
+ warn (_("Constant pool offset (%x) is less than symbol table offset (%x)\n"),
+ constant_pool_offset, symbol_table_offset);
+ return 0;
+ }
+
symbol_table_slots = (constant_pool_offset - symbol_table_offset) / 8;
cu_list = start + cu_list_offset;
symbol_table = start + symbol_table_offset;
constant_pool = start + constant_pool_offset;
+ if (address_table + address_table_size * (2 + 8 + 4) > section->start + section->size)
+ {
+ warn (_("Address table extends beyond end of section. %x"), address_table_size);
+ return 0;
+ }
+
printf (_("\nCU table:\n"));
for (i = 0; i < cu_list_elements; i += 2)
{
}
printf (_("\nAddress table:\n"));
- for (i = 0; i < address_table_size; i += 2 * 8 + 4)
+ for (i = 0; i < address_table_size && i <= address_table_size - (2 * 8 + 4);
+ i += 2 * 8 + 4)
{
uint64_t low = byte_get_little_endian (address_table + i, 8);
uint64_t high = byte_get_little_endian (address_table + i + 8, 8);
{
unsigned int j;
- printf ("[%3u] %s:", i, constant_pool + name_offset);
- num_cus = byte_get_little_endian (constant_pool + cu_vector_offset, 4);
+ /* PR 17531: file: 5b7b07ad. */
+ if (constant_pool + name_offset < constant_pool
+ || constant_pool + name_offset >= section->start + section->size)
+ {
+ printf (_("[%3u] <corrupt offset: %x>"), i, name_offset);
+ warn (_("Corrupt name offset of 0x%x found for symbol table slot %d\n"),
+ name_offset, i);
+ }
+ else
+ printf ("[%3u] %.*s:", i,
+ (int) (section->size - (constant_pool_offset + name_offset)),
+ constant_pool + name_offset);
+
+ if (constant_pool + cu_vector_offset < constant_pool
+ || constant_pool + cu_vector_offset >= section->start + section->size)
+ {
+ printf (_("<invalid CU vector offset: %x>\n"), cu_vector_offset);
+ warn (_("Corrupt CU vector offset of 0x%x found for symbol table slot %d\n"),
+ cu_vector_offset, i);
+ continue;
+ }
+ else
+ num_cus = byte_get_little_endian (constant_pool + cu_vector_offset, 4);
+
+ if (num_cus * 4 < num_cus
+ || constant_pool + cu_vector_offset + 4 + num_cus * 4 >=
+ section->start + section->size)
+ {
+ printf ("<invalid number of CUs: %d>\n", num_cus);
+ warn (_("Invalid number of CUs (0x%x) for symbol table slot %d\n"),
+ num_cus, i);
+ continue;
+ }
+
if (num_cus > 1)
printf ("\n");
for (j = 0; j < num_cus; ++j)
if (row != 0)
{
/* PR 17531: file: a05f6ab3. */
- if (row >= nused)
+ if (row > nused)
{
warn (_("Row index (%u) is larger than number of used entries (%u)\n"),
row, nused);
struct dwarf_section_display debug_displays[] =
{
- { { ".debug_abbrev", ".zdebug_abbrev", NULL, NULL, 0, 0, 0 },
+ { { ".debug_abbrev", ".zdebug_abbrev", NULL, NULL, 0, 0, 0, NULL },
display_debug_abbrev, &do_debug_abbrevs, 0 },
- { { ".debug_aranges", ".zdebug_aranges", NULL, NULL, 0, 0, 0 },
+ { { ".debug_aranges", ".zdebug_aranges", NULL, NULL, 0, 0, 0, NULL },
display_debug_aranges, &do_debug_aranges, 1 },
- { { ".debug_frame", ".zdebug_frame", NULL, NULL, 0, 0, 0 },
+ { { ".debug_frame", ".zdebug_frame", NULL, NULL, 0, 0, 0, NULL },
display_debug_frames, &do_debug_frames, 1 },
- { { ".debug_info", ".zdebug_info", NULL, NULL, 0, 0, abbrev },
+ { { ".debug_info", ".zdebug_info", NULL, NULL, 0, 0, abbrev, NULL },
display_debug_info, &do_debug_info, 1 },
- { { ".debug_line", ".zdebug_line", NULL, NULL, 0, 0, 0 },
+ { { ".debug_line", ".zdebug_line", NULL, NULL, 0, 0, 0, NULL },
display_debug_lines, &do_debug_lines, 1 },
- { { ".debug_pubnames", ".zdebug_pubnames", NULL, NULL, 0, 0, 0 },
+ { { ".debug_pubnames", ".zdebug_pubnames", NULL, NULL, 0, 0, 0, NULL },
display_debug_pubnames, &do_debug_pubnames, 0 },
- { { ".debug_gnu_pubnames", ".zdebug_gnu_pubnames", NULL, NULL, 0, 0, 0 },
+ { { ".debug_gnu_pubnames", ".zdebug_gnu_pubnames", NULL, NULL, 0, 0, 0, NULL },
display_debug_gnu_pubnames, &do_debug_pubnames, 0 },
- { { ".eh_frame", "", NULL, NULL, 0, 0, 0 },
+ { { ".eh_frame", "", NULL, NULL, 0, 0, 0, NULL },
display_debug_frames, &do_debug_frames, 1 },
- { { ".debug_macinfo", ".zdebug_macinfo", NULL, NULL, 0, 0, 0 },
+ { { ".debug_macinfo", ".zdebug_macinfo", NULL, NULL, 0, 0, 0, NULL },
display_debug_macinfo, &do_debug_macinfo, 0 },
- { { ".debug_macro", ".zdebug_macro", NULL, NULL, 0, 0, 0 },
+ { { ".debug_macro", ".zdebug_macro", NULL, NULL, 0, 0, 0, NULL },
display_debug_macro, &do_debug_macinfo, 1 },
- { { ".debug_str", ".zdebug_str", NULL, NULL, 0, 0, 0 },
+ { { ".debug_str", ".zdebug_str", NULL, NULL, 0, 0, 0, NULL },
display_debug_str, &do_debug_str, 0 },
- { { ".debug_loc", ".zdebug_loc", NULL, NULL, 0, 0, 0 },
+ { { ".debug_loc", ".zdebug_loc", NULL, NULL, 0, 0, 0, NULL },
display_debug_loc, &do_debug_loc, 1 },
- { { ".debug_pubtypes", ".zdebug_pubtypes", NULL, NULL, 0, 0, 0 },
+ { { ".debug_pubtypes", ".zdebug_pubtypes", NULL, NULL, 0, 0, 0, NULL },
display_debug_pubnames, &do_debug_pubtypes, 0 },
- { { ".debug_gnu_pubtypes", ".zdebug_gnu_pubtypes", NULL, NULL, 0, 0, 0 },
+ { { ".debug_gnu_pubtypes", ".zdebug_gnu_pubtypes", NULL, NULL, 0, 0, 0, NULL },
display_debug_gnu_pubnames, &do_debug_pubtypes, 0 },
- { { ".debug_ranges", ".zdebug_ranges", NULL, NULL, 0, 0, 0 },
+ { { ".debug_ranges", ".zdebug_ranges", NULL, NULL, 0, 0, 0, NULL },
display_debug_ranges, &do_debug_ranges, 1 },
- { { ".debug_static_func", ".zdebug_static_func", NULL, NULL, 0, 0, 0 },
+ { { ".debug_static_func", ".zdebug_static_func", NULL, NULL, 0, 0, 0, NULL },
display_debug_not_supported, NULL, 0 },
- { { ".debug_static_vars", ".zdebug_static_vars", NULL, NULL, 0, 0, 0 },
+ { { ".debug_static_vars", ".zdebug_static_vars", NULL, NULL, 0, 0, 0, NULL },
display_debug_not_supported, NULL, 0 },
- { { ".debug_types", ".zdebug_types", NULL, NULL, 0, 0, abbrev },
+ { { ".debug_types", ".zdebug_types", NULL, NULL, 0, 0, abbrev, NULL },
display_debug_types, &do_debug_info, 1 },
- { { ".debug_weaknames", ".zdebug_weaknames", NULL, NULL, 0, 0, 0 },
+ { { ".debug_weaknames", ".zdebug_weaknames", NULL, NULL, 0, 0, 0, NULL },
display_debug_not_supported, NULL, 0 },
- { { ".gdb_index", "", NULL, NULL, 0, 0, 0 },
+ { { ".gdb_index", "", NULL, NULL, 0, 0, 0, NULL },
display_gdb_index, &do_gdb_index, 0 },
- { { ".trace_info", "", NULL, NULL, 0, 0, trace_abbrev },
+ { { ".trace_info", "", NULL, NULL, 0, 0, trace_abbrev, NULL },
display_trace_info, &do_trace_info, 1 },
- { { ".trace_abbrev", "", NULL, NULL, 0, 0, 0 },
+ { { ".trace_abbrev", "", NULL, NULL, 0, 0, 0, NULL },
display_debug_abbrev, &do_trace_abbrevs, 0 },
- { { ".trace_aranges", "", NULL, NULL, 0, 0, 0 },
+ { { ".trace_aranges", "", NULL, NULL, 0, 0, 0, NULL },
display_debug_aranges, &do_trace_aranges, 0 },
- { { ".debug_info.dwo", ".zdebug_info.dwo", NULL, NULL, 0, 0, abbrev_dwo },
+ { { ".debug_info.dwo", ".zdebug_info.dwo", NULL, NULL, 0, 0, abbrev_dwo, NULL },
display_debug_info, &do_debug_info, 1 },
- { { ".debug_abbrev.dwo", ".zdebug_abbrev.dwo", NULL, NULL, 0, 0, 0 },
+ { { ".debug_abbrev.dwo", ".zdebug_abbrev.dwo", NULL, NULL, 0, 0, 0, NULL },
display_debug_abbrev, &do_debug_abbrevs, 0 },
- { { ".debug_types.dwo", ".zdebug_types.dwo", NULL, NULL, 0, 0, abbrev_dwo },
+ { { ".debug_types.dwo", ".zdebug_types.dwo", NULL, NULL, 0, 0, abbrev_dwo, NULL },
display_debug_types, &do_debug_info, 1 },
- { { ".debug_line.dwo", ".zdebug_line.dwo", NULL, NULL, 0, 0, 0 },
+ { { ".debug_line.dwo", ".zdebug_line.dwo", NULL, NULL, 0, 0, 0, NULL },
display_debug_lines, &do_debug_lines, 1 },
- { { ".debug_loc.dwo", ".zdebug_loc.dwo", NULL, NULL, 0, 0, 0 },
+ { { ".debug_loc.dwo", ".zdebug_loc.dwo", NULL, NULL, 0, 0, 0, NULL },
display_debug_loc, &do_debug_loc, 1 },
- { { ".debug_macro.dwo", ".zdebug_macro.dwo", NULL, NULL, 0, 0, 0 },
+ { { ".debug_macro.dwo", ".zdebug_macro.dwo", NULL, NULL, 0, 0, 0, NULL },
display_debug_macro, &do_debug_macinfo, 1 },
- { { ".debug_macinfo.dwo", ".zdebug_macinfo.dwo", NULL, NULL, 0, 0, 0 },
+ { { ".debug_macinfo.dwo", ".zdebug_macinfo.dwo", NULL, NULL, 0, 0, 0, NULL },
display_debug_macinfo, &do_debug_macinfo, 0 },
- { { ".debug_str.dwo", ".zdebug_str.dwo", NULL, NULL, 0, 0, 0 },
+ { { ".debug_str.dwo", ".zdebug_str.dwo", NULL, NULL, 0, 0, 0, NULL },
display_debug_str, &do_debug_str, 1 },
- { { ".debug_str_offsets", ".zdebug_str_offsets", NULL, NULL, 0, 0, 0 },
+ { { ".debug_str_offsets", ".zdebug_str_offsets", NULL, NULL, 0, 0, 0, NULL },
display_debug_str_offsets, NULL, 0 },
- { { ".debug_str_offsets.dwo", ".zdebug_str_offsets.dwo", NULL, NULL, 0, 0, 0 },
+ { { ".debug_str_offsets.dwo", ".zdebug_str_offsets.dwo", NULL, NULL, 0, 0, 0, NULL },
display_debug_str_offsets, NULL, 0 },
- { { ".debug_addr", ".zdebug_addr", NULL, NULL, 0, 0, 0 },
+ { { ".debug_addr", ".zdebug_addr", NULL, NULL, 0, 0, 0, NULL },
display_debug_addr, &do_debug_addr, 1 },
- { { ".debug_cu_index", "", NULL, NULL, 0, 0, 0 },
+ { { ".debug_cu_index", "", NULL, NULL, 0, 0, 0, NULL },
display_cu_index, &do_debug_cu_index, 0 },
- { { ".debug_tu_index", "", NULL, NULL, 0, 0, 0 },
+ { { ".debug_tu_index", "", NULL, NULL, 0, 0, 0, NULL },
display_cu_index, &do_debug_cu_index, 0 },
};