/* dwarf.c -- display DWARF contents of a BFD binary file
- Copyright 2005, 2006, 2007, 2008, 2009, 2010
+ Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
This file is part of GNU Binutils.
int do_trace_aranges;
int do_wide;
+int dwarf_cutoff_level = -1;
+unsigned long dwarf_start_die;
+
/* Values for do_debug_lines. */
#define FLAG_DEBUG_LINES_RAW 1
#define FLAG_DEBUG_LINES_DECODED 2
print_dwarf_vma (dwarf_vma val, unsigned byte_size)
{
static char buff[18];
+ int offset = 0;
/* Printf does not have a way of specifiying a maximum field width for an
integer value, so we print the full value into a buffer and then select
the precision we need. */
#if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
-#ifndef __MSVCRT__
+#ifndef __MINGW32__
snprintf (buff, sizeof (buff), "%16.16llx ", val);
#else
snprintf (buff, sizeof (buff), "%016I64x ", val);
snprintf (buff, sizeof (buff), "%16.16lx ", val);
#endif
- fputs (buff + (byte_size == 4 ? 8 : 0), stdout);
+ if (byte_size != 0)
+ {
+ if (byte_size > 0 && byte_size <= 8)
+ offset = 16 - 2 * byte_size;
+ else
+ error ("Wrong size in print_dwarf_vma");
+ }
+
+ fputs (buff + offset, stdout);
+}
+
+#if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
+#ifndef __MINGW32__
+#define DWARF_VMA_FMT "ll"
+#else
+#define DWARF_VMA_FMT "I64"
+#endif
+#else
+#define DWARF_VMA_FMT "l"
+#endif
+
+static const char *
+dwarf_vmatoa (const char *fmtch, dwarf_vma value)
+{
+ /* As dwarf_vmatoa is used more then once in a printf call
+ for output, we are cycling through an fixed array of pointers
+ for return address. */
+ static int buf_pos = 0;
+ static struct dwarf_vmatoa_buf
+ {
+ char place[64];
+ } buf[16];
+ char fmt[32];
+ char *ret;
+
+ sprintf (fmt, "%%%s%s", DWARF_VMA_FMT, fmtch);
+
+ ret = buf[buf_pos++].place;
+ buf_pos %= ARRAY_SIZE (buf);
+
+ snprintf (ret, sizeof (buf[0].place), fmt, value);
+
+ return ret;
}
-unsigned long int
+dwarf_vma
read_leb128 (unsigned char *data, unsigned int *length_return, int sign)
{
- unsigned long int result = 0;
+ dwarf_vma result = 0;
unsigned int num_read = 0;
unsigned int shift = 0;
unsigned char byte;
byte = *data++;
num_read++;
- result |= ((unsigned long int) (byte & 0x7f)) << shift;
+ result |= ((dwarf_vma) (byte & 0x7f)) << shift;
shift += 7;
return result;
}
+/* Create a signed version to avoid painful typecasts. */
+static dwarf_signed_vma
+read_sleb128 (unsigned char *data, unsigned int *length_return)
+{
+ return (dwarf_signed_vma) read_leb128 (data, length_return, 1);
+}
+
typedef struct State_Machine_Registers
{
- unsigned long address;
+ dwarf_vma address;
unsigned int file;
unsigned int line;
unsigned int column;
unsigned int bytes_read;
unsigned int len;
unsigned char *name;
- unsigned long adr;
+ dwarf_vma adr;
len = read_leb128 (data, & bytes_read, 0);
data += bytes_read;
case DW_LNE_set_address:
adr = byte_get (data, len - bytes_read - 1);
- printf (_("set Address to 0x%lx\n"), adr);
+ printf (_("set Address to 0x%s\n"), dwarf_vmatoa ("x", adr));
state_machine_regs.address = adr;
state_machine_regs.op_index = 0;
break;
printf (" %d\t", ++state_machine_regs.last_file_entry);
name = data;
data += strlen ((char *) data) + 1;
- printf ("%lu\t", read_leb128 (data, & bytes_read, 0));
+ printf ("%s\t", dwarf_vmatoa ("u", read_leb128 (data, & bytes_read, 0)));
data += bytes_read;
- printf ("%lu\t", read_leb128 (data, & bytes_read, 0));
+ printf ("%s\t", dwarf_vmatoa ("u", read_leb128 (data, & bytes_read, 0)));
data += bytes_read;
- printf ("%lu\t", read_leb128 (data, & bytes_read, 0));
+ printf ("%s\t", dwarf_vmatoa ("u", read_leb128 (data, & bytes_read, 0)));
printf ("%s\n\n", name);
break;
case DW_LNE_set_discriminator:
- printf (_("set Discriminator to %lu\n"),
- read_leb128 (data, & bytes_read, 0));
+ printf (_("set Discriminator to %s\n"),
+ dwarf_vmatoa ("u", read_leb128 (data, & bytes_read, 0)));
break;
/* HP extensions. */
case DW_LNE_HP_define_proc:
printf ("DW_LNE_HP_define_proc\n");
break;
+ case DW_LNE_HP_source_file_correlation:
+ {
+ unsigned char *edata = data + len - bytes_read - 1;
+
+ printf ("DW_LNE_HP_source_file_correlation\n");
+
+ while (data < edata)
+ {
+ unsigned int opc;
+
+ opc = read_leb128 (data, & bytes_read, 0);
+ data += bytes_read;
+
+ switch (opc)
+ {
+ case DW_LNE_HP_SFC_formfeed:
+ printf (" DW_LNE_HP_SFC_formfeed\n");
+ break;
+ case DW_LNE_HP_SFC_set_listing_line:
+ printf (" DW_LNE_HP_SFC_set_listing_line (%s)\n",
+ dwarf_vmatoa ("u",
+ read_leb128 (data, & bytes_read, 0)));
+ data += bytes_read;
+ break;
+ case DW_LNE_HP_SFC_associate:
+ printf (" DW_LNE_HP_SFC_associate ");
+ printf (_("(%s"),
+ dwarf_vmatoa ("u",
+ read_leb128 (data, & bytes_read, 0)));
+ data += bytes_read;
+ printf (_(",%s"),
+ dwarf_vmatoa ("u",
+ read_leb128 (data, & bytes_read, 0)));
+ data += bytes_read;
+ printf (_(",%s)\n"),
+ dwarf_vmatoa ("u",
+ read_leb128 (data, & bytes_read, 0)));
+ data += bytes_read;
+ break;
+ default:
+ printf (" UNKNOW DW_LNE_HP_SFC opcode (%u)\n", opc);
+ data = edata;
+ break;
+ }
+ }
+ }
+ break;
default:
- if (op_code >= DW_LNE_lo_user
- /* The test against DW_LNW_hi_user is redundant due to
- the limited range of the unsigned char data type used
- for op_code. */
- /*&& op_code <= DW_LNE_hi_user*/)
- printf (_("user defined: length %d\n"), len - bytes_read);
- else
- printf (_("UNKNOWN: length %d\n"), len - bytes_read);
+ {
+ unsigned int rlen = len - bytes_read - 1;
+
+ if (op_code >= DW_LNE_lo_user
+ /* The test against DW_LNW_hi_user is redundant due to
+ the limited range of the unsigned char data type used
+ for op_code. */
+ /*&& op_code <= DW_LNE_hi_user*/)
+ printf (_("user defined: "));
+ else
+ printf (_("UNKNOWN: "));
+ printf (_("length %d ["), rlen);
+ for (; rlen; rlen--)
+ printf (" %02x", *data++);
+ printf ("]\n");
+ }
break;
}
}
static const char *
-fetch_indirect_string (unsigned long offset)
+fetch_indirect_string (dwarf_vma offset)
{
struct dwarf_section *section = &debug_displays [str].section;
offset -= section->address;
if (offset > section->size)
{
- warn (_("DW_FORM_strp offset too big: %lx\n"), offset);
+ warn (_("DW_FORM_strp offset too big: %s\n"),
+ dwarf_vmatoa ("x", offset));
return _("<offset is too big>");
}
abbrev_entry *entry;
entry = (abbrev_entry *) malloc (sizeof (*entry));
-
if (entry == NULL)
/* ugg */
return;
abbrev_attr *attr;
attr = (abbrev_attr *) malloc (sizeof (*attr));
-
if (attr == NULL)
/* ugg */
return;
case DW_TAG_upc_shared_type: return "DW_TAG_upc_shared_type";
case DW_TAG_upc_strict_type: return "DW_TAG_upc_strict_type";
case DW_TAG_upc_relaxed_type: return "DW_TAG_upc_relaxed_type";
+ /* GNU values. */
+ case DW_TAG_GNU_call_site: return "DW_TAG_GNU_call_site";
+ case DW_TAG_GNU_call_site_parameter:return "DW_TAG_GNU_call_site_parameter";
default:
{
static char buffer[100];
}
static unsigned char *
-display_block (unsigned char *data, unsigned long length)
+display_block (unsigned char *data, dwarf_vma length)
{
- printf (_(" %lu byte block: "), length);
+ printf (_(" %s byte block: "), dwarf_vmatoa ("u", length));
while (length --)
printf ("%lx ", (unsigned long) byte_get (data++, 1));
unsigned int pointer_size,
unsigned int offset_size,
int dwarf_version,
- unsigned long length,
- unsigned long cu_offset,
+ dwarf_vma length,
+ dwarf_vma cu_offset,
struct dwarf_section * section)
{
unsigned op;
unsigned int bytes_read;
- unsigned long uvalue;
+ dwarf_vma uvalue;
unsigned char *end = data + length;
int need_frame_base = 0;
switch (op)
{
case DW_OP_addr:
- printf ("DW_OP_addr: %lx",
- (unsigned long) byte_get (data, pointer_size));
+ printf ("DW_OP_addr: %s",
+ dwarf_vmatoa ("x", byte_get (data, pointer_size)));
data += pointer_size;
break;
case DW_OP_deref:
data += 8;
break;
case DW_OP_constu:
- printf ("DW_OP_constu: %lu", read_leb128 (data, &bytes_read, 0));
+ printf ("DW_OP_constu: %s",
+ dwarf_vmatoa ("u", read_leb128 (data, &bytes_read, 0)));
data += bytes_read;
break;
case DW_OP_consts:
- printf ("DW_OP_consts: %ld", read_leb128 (data, &bytes_read, 1));
+ printf ("DW_OP_consts: %s",
+ dwarf_vmatoa ("d", read_sleb128 (data, &bytes_read)));
data += bytes_read;
break;
case DW_OP_dup:
printf ("DW_OP_plus");
break;
case DW_OP_plus_uconst:
- printf ("DW_OP_plus_uconst: %lu",
- read_leb128 (data, &bytes_read, 0));
+ printf ("DW_OP_plus_uconst: %s",
+ dwarf_vmatoa ("u", read_leb128 (data, &bytes_read, 0)));
data += bytes_read;
break;
case DW_OP_shl:
case DW_OP_breg29:
case DW_OP_breg30:
case DW_OP_breg31:
- printf ("DW_OP_breg%d (%s): %ld", op - DW_OP_breg0,
+ printf ("DW_OP_breg%d (%s): %s",
+ op - DW_OP_breg0,
regname (op - DW_OP_breg0, 1),
- read_leb128 (data, &bytes_read, 1));
+ dwarf_vmatoa ("d", (dwarf_signed_vma)
+ read_leb128 (data, &bytes_read, 1)));
data += bytes_read;
break;
case DW_OP_regx:
uvalue = read_leb128 (data, &bytes_read, 0);
data += bytes_read;
- printf ("DW_OP_regx: %lu (%s)", uvalue, regname (uvalue, 1));
+ printf ("DW_OP_regx: %s (%s)",
+ dwarf_vmatoa ("u", uvalue), regname (uvalue, 1));
break;
case DW_OP_fbreg:
need_frame_base = 1;
- printf ("DW_OP_fbreg: %ld", read_leb128 (data, &bytes_read, 1));
+ printf ("DW_OP_fbreg: %s",
+ dwarf_vmatoa ("d", read_sleb128 (data, &bytes_read)));
data += bytes_read;
break;
case DW_OP_bregx:
uvalue = read_leb128 (data, &bytes_read, 0);
data += bytes_read;
- printf ("DW_OP_bregx: %lu (%s) %ld", uvalue, regname (uvalue, 1),
- read_leb128 (data, &bytes_read, 1));
+ printf ("DW_OP_bregx: %s (%s) %s",
+ dwarf_vmatoa ("u", uvalue), regname (uvalue, 1),
+ dwarf_vmatoa ("d", read_sleb128 (data, &bytes_read)));
data += bytes_read;
break;
case DW_OP_piece:
- printf ("DW_OP_piece: %lu", read_leb128 (data, &bytes_read, 0));
+ printf ("DW_OP_piece: %s",
+ dwarf_vmatoa ("u", read_leb128 (data, &bytes_read, 0)));
data += bytes_read;
break;
case DW_OP_deref_size:
case DW_OP_call2:
/* XXX: Strictly speaking for 64-bit DWARF3 files
this ought to be an 8-byte wide computation. */
- printf ("DW_OP_call2: <0x%lx>", (long) byte_get (data, 2) + cu_offset);
+ printf ("DW_OP_call2: <0x%s>",
+ dwarf_vmatoa ("x", (dwarf_signed_vma) byte_get (data, 2)
+ + cu_offset));
data += 2;
break;
case DW_OP_call4:
/* XXX: Strictly speaking for 64-bit DWARF3 files
this ought to be an 8-byte wide computation. */
- printf ("DW_OP_call4: <0x%lx>", (long) byte_get (data, 4) + cu_offset);
+ printf ("DW_OP_call4: <0x%s>",
+ dwarf_vmatoa ("x", (dwarf_signed_vma) byte_get (data, 4)
+ + cu_offset));
data += 4;
break;
case DW_OP_call_ref:
}
if (dwarf_version == 2)
{
- printf ("DW_OP_call_ref: <0x%lx>",
- (long) byte_get (data, pointer_size));
+ printf ("DW_OP_call_ref: <0x%s>",
+ dwarf_vmatoa ("x", byte_get (data, pointer_size)));
data += pointer_size;
}
else
{
- printf ("DW_OP_call_ref: <0x%lx>",
- (long) byte_get (data, offset_size));
+ printf ("DW_OP_call_ref: <0x%s>",
+ dwarf_vmatoa ("x", byte_get (data, offset_size)));
data += offset_size;
}
break;
break;
case DW_OP_bit_piece:
printf ("DW_OP_bit_piece: ");
- printf ("size: %lu ", read_leb128 (data, &bytes_read, 0));
+ printf ("size: %s ",
+ dwarf_vmatoa ("u", read_leb128 (data, &bytes_read, 0)));
data += bytes_read;
- printf ("offset: %lu ", read_leb128 (data, &bytes_read, 0));
+ printf ("offset: %s ",
+ dwarf_vmatoa ("u", read_leb128 (data, &bytes_read, 0)));
data += bytes_read;
break;
{
int encoding;
dwarf_vma addr;
-
+
encoding = *data++;
addr = get_encoded_value (data, encoding, section);
data += size_of_encoded_value (encoding);
}
if (dwarf_version == 2)
{
- printf ("DW_OP_GNU_implicit_pointer: <0x%lx> %ld",
- (long) byte_get (data, pointer_size),
- read_leb128 (data + pointer_size, &bytes_read, 1));
+ 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)));
data += pointer_size + bytes_read;
}
else
{
- printf ("DW_OP_GNU_implicit_pointer: <0x%lx> %ld",
- (long) byte_get (data, offset_size),
- read_leb128 (data + offset_size, &bytes_read, 1));
+ 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)));
data += offset_size + bytes_read;
}
break;
+ case DW_OP_GNU_entry_value:
+ uvalue = read_leb128 (data, &bytes_read, 0);
+ data += bytes_read;
+ printf ("DW_OP_GNU_entry_value: (");
+ if (decode_location_expression (data, pointer_size, offset_size,
+ dwarf_version, uvalue,
+ cu_offset, section))
+ need_frame_base = 1;
+ putchar (')');
+ data += uvalue;
+ break;
+ case DW_OP_GNU_const_type:
+ uvalue = read_leb128 (data, &bytes_read, 0);
+ 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);
+ data += uvalue;
+ break;
+ case DW_OP_GNU_regval_type:
+ uvalue = read_leb128 (data, &bytes_read, 0);
+ data += bytes_read;
+ printf ("DW_OP_GNU_regval_type: %s (%s)",
+ dwarf_vmatoa ("u", uvalue), regname (uvalue, 1));
+ uvalue = read_leb128 (data, &bytes_read, 0);
+ data += bytes_read;
+ 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));
+ uvalue = read_leb128 (data, &bytes_read, 0);
+ data += bytes_read;
+ printf (" <0x%s>", dwarf_vmatoa ("x", cu_offset + uvalue));
+ break;
+ case DW_OP_GNU_convert:
+ uvalue = read_leb128 (data, &bytes_read, 0);
+ data += bytes_read;
+ printf ("DW_OP_GNU_convert <0x%s>",
+ dwarf_vmatoa ("x", uvalue ? cu_offset + uvalue : 0));
+ break;
+ case DW_OP_GNU_reinterpret:
+ uvalue = read_leb128 (data, &bytes_read, 0);
+ data += bytes_read;
+ printf ("DW_OP_GNU_reinterpret <0x%s>",
+ dwarf_vmatoa ("x", uvalue ? cu_offset + uvalue : 0));
+ break;
+ case DW_OP_GNU_parameter_ref:
+ printf ("DW_OP_GNU_parameter_ref: <0x%s>",
+ dwarf_vmatoa ("x", cu_offset + byte_get (data, 4)));
+ data += 4;
+ break;
/* HP extensions. */
case DW_OP_HP_is_value:
read_and_display_attr_value (unsigned long attribute,
unsigned long form,
unsigned char * data,
- unsigned long cu_offset,
- unsigned long pointer_size,
- unsigned long offset_size,
+ dwarf_vma cu_offset,
+ dwarf_vma pointer_size,
+ dwarf_vma offset_size,
int dwarf_version,
debug_info * debug_info_p,
int do_loc,
struct dwarf_section * section)
{
- unsigned long uvalue = 0;
+ dwarf_vma uvalue = 0;
unsigned char *block_start = NULL;
unsigned char * orig_data = data;
unsigned int bytes_read;
data += offset_size;
}
else
- {
- error (_("Internal error: DWARF version is not 2, 3 or 4.\n"));
- }
+ error (_("Internal error: DWARF version is not 2, 3 or 4.\n"));
+
break;
case DW_FORM_addr:
{
case DW_FORM_ref_addr:
if (!do_loc)
- printf (" <0x%lx>", uvalue);
+ printf (" <0x%s>", dwarf_vmatoa ("x",uvalue));
break;
case DW_FORM_ref1:
case DW_FORM_ref4:
case DW_FORM_ref_udata:
if (!do_loc)
- printf (" <0x%lx>", uvalue + cu_offset);
+ printf (" <0x%s>", dwarf_vmatoa ("x", uvalue + cu_offset));
break;
case DW_FORM_data4:
case DW_FORM_addr:
case DW_FORM_sec_offset:
if (!do_loc)
- printf (" 0x%lx", uvalue);
+ printf (" 0x%s", dwarf_vmatoa ("x", uvalue));
break;
case DW_FORM_flag_present:
case DW_FORM_sdata:
case DW_FORM_udata:
if (!do_loc)
- printf (" %ld", uvalue);
+ printf (" %s", dwarf_vmatoa ("d", uvalue));
break;
case DW_FORM_ref8:
if (!do_loc)
{
uvalue = byte_get (data, 4);
- printf (" 0x%lx", uvalue);
+ printf (" 0x%s", dwarf_vmatoa ("x", uvalue));
printf (" 0x%lx", (unsigned long) byte_get (data + 4, 4));
}
if ((do_loc || do_debug_loc || do_debug_ranges)
if (sizeof (uvalue) == 8)
uvalue = byte_get (data, 8);
else
- error (_("DW_FORM_data8 is unsupported when sizeof (unsigned long) != 8\n"));
+ error (_("DW_FORM_data8 is unsupported when sizeof (dwarf_vma) != 8\n"));
}
data += 8;
break;
case DW_FORM_strp:
if (!do_loc)
- printf (_(" (indirect string, offset: 0x%lx): %s"),
- uvalue, fetch_indirect_string (uvalue));
+ printf (_(" (indirect string, offset: 0x%s): %s"),
+ dwarf_vmatoa ("x", uvalue),
+ fetch_indirect_string (uvalue));
break;
case DW_FORM_indirect:
}
if ((do_loc || do_debug_loc || do_debug_ranges)
- && num_debug_info_entries == 0)
+ && num_debug_info_entries == 0
+ && debug_info_p != NULL)
{
switch (attribute)
{
case DW_AT_segment:
case DW_AT_static_link:
case DW_AT_use_location:
- if (form == DW_FORM_data4
- || form == DW_FORM_data8
+ case DW_AT_GNU_call_site_value:
+ case DW_AT_GNU_call_site_data_value:
+ case DW_AT_GNU_call_site_target:
+ case DW_AT_GNU_call_site_target_clobbered:
+ if ((dwarf_version < 4
+ && (form == DW_FORM_data4 || form == DW_FORM_data8))
|| form == DW_FORM_sec_offset)
{
/* Process location list. */
if (lmax == 0 || num >= lmax)
{
lmax += 1024;
- debug_info_p->loc_offsets = (long unsigned int *)
+ debug_info_p->loc_offsets = (dwarf_vma *)
xcrealloc (debug_info_p->loc_offsets,
lmax, sizeof (*debug_info_p->loc_offsets));
debug_info_p->have_frame_base = (int *)
break;
case DW_AT_ranges:
- if (form == DW_FORM_data4
- || form == DW_FORM_data8
+ if ((dwarf_version < 4
+ && (form == DW_FORM_data4 || form == DW_FORM_data8))
|| form == DW_FORM_sec_offset)
{
/* Process range list. */
if (lmax == 0 || num >= lmax)
{
lmax += 1024;
- debug_info_p->range_lists = (long unsigned int *)
+ debug_info_p->range_lists = (dwarf_vma *)
xcrealloc (debug_info_p->range_lists,
lmax, sizeof (*debug_info_p->range_lists));
debug_info_p->max_range_lists = lmax;
}
}
- if (do_loc)
+ if (do_loc || attribute == 0)
return data;
/* For some attributes we can display further information. */
printf (_("(declared as inline and inlined)"));
break;
default:
- printf (_(" (Unknown inline attribute value: %lx)"), uvalue);
+ printf (_(" (Unknown inline attribute value: %s)"),
+ dwarf_vmatoa ("x", uvalue));
break;
}
break;
case DW_LANG_Upc: printf ("(Unified Parallel C)"); break;
default:
if (uvalue >= DW_LANG_lo_user && uvalue <= DW_LANG_hi_user)
- printf ("(implementation defined: %lx)", uvalue);
+ printf ("(implementation defined: %s)",
+ dwarf_vmatoa ("x", uvalue));
else
- printf ("(Unknown: %lx)", uvalue);
+ printf ("(Unknown: %s)", dwarf_vmatoa ("x", uvalue));
break;
}
break;
case DW_AT_segment:
case DW_AT_static_link:
case DW_AT_use_location:
- if (form == DW_FORM_data4
- || form == DW_FORM_data8
+ case DW_AT_GNU_call_site_value:
+ case DW_AT_GNU_call_site_data_value:
+ case DW_AT_GNU_call_site_target:
+ case DW_AT_GNU_call_site_target_clobbered:
+ if ((dwarf_version < 4
+ && (form == DW_FORM_data4 || form == DW_FORM_data8))
|| form == DW_FORM_sec_offset)
printf (_("(location list)"));
/* Fall through. */
uvalue += cu_offset;
if (uvalue >= section->size)
- warn (_("Offset %lx used as value for DW_AT_import attribute of DIE at offset %lx is too big.\n"),
- uvalue, (unsigned long) (orig_data - section->start));
+ warn (_("Offset %s used as value for DW_AT_import attribute of DIE at offset %lx is too big.\n"),
+ dwarf_vmatoa ("x", uvalue),
+ (unsigned long) (orig_data - section->start));
else
{
unsigned long abbrev_number;
case DW_AT_GNU_odr_signature: return "DW_AT_GNU_odr_signature";
case DW_AT_use_GNAT_descriptive_type: return "DW_AT_use_GNAT_descriptive_type";
case DW_AT_GNAT_descriptive_type: return "DW_AT_GNAT_descriptive_type";
+ case DW_AT_GNU_call_site_value: return "DW_AT_GNU_call_site_value";
+ case DW_AT_GNU_call_site_data_value: return "DW_AT_GNU_call_site_data_value";
+ case DW_AT_GNU_call_site_target: return "DW_AT_GNU_call_site_target";
+ case DW_AT_GNU_call_site_target_clobbered: return "DW_AT_GNU_call_site_target_clobbered";
+ case DW_AT_GNU_tail_call: return "DW_AT_GNU_tail_call";
+ case DW_AT_GNU_all_tail_call_sites: return "DW_AT_GNU_all_tail_call_sites";
+ case DW_AT_GNU_all_call_sites: return "DW_AT_GNU_all_call_sites";
+ case DW_AT_GNU_all_source_call_sites: return "DW_AT_GNU_all_source_call_sites";
+ case DW_AT_GNU_macros: return "DW_AT_GNU_macros";
/* UPC extension. */
case DW_AT_upc_threads_scaled: return "DW_AT_upc_threads_scaled";
read_and_display_attr (unsigned long attribute,
unsigned long form,
unsigned char * data,
- unsigned long cu_offset,
- unsigned long pointer_size,
- unsigned long offset_size,
+ dwarf_vma cu_offset,
+ dwarf_vma pointer_size,
+ dwarf_vma offset_size,
int dwarf_version,
debug_info * debug_info_p,
int do_loc,
&& num_debug_info_entries == 0
&& ! do_types)
{
- unsigned long length;
+ dwarf_vma length;
/* First scan the section to get the number of comp units. */
for (section_begin = start, num_units = 0; section_begin < end;
}
else if (length >= 0xfffffff0 && length < 0xffffffff)
{
- warn (_("Reserved length value (%lx) found in section %s\n"), length, section->name);
+ warn (_("Reserved length value (0x%s) found in section %s\n"),
+ dwarf_vmatoa ("x", length), section->name);
return 0;
}
else
relocations to an object file. */
if ((signed long) length <= 0)
{
- warn (_("Corrupt unit length (%lx) found in section %s\n"), length, section->name);
+ warn (_("Corrupt unit length (0x%s) found in section %s\n"),
+ dwarf_vmatoa ("x", length), section->name);
return 0;
}
}
if (!do_loc)
{
- printf (_("Contents of the %s section:\n\n"), section->name);
+ if (dwarf_start_die == 0)
+ printf (_("Contents of the %s section:\n\n"), section->name);
load_debug_section (str, file);
}
DWARF2_Internal_CompUnit compunit;
unsigned char *hdrptr;
unsigned char *tags;
- int level;
- unsigned long cu_offset;
+ int level, last_level, saved_level;
+ dwarf_vma cu_offset;
int offset_size;
int initial_length_size;
unsigned char signature[8] = { 0 };
- unsigned long type_offset = 0;
+ dwarf_vma type_offset = 0;
hdrptr = start;
debug_information [unit].num_range_lists = 0;
}
- if (!do_loc)
+ if (!do_loc && dwarf_start_die == 0)
{
- printf (_(" Compilation Unit @ offset 0x%lx:\n"), cu_offset);
- printf (_(" Length: 0x%lx (%s)\n"), compunit.cu_length,
- initial_length_size == 8 ? "64-bit" : "32-bit");
+ printf (_(" Compilation Unit @ offset 0x%s:\n"),
+ dwarf_vmatoa ("x", cu_offset));
+ printf (_(" Length: 0x%s (%s)\n"),
+ dwarf_vmatoa ("x", compunit.cu_length),
+ offset_size == 8 ? "64-bit" : "32-bit");
printf (_(" Version: %d\n"), compunit.cu_version);
- printf (_(" Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset);
+ printf (_(" Abbrev Offset: %s\n"),
+ dwarf_vmatoa ("d", compunit.cu_abbrev_offset));
printf (_(" Pointer Size: %d\n"), compunit.cu_pointer_size);
if (do_types)
{
for (i = 0; i < 8; i++)
printf ("%02x", signature[i]);
printf ("\n");
- printf (_(" Type Offset: 0x%lx\n"), type_offset);
+ printf (_(" Type Offset: 0x%s\n"),
+ dwarf_vmatoa ("x", type_offset));
}
}
if (cu_offset + compunit.cu_length + initial_length_size
> section->size)
{
- warn (_("Debug info is corrupted, length of CU at %lx extends beyond end of section (length = %lx)\n"),
- cu_offset, compunit.cu_length);
+ warn (_("Debug info is corrupted, length of CU at %s"
+ " extends beyond end of section (length = %s)\n"),
+ dwarf_vmatoa ("x", cu_offset),
+ dwarf_vmatoa ("x", compunit.cu_length));
break;
}
tags = hdrptr;
&& compunit.cu_version != 3
&& compunit.cu_version != 4)
{
- warn (_("CU at offset %lx contains corrupt or unsupported version number: %d.\n"),
- cu_offset, compunit.cu_version);
+ warn (_("CU at offset %s contains corrupt or "
+ "unsupported version number: %d.\n"),
+ dwarf_vmatoa ("x", cu_offset), compunit.cu_version);
continue;
}
+ debug_displays [abbrev_sec].section.size);
level = 0;
+ last_level = level;
+ saved_level = -1;
while (tags < start)
{
unsigned int bytes_read;
unsigned long die_offset;
abbrev_entry *entry;
abbrev_attr *attr;
+ int do_printing = 1;
die_offset = tags - section_begin;
warn (_("Further warnings about bogus end-of-sibling markers suppressed\n"));
}
}
+ if (dwarf_start_die != 0 && level < saved_level)
+ return 1;
continue;
}
if (!do_loc)
- printf (_(" <%d><%lx>: Abbrev Number: %lu"),
- level, die_offset, abbrev_number);
+ {
+ if (dwarf_start_die != 0 && die_offset < dwarf_start_die)
+ do_printing = 0;
+ else
+ {
+ if (dwarf_start_die != 0 && die_offset == dwarf_start_die)
+ saved_level = level;
+ do_printing = (dwarf_cutoff_level == -1
+ || level < dwarf_cutoff_level);
+ if (do_printing)
+ printf (_(" <%d><%lx>: Abbrev Number: %lu"),
+ level, die_offset, abbrev_number);
+ else if (dwarf_cutoff_level == -1
+ || last_level < dwarf_cutoff_level)
+ printf (_(" <%d><%lx>: ...\n"), level, die_offset);
+ last_level = level;
+ }
+ }
/* Scan through the abbreviation list until we reach the
correct entry. */
if (entry == NULL)
{
- if (!do_loc)
+ if (!do_loc && do_printing)
{
printf ("\n");
fflush (stdout);
return 0;
}
- if (!do_loc)
+ if (!do_loc && do_printing)
printf (" (%s)\n", get_TAG_name (entry->tag));
switch (entry->tag)
for (attr = entry->first_attr; attr; attr = attr->next)
{
- if (! do_loc)
+ debug_info *arg;
+
+ if (! do_loc && do_printing)
/* Show the offset from where the tag was extracted. */
- printf (" <%2lx>", (unsigned long)(tags - section_begin));
+ printf (" <%lx>", (unsigned long)(tags - section_begin));
+
+ arg = debug_information;
+ if (debug_information)
+ arg += unit;
tags = read_and_display_attr (attr->attribute,
attr->form,
compunit.cu_pointer_size,
offset_size,
compunit.cu_version,
- debug_information + unit,
- do_loc, section);
+ arg,
+ do_loc || ! do_printing, section);
}
if (entry->children)
num_debug_info_entries = num_units;
if (!do_loc)
- {
- printf ("\n");
- }
+ printf ("\n");
return 1;
}
linfo.li_line_base >>= 24;
printf (_(" Offset: 0x%lx\n"), hdroff);
- printf (_(" Length: %ld\n"), linfo.li_length);
+ printf (_(" Length: %ld\n"), (long) linfo.li_length);
printf (_(" DWARF Version: %d\n"), linfo.li_version);
printf (_(" Prologue Length: %d\n"), linfo.li_prologue_length);
printf (_(" Minimum Instruction Length: %d\n"), linfo.li_min_insn_length);
data += strlen ((char *) data) + 1;
- printf ("%lu\t", read_leb128 (data, & bytes_read, 0));
+ printf ("%s\t",
+ dwarf_vmatoa ("u", read_leb128 (data, & bytes_read, 0)));
data += bytes_read;
- printf ("%lu\t", read_leb128 (data, & bytes_read, 0));
+ printf ("%s\t",
+ dwarf_vmatoa ("u", read_leb128 (data, & bytes_read, 0)));
data += bytes_read;
- printf ("%lu\t", read_leb128 (data, & bytes_read, 0));
+ printf ("%s\t",
+ dwarf_vmatoa ("u", read_leb128 (data, & bytes_read, 0)));
data += bytes_read;
printf ("%s\n", name);
}
while (data < end_of_sequence)
{
unsigned char op_code;
- int adv;
- unsigned long int uladv;
+ dwarf_signed_vma adv;
+ dwarf_vma uladv;
unsigned int bytes_read;
op_code = *data++;
{
uladv *= linfo.li_min_insn_length;
state_machine_regs.address += uladv;
- printf (_(" Special opcode %d: advance Address by %lu to 0x%lx"),
- op_code, uladv, state_machine_regs.address);
+ printf (_(" Special opcode %d: "
+ "advance Address by %s to 0x%s"),
+ op_code, dwarf_vmatoa ("u", uladv),
+ dwarf_vmatoa ("x", state_machine_regs.address));
}
else
{
state_machine_regs.op_index
= (state_machine_regs.op_index + uladv)
% linfo.li_max_ops_per_insn;
- printf (_(" Special opcode %d: advance Address by %lu to 0x%lx[%d]"),
- op_code, uladv, state_machine_regs.address,
+ printf (_(" Special opcode %d: "
+ "advance Address by %s to 0x%s[%d]"),
+ op_code, dwarf_vmatoa ("u", uladv),
+ dwarf_vmatoa ("x", state_machine_regs.address),
state_machine_regs.op_index);
}
adv = (op_code % linfo.li_line_range) + linfo.li_line_base;
state_machine_regs.line += adv;
- printf (_(" and Line by %d to %d\n"),
- adv, state_machine_regs.line);
+ printf (_(" and Line by %s to %d\n"),
+ dwarf_vmatoa ("d", adv), state_machine_regs.line);
}
else switch (op_code)
{
{
uladv *= linfo.li_min_insn_length;
state_machine_regs.address += uladv;
- printf (_(" Advance PC by %lu to 0x%lx\n"), uladv,
- state_machine_regs.address);
+ printf (_(" Advance PC by %s to 0x%s\n"),
+ dwarf_vmatoa ("u", uladv),
+ dwarf_vmatoa ("x", state_machine_regs.address));
}
else
{
state_machine_regs.op_index
= (state_machine_regs.op_index + uladv)
% linfo.li_max_ops_per_insn;
- printf (_(" Advance PC by %lu to 0x%lx[%d]\n"), uladv,
- state_machine_regs.address,
+ printf (_(" Advance PC by %s to 0x%s[%d]\n"),
+ dwarf_vmatoa ("u", uladv),
+ dwarf_vmatoa ("x", state_machine_regs.address),
state_machine_regs.op_index);
}
break;
case DW_LNS_advance_line:
- adv = read_leb128 (data, & bytes_read, 1);
+ adv = read_sleb128 (data, & bytes_read);
data += bytes_read;
state_machine_regs.line += adv;
- printf (_(" Advance Line by %d to %d\n"), adv,
- state_machine_regs.line);
+ printf (_(" Advance Line by %s to %d\n"),
+ dwarf_vmatoa ("d", adv),
+ state_machine_regs.line);
break;
case DW_LNS_set_file:
adv = read_leb128 (data, & bytes_read, 0);
data += bytes_read;
- printf (_(" Set File Name to entry %d in the File Name Table\n"),
- adv);
+ printf (_(" Set File Name to entry %s in the File Name Table\n"),
+ dwarf_vmatoa ("d", adv));
state_machine_regs.file = adv;
break;
case DW_LNS_set_column:
uladv = read_leb128 (data, & bytes_read, 0);
data += bytes_read;
- printf (_(" Set column to %lu\n"), uladv);
+ printf (_(" Set column to %s\n"),
+ dwarf_vmatoa ("u", uladv));
state_machine_regs.column = uladv;
break;
case DW_LNS_negate_stmt:
adv = state_machine_regs.is_stmt;
adv = ! adv;
- printf (_(" Set is_stmt to %d\n"), adv);
+ printf (_(" Set is_stmt to %s\n"), dwarf_vmatoa ("d", adv));
state_machine_regs.is_stmt = adv;
break;
{
uladv *= linfo.li_min_insn_length;
state_machine_regs.address += uladv;
- printf (_(" Advance PC by constant %lu to 0x%lx\n"), uladv,
- state_machine_regs.address);
+ printf (_(" Advance PC by constant %s to 0x%s\n"),
+ dwarf_vmatoa ("u", uladv),
+ dwarf_vmatoa ("x", state_machine_regs.address));
}
else
{
state_machine_regs.op_index
= (state_machine_regs.op_index + uladv)
% linfo.li_max_ops_per_insn;
- printf (_(" Advance PC by constant %lu to 0x%lx[%d]\n"),
- uladv, state_machine_regs.address,
+ printf (_(" Advance PC by constant %s to 0x%s[%d]\n"),
+ dwarf_vmatoa ("u", uladv),
+ dwarf_vmatoa ("x", state_machine_regs.address),
state_machine_regs.op_index);
}
break;
data += 2;
state_machine_regs.address += uladv;
state_machine_regs.op_index = 0;
- printf (_(" Advance PC by fixed size amount %lu to 0x%lx\n"),
- uladv, state_machine_regs.address);
+ printf (_(" Advance PC by fixed size amount %s to 0x%s\n"),
+ dwarf_vmatoa ("u", uladv),
+ dwarf_vmatoa ("x", state_machine_regs.address));
break;
case DW_LNS_set_prologue_end:
case DW_LNS_set_isa:
uladv = read_leb128 (data, & bytes_read, 0);
data += bytes_read;
- printf (_(" Set ISA to %lu\n"), uladv);
+ printf (_(" Set ISA to %s\n"), dwarf_vmatoa ("u", uladv));
break;
default:
for (i = standard_opcodes[op_code - 1]; i > 0 ; --i)
{
- printf ("0x%lx%s", read_leb128 (data, &bytes_read, 0),
+ printf ("0x%s%s", dwarf_vmatoa ("x", read_leb128 (data,
+ &bytes_read, 0)),
i == 1 ? "" : ", ");
data += bytes_read;
}
typedef struct
{
- unsigned char *name;
- unsigned int directory_index;
- unsigned int modification_date;
- unsigned int length;
+ unsigned char *name;
+ unsigned int directory_index;
+ unsigned int modification_date;
+ unsigned int length;
} File_Entry;
/* Output a decoded representation of the .debug_line section. */
break;
case DW_LNS_advance_line:
- adv = read_leb128 (data, & bytes_read, 1);
+ adv = read_sleb128 (data, & bytes_read);
data += bytes_read;
state_machine_regs.line += adv;
break;
for (i = standard_opcodes[op_code - 1]; i > 0 ; --i)
{
- printf ("0x%lx%s", read_leb128 (data, &bytes_read, 0),
+ printf ("0x%s%s", dwarf_vmatoa ("x", read_leb128 (data,
+ &bytes_read, 0)),
i == 1 ? "" : ", ");
data += bytes_read;
}
if (!do_wide || (fileNameLength <= MAX_FILENAME_LENGTH))
{
if (linfo.li_max_ops_per_insn == 1)
- printf ("%-35s %11d %#18lx\n", newFileName,
- state_machine_regs.line,
+ printf ("%-35s %11d %#18" DWARF_VMA_FMT "x\n",
+ newFileName, state_machine_regs.line,
state_machine_regs.address);
else
- printf ("%-35s %11d %#18lx[%d]\n", newFileName,
- state_machine_regs.line,
+ printf ("%-35s %11d %#18" DWARF_VMA_FMT "x[%d]\n",
+ newFileName, state_machine_regs.line,
state_machine_regs.address,
state_machine_regs.op_index);
}
else
{
if (linfo.li_max_ops_per_insn == 1)
- printf ("%s %11d %#18lx\n", newFileName,
- state_machine_regs.line,
+ printf ("%s %11d %#18" DWARF_VMA_FMT "x\n",
+ newFileName, state_machine_regs.line,
state_machine_regs.address);
else
- printf ("%s %11d %#18lx[%d]\n", newFileName,
- state_machine_regs.line,
+ printf ("%s %11d %#18" DWARF_VMA_FMT "x[%d]\n",
+ newFileName, state_machine_regs.line,
state_machine_regs.address,
state_machine_regs.op_index);
}
&& num_debug_info_entries > 0
&& find_debug_info_for_offset (names.pn_offset) == NULL)
warn (_(".debug_info offset of 0x%lx in %s section does not point to a CU header.\n"),
- names.pn_offset, section->name);
+ (unsigned long) names.pn_offset, section->name);
names.pn_size = byte_get (data, offset_size);
data += offset_size;
}
printf (_(" Length: %ld\n"),
- names.pn_length);
+ (long) names.pn_length);
printf (_(" Version: %d\n"),
names.pn_version);
printf (_(" Offset into .debug_info section: 0x%lx\n"),
- names.pn_offset);
+ (unsigned long) names.pn_offset);
printf (_(" Size of area in .debug_info section: %ld\n"),
- names.pn_size);
+ (long) names.pn_size);
printf (_("\n Offset\tName\n"));
return 1;
}
+/* Given LINE_OFFSET into the .debug_line section, attempt to return
+ filename and dirname corresponding to file name table entry with index
+ FILEIDX. Return NULL on failure. */
+
+static unsigned char *
+get_line_filename_and_dirname (dwarf_vma line_offset, dwarf_vma fileidx,
+ unsigned char **dir_name)
+{
+ struct dwarf_section *section = &debug_displays [line].section;
+ unsigned char *hdrptr, *dirtable, *file_name;
+ unsigned int offset_size, initial_length_size;
+ unsigned int version, opcode_base, bytes_read;
+ dwarf_vma length, diridx;
+
+ *dir_name = NULL;
+ if (section->start == NULL
+ || line_offset >= section->size
+ || fileidx == 0)
+ return NULL;
+
+ hdrptr = section->start + line_offset;
+ length = byte_get (hdrptr, 4);
+ hdrptr += 4;
+ if (length == 0xffffffff)
+ {
+ /* This section is 64-bit DWARF 3. */
+ length = byte_get (hdrptr, 8);
+ hdrptr += 8;
+ offset_size = 8;
+ initial_length_size = 12;
+ }
+ else
+ {
+ offset_size = 4;
+ initial_length_size = 4;
+ }
+ if (length + initial_length_size > section->size)
+ return NULL;
+ version = byte_get (hdrptr, 2);
+ hdrptr += 2;
+ 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);
+ 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++; /* 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;
+ read_leb128 (hdrptr, &bytes_read, 0);
+ hdrptr += bytes_read;
+ read_leb128 (hdrptr, &bytes_read, 0);
+ hdrptr += bytes_read;
+ read_leb128 (hdrptr, &bytes_read, 0);
+ hdrptr += bytes_read;
+ }
+ if (*hdrptr == '\0')
+ return NULL;
+ file_name = hdrptr;
+ hdrptr += strlen ((char *) hdrptr) + 1;
+ diridx = read_leb128 (hdrptr, &bytes_read, 0);
+ if (diridx == 0)
+ return file_name;
+ for (; *dirtable != '\0' && diridx > 1; diridx--)
+ dirtable += strlen ((char *) dirtable) + 1;
+ if (*dirtable == '\0')
+ return NULL;
+ *dir_name = dirtable;
+ return file_name;
+}
+
+static int
+display_debug_macro (struct dwarf_section *section,
+ void *file)
+{
+ unsigned char *start = section->start;
+ unsigned char *end = start + section->size;
+ unsigned char *curr = start;
+ unsigned char *extended_op_buf[256];
+ unsigned int bytes_read;
+
+ load_debug_section (str, file);
+ load_debug_section (line, file);
+
+ printf (_("Contents of the %s section:\n\n"), section->name);
+
+ while (curr < end)
+ {
+ unsigned int lineno, version, flags;
+ unsigned int offset_size = 4;
+ const char *string;
+ dwarf_vma line_offset = 0, sec_offset = curr - start, offset;
+ unsigned char **extended_ops = NULL;
+
+ version = byte_get (curr, 2);
+ curr += 2;
+
+ if (version != 4)
+ {
+ error (_("Only GNU extension to DWARF 4 of %s is currently supported.\n"),
+ section->name);
+ return 0;
+ }
+
+ flags = byte_get (curr++, 1);
+ if (flags & 1)
+ offset_size = 8;
+ printf (_(" Offset: 0x%lx\n"),
+ (unsigned long) sec_offset);
+ printf (_(" Version: %d\n"), version);
+ printf (_(" Offset size: %d\n"), offset_size);
+ if (flags & 2)
+ {
+ line_offset = byte_get (curr, offset_size);
+ curr += offset_size;
+ printf (_(" Offset into .debug_line: 0x%lx\n"),
+ (unsigned long) line_offset);
+ }
+ if (flags & 4)
+ {
+ unsigned int i, count = byte_get (curr++, 1), op;
+ dwarf_vma nargs, n;
+ 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);
+ extended_ops[op] = curr;
+ nargs = read_leb128 (curr, &bytes_read, 0);
+ curr += bytes_read;
+ if (nargs == 0)
+ printf (_(" DW_MACRO_GNU_%02x has no arguments\n"), op);
+ else
+ {
+ printf (_(" DW_MACRO_GNU_%02x arguments: "), op);
+ for (n = 0; n < nargs; n++)
+ {
+ unsigned int form = byte_get (curr++, 1);
+ printf ("%s%s", get_FORM_name (form),
+ n == nargs - 1 ? "\n" : ", ");
+ switch (form)
+ {
+ case DW_FORM_data1:
+ case DW_FORM_data2:
+ case DW_FORM_data4:
+ case DW_FORM_data8:
+ case DW_FORM_sdata:
+ case DW_FORM_udata:
+ case DW_FORM_block:
+ case DW_FORM_block1:
+ case DW_FORM_block2:
+ case DW_FORM_block4:
+ case DW_FORM_flag:
+ case DW_FORM_string:
+ case DW_FORM_strp:
+ case DW_FORM_sec_offset:
+ break;
+ default:
+ error (_("Invalid extension opcode form %s\n"),
+ get_FORM_name (form));
+ return 0;
+ }
+ }
+ }
+ }
+ }
+ }
+ printf ("\n");
+
+ while (1)
+ {
+ unsigned int op;
+
+ if (curr >= end)
+ {
+ error (_(".debug_macro section not zero terminated\n"));
+ return 0;
+ }
+
+ op = byte_get (curr++, 1);
+ if (op == 0)
+ break;
+
+ switch (op)
+ {
+ case DW_MACRO_GNU_start_file:
+ {
+ unsigned int filenum;
+ unsigned char *file_name = NULL, *dir_name = NULL;
+
+ lineno = read_leb128 (curr, &bytes_read, 0);
+ curr += bytes_read;
+ filenum = read_leb128 (curr, &bytes_read, 0);
+ curr += bytes_read;
+
+ if ((flags & 2) == 0)
+ error (_("DW_MACRO_GNU_start_file used, but no .debug_line offset provided.\n"));
+ else
+ file_name
+ = get_line_filename_and_dirname (line_offset, filenum,
+ &dir_name);
+ if (file_name == NULL)
+ printf (_(" DW_MACRO_GNU_start_file - lineno: %d filenum: %d\n"),
+ lineno, filenum);
+ else
+ printf (_(" DW_MACRO_GNU_start_file - lineno: %d filenum: %d filename: %s%s%s\n"),
+ lineno, filenum,
+ dir_name != NULL ? (const char *) dir_name : "",
+ dir_name != NULL ? "/" : "", file_name);
+ }
+ break;
+
+ case DW_MACRO_GNU_end_file:
+ printf (_(" DW_MACRO_GNU_end_file\n"));
+ break;
+
+ case DW_MACRO_GNU_define:
+ lineno = read_leb128 (curr, &bytes_read, 0);
+ curr += bytes_read;
+ string = (char *) curr;
+ curr += strlen (string) + 1;
+ printf (_(" DW_MACRO_GNU_define - lineno : %d macro : %s\n"),
+ lineno, string);
+ break;
+
+ case DW_MACRO_GNU_undef:
+ lineno = read_leb128 (curr, &bytes_read, 0);
+ curr += bytes_read;
+ string = (char *) curr;
+ curr += strlen (string) + 1;
+ printf (_(" DW_MACRO_GNU_undef - lineno : %d macro : %s\n"),
+ lineno, string);
+ break;
+
+ case DW_MACRO_GNU_define_indirect:
+ lineno = read_leb128 (curr, &bytes_read, 0);
+ curr += bytes_read;
+ offset = byte_get (curr, offset_size);
+ curr += offset_size;
+ string = fetch_indirect_string (offset);
+ printf (_(" DW_MACRO_GNU_define_indirect - lineno : %d macro : %s\n"),
+ lineno, string);
+ break;
+
+ case DW_MACRO_GNU_undef_indirect:
+ lineno = read_leb128 (curr, &bytes_read, 0);
+ curr += bytes_read;
+ offset = byte_get (curr, offset_size);
+ curr += offset_size;
+ 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;
+ printf (_(" DW_MACRO_GNU_transparent_include - offset : 0x%lx\n"),
+ (unsigned long) offset);
+ break;
+
+ default:
+ if (extended_ops == NULL || extended_ops[op] == NULL)
+ {
+ error (_(" Unknown macro opcode %02x seen\n"), op);
+ return 0;
+ }
+ else
+ {
+ /* Skip over unhandled opcodes. */
+ dwarf_vma nargs, n;
+ unsigned char *desc = extended_ops[op];
+ nargs = read_leb128 (desc, &bytes_read, 0);
+ desc += bytes_read;
+ if (nargs == 0)
+ {
+ printf (_(" DW_MACRO_GNU_%02x\n"), op);
+ break;
+ }
+ printf (_(" DW_MACRO_GNU_%02x -"), op);
+ for (n = 0; n < nargs; n++)
+ {
+ curr
+ = read_and_display_attr_value (0, byte_get (desc++, 1),
+ curr, 0, 0, offset_size,
+ version, NULL, 0, NULL);
+ if (n != nargs - 1)
+ printf (",");
+ }
+ printf ("\n");
+ }
+ break;
+ }
+ }
+
+ printf ("\n");
+ }
+
+ return 1;
+}
+
static int
display_debug_abbrev (struct dwarf_section *section,
void *file ATTRIBUTE_UNUSED)
return 1;
}
+/* Sort array of indexes in ascending order of loc_offsets[idx]. */
+
+static dwarf_vma *loc_offsets;
+
+static int
+loc_offsets_compar (const void *ap, const void *bp)
+{
+ dwarf_vma a = loc_offsets[*(const unsigned int *) ap];
+ dwarf_vma b = loc_offsets[*(const unsigned int *) bp];
+
+ return (a > b) - (b > a);
+}
+
static int
display_debug_loc (struct dwarf_section *section, void *file)
{
unsigned int first = 0;
unsigned int i;
unsigned int j;
+ unsigned int k;
int seen_first_offset = 0;
- int use_debug_info = 1;
+ int locs_sorted = 1;
unsigned char *next;
+ unsigned int *array = NULL;
bytes = section->size;
section_end = start + bytes;
unsigned int num;
num = debug_information [i].num_loc_offsets;
- num_loc_list += num;
+ if (num > num_loc_list)
+ num_loc_list = num;
/* Check if we can use `debug_information' directly. */
- if (use_debug_info && num != 0)
+ if (locs_sorted && num != 0)
{
if (!seen_first_offset)
{
if (last_offset >
debug_information [i].loc_offsets [j])
{
- use_debug_info = 0;
+ locs_sorted = 0;
break;
}
last_offset = debug_information [i].loc_offsets [j];
}
}
- if (!use_debug_info)
- /* FIXME: Should we handle this case? */
- error (_("Location lists in .debug_info section aren't in ascending order!\n"));
-
if (!seen_first_offset)
error (_("No location lists in .debug_info section!\n"));
/* DWARF sections under Mach-O have non-zero addresses. */
if (debug_information [first].num_loc_offsets > 0
&& debug_information [first].loc_offsets [0] != section->address)
- warn (_("Location lists in %s section start at 0x%lx\n"),
- section->name, debug_information [first].loc_offsets [0]);
+ warn (_("Location lists in %s section start at 0x%s\n"),
+ section->name,
+ dwarf_vmatoa ("x", debug_information [first].loc_offsets [0]));
+ if (!locs_sorted)
+ array = (unsigned int *) xcmalloc (num_loc_list, sizeof (unsigned int));
printf (_("Contents of the %s section:\n\n"), section->name);
printf (_(" Offset Begin End Expression\n"));
cu_offset = debug_information [i].cu_offset;
offset_size = debug_information [i].offset_size;
dwarf_version = debug_information [i].dwarf_version;
+ if (!locs_sorted)
+ {
+ for (k = 0; k < debug_information [i].num_loc_offsets; k++)
+ array[k] = k;
+ loc_offsets = debug_information [i].loc_offsets;
+ qsort (array, debug_information [i].num_loc_offsets,
+ sizeof (*array), loc_offsets_compar);
+ }
- for (j = 0; j < debug_information [i].num_loc_offsets; j++)
+ for (k = 0; k < debug_information [i].num_loc_offsets; k++)
{
+ j = locs_sorted ? k : array[k];
+ if (k
+ && debug_information [i].loc_offsets [locs_sorted
+ ? k - 1 : array [k - 1]]
+ == debug_information [i].loc_offsets [j])
+ continue;
has_frame_base = debug_information [i].have_frame_base [j];
/* DWARF sections under Mach-O have non-zero addresses. */
offset = debug_information [i].loc_offsets [j] - section->address;
warn (_("There are %ld unused bytes at the end of section %s\n"),
(long) (section_end - start), section->name);
putchar ('\n');
+ free (array);
return 1;
}
&& num_debug_info_entries > 0
&& find_debug_info_for_offset (arange.ar_info_offset) == NULL)
warn (_(".debug_info offset of 0x%lx in %s section does not point to a CU header.\n"),
- arange.ar_info_offset, section->name);
+ (unsigned long) arange.ar_info_offset, section->name);
arange.ar_pointer_size = byte_get (hdrptr, 1);
hdrptr += 1;
break;
}
- printf (_(" Length: %ld\n"), arange.ar_length);
+ printf (_(" Length: %ld\n"),
+ (long) arange.ar_length);
printf (_(" Version: %d\n"), arange.ar_version);
- printf (_(" Offset into .debug_info: 0x%lx\n"), arange.ar_info_offset);
+ printf (_(" Offset into .debug_info: 0x%lx\n"),
+ (unsigned long) arange.ar_info_offset);
printf (_(" Pointer Size: %d\n"), arange.ar_pointer_size);
printf (_(" Segment Size: %d\n"), arange.ar_segment_size);
sorting purposes. */
struct range_entry
- {
- /* The debug_information[x].range_lists[y] value. */
- unsigned long ranges_offset;
+{
+ /* The debug_information[x].range_lists[y] value. */
+ unsigned long ranges_offset;
- /* Original debug_information to find parameters of the data. */
- debug_info *debug_info_p;
- };
+ /* Original debug_information to find parameters of the data. */
+ debug_info *debug_info_p;
+};
/* Sort struct range_entry in ascending order of its RANGES_OFFSET. */
case EM_X86_64:
case EM_L1OM:
+ case EM_K1OM:
init_dwarf_regnames_x86_64 ();
break;
#define GET(N) byte_get (start, N); start += N
#define LEB() read_leb128 (start, & length_return, 0); start += length_return
-#define SLEB() read_leb128 (start, & length_return, 1); start += length_return
+#define SLEB() read_sleb128 (start, & length_return); start += length_return
static int
display_debug_frames (struct dwarf_section *section,
/* Prior versions are obsolete, and future versions may not be
backwards compatible. */
- if (version != 3)
+ switch (version)
{
+ case 3:
+ warn (_("The address table data in version 3 may be wrong.\n"));
+ break;
+ case 4:
+ warn (_("Version 4 does not support case insensitive lookups.\n"));
+ break;
+ case 5:
+ break;
+ default:
warn (_("Unsupported version %lu.\n"), (unsigned long) version);
return 0;
}
{
cu = byte_get_little_endian (constant_pool + cu_vector_offset + 4 + j * 4, 4);
/* Convert to TU number if it's for a type unit. */
- if (cu >= cu_list_elements)
- printf (" T%lu", (unsigned long) (cu - cu_list_elements));
+ if (cu >= cu_list_elements / 2)
+ printf (" T%lu", (unsigned long) (cu - cu_list_elements / 2));
else
printf (" %lu", (unsigned long) cu);
}
};
const char *p;
-
+
p = names;
while (*p)
{
const debug_dump_long_opts * entry;
-
+
for (entry = opts_table; entry->option; entry++)
{
size_t len = strlen (entry->option);
-
+
if (strncmp (p, entry->option, len) == 0
&& (p[len] == ',' || p[len] == '\0'))
{
* entry->variable |= entry->val;
-
+
/* The --debug-dump=frames-interp option also
enables the --debug-dump=frames option. */
if (do_debug_frames_interp)
break;
}
}
-
+
if (entry->option == NULL)
{
warn (_("Unrecognized debug option '%s'\n"), p);
if (p == NULL)
break;
}
-
+
if (*p == ',')
p++;
}
case 'i':
do_debug_info = 1;
break;
-
+
case 'a':
do_debug_abbrevs = 1;
break;
-
+
case 'l':
do_debug_lines |= FLAG_DEBUG_LINES_RAW;
break;
-
+
case 'L':
do_debug_lines |= FLAG_DEBUG_LINES_DECODED;
break;
-
+
case 'p':
do_debug_pubnames = 1;
break;
-
+
case 't':
do_debug_pubtypes = 1;
break;
-
+
case 'r':
do_debug_aranges = 1;
break;
-
+
case 'R':
do_debug_ranges = 1;
break;
-
+
case 'F':
do_debug_frames_interp = 1;
case 'f':
do_debug_frames = 1;
break;
-
+
case 'm':
do_debug_macinfo = 1;
break;
-
+
case 's':
do_debug_str = 1;
break;
-
+
case 'o':
do_debug_loc = 1;
break;
-
+
default:
warn (_("Unrecognized debug option '%s'\n"), optarg);
break;
display_debug_frames, &do_debug_frames, 1 },
{ { ".debug_macinfo", ".zdebug_macinfo", NULL, NULL, 0, 0 },
display_debug_macinfo, &do_debug_macinfo, 0 },
+ { { ".debug_macro", ".zdebug_macro", NULL, NULL, 0, 0 },
+ display_debug_macro, &do_debug_macinfo, 1 },
{ { ".debug_str", ".zdebug_str", NULL, NULL, 0, 0 },
display_debug_str, &do_debug_str, 0 },
{ { ".debug_loc", ".zdebug_loc", NULL, NULL, 0, 0 },