#include "sysdep.h"
#include "libiberty.h"
#include "bfd.h"
+#include "bfd_stdint.h"
#include "bucomm.h"
+#include "elfcomm.h"
#include "elf/common.h"
#include "dwarf2.h"
#include "dwarf.h"
int do_debug_macinfo;
int do_debug_str;
int do_debug_loc;
+int do_gdb_index;
int do_trace_info;
int do_trace_abbrevs;
int do_trace_aranges;
#define FLAG_DEBUG_LINES_RAW 1
#define FLAG_DEBUG_LINES_DECODED 2
-dwarf_vma (*byte_get) (unsigned char *, int);
-
-dwarf_vma
-byte_get_little_endian (unsigned char *field, int size)
-{
- switch (size)
- {
- case 1:
- return *field;
-
- case 2:
- return ((unsigned int) (field[0]))
- | (((unsigned int) (field[1])) << 8);
-
- case 3:
- return ((unsigned long) (field[0]))
- | (((unsigned long) (field[1])) << 8)
- | (((unsigned long) (field[2])) << 16);
-
- case 4:
- return ((unsigned long) (field[0]))
- | (((unsigned long) (field[1])) << 8)
- | (((unsigned long) (field[2])) << 16)
- | (((unsigned long) (field[3])) << 24);
-
- case 8:
- if (sizeof (dwarf_vma) == 8)
- return ((dwarf_vma) (field[0]))
- | (((dwarf_vma) (field[1])) << 8)
- | (((dwarf_vma) (field[2])) << 16)
- | (((dwarf_vma) (field[3])) << 24)
- | (((dwarf_vma) (field[4])) << 32)
- | (((dwarf_vma) (field[5])) << 40)
- | (((dwarf_vma) (field[6])) << 48)
- | (((dwarf_vma) (field[7])) << 56);
- else if (sizeof (dwarf_vma) == 4)
- /* We want to extract data from an 8 byte wide field and
- place it into a 4 byte wide field. Since this is a little
- endian source we can just use the 4 byte extraction code. */
- return ((unsigned long) (field[0]))
- | (((unsigned long) (field[1])) << 8)
- | (((unsigned long) (field[2])) << 16)
- | (((unsigned long) (field[3])) << 24);
-
- default:
- error (_("Unhandled data length: %d\n"), size);
- abort ();
- }
-}
-
-dwarf_vma
-byte_get_big_endian (unsigned char *field, int size)
-{
- switch (size)
- {
- case 1:
- return *field;
-
- case 2:
- return ((unsigned int) (field[1])) | (((int) (field[0])) << 8);
-
- case 3:
- return ((unsigned long) (field[2]))
- | (((unsigned long) (field[1])) << 8)
- | (((unsigned long) (field[0])) << 16);
-
- case 4:
- return ((unsigned long) (field[3]))
- | (((unsigned long) (field[2])) << 8)
- | (((unsigned long) (field[1])) << 16)
- | (((unsigned long) (field[0])) << 24);
-
- case 8:
- if (sizeof (dwarf_vma) == 8)
- return ((dwarf_vma) (field[7]))
- | (((dwarf_vma) (field[6])) << 8)
- | (((dwarf_vma) (field[5])) << 16)
- | (((dwarf_vma) (field[4])) << 24)
- | (((dwarf_vma) (field[3])) << 32)
- | (((dwarf_vma) (field[2])) << 40)
- | (((dwarf_vma) (field[1])) << 48)
- | (((dwarf_vma) (field[0])) << 56);
- else if (sizeof (dwarf_vma) == 4)
- {
- /* Although we are extracing data from an 8 byte wide field,
- we are returning only 4 bytes of data. */
- field += 4;
- return ((unsigned long) (field[3]))
- | (((unsigned long) (field[2])) << 8)
- | (((unsigned long) (field[1])) << 16)
- | (((unsigned long) (field[0])) << 24);
- }
-
- default:
- error (_("Unhandled data length: %d\n"), size);
- abort ();
- }
-}
-
-dwarf_vma
-byte_get_signed (unsigned char *field, int size)
-{
- dwarf_vma x = byte_get (field, size);
-
- switch (size)
- {
- case 1:
- return (x ^ 0x80) - 0x80;
- case 2:
- return (x ^ 0x8000) - 0x8000;
- case 4:
- return (x ^ 0x80000000) - 0x80000000;
- case 8:
- return x;
- default:
- abort ();
- }
-}
-
static int
size_of_encoded_value (int encoding)
{
}
static dwarf_vma
-get_encoded_value (unsigned char *data, int encoding)
+get_encoded_value (unsigned char *data,
+ int encoding,
+ struct dwarf_section *section)
{
int size = size_of_encoded_value (encoding);
+ dwarf_vma val;
if (encoding & DW_EH_PE_signed)
- return byte_get_signed (data, size);
+ val = byte_get_signed (data, size);
else
- return byte_get (data, size);
+ val = byte_get (data, size);
+
+ if ((encoding & 0x70) == DW_EH_PE_pcrel)
+ val += section->address + (data - section->start);
+ return val;
}
/* Print a dwarf_vma value (typically an address, offset or length) in
fputs (buff + (byte_size == 4 ? 8 : 0), stdout);
}
-unsigned long int
+static const char *
+dwarf_vmatoa (const char *fmtch, bfd_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", BFD_VMA_FMT, fmtch);
+
+ ret = buf[buf_pos++].place;
+ buf_pos %= ARRAY_SIZE(buf);
+
+ snprintf (ret, sizeof (buf[0].place), fmt, value);
+
+ return ret;
+}
+
+bfd_vma
read_leb128 (unsigned char *data, unsigned int *length_return, int sign)
{
- unsigned long int result = 0;
+ bfd_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 |= ((bfd_vma) (byte & 0x7f)) << shift;
shift += 7;
unsigned int bytes_read;
unsigned int len;
unsigned char *name;
- unsigned long adr;
+ bfd_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 ("%" BFD_VMA_FMT "u\t", read_leb128 (data, & bytes_read, 0));
data += bytes_read;
- printf ("%lu\t", read_leb128 (data, & bytes_read, 0));
+ printf ("%" BFD_VMA_FMT "u\t",
+ read_leb128 (data, & bytes_read, 0));
data += bytes_read;
- printf ("%lu\t", read_leb128 (data, & bytes_read, 0));
+ printf ("%" BFD_VMA_FMT "u\t", 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. */
}
static const char *
-fetch_indirect_string (unsigned long offset)
+fetch_indirect_string (bfd_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: %lx\n"), (long) offset);
return _("<offset is too big>");
}
unsigned int pointer_size,
unsigned int offset_size,
int dwarf_version,
- unsigned long length,
- unsigned long cu_offset,
+ bfd_vma length,
+ bfd_vma cu_offset,
struct dwarf_section * section)
{
unsigned op;
unsigned int bytes_read;
- unsigned long uvalue;
+ bfd_vma uvalue;
unsigned char *end = data + length;
int need_frame_base = 0;
data += 8;
break;
case DW_OP_constu:
- printf ("DW_OP_constu: %lu", read_leb128 (data, &bytes_read, 0));
+ printf ("DW_OP_constu: %" BFD_VMA_FMT "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: %" BFD_VMA_FMT "d",
+ read_leb128 (data, &bytes_read, 1));
data += bytes_read;
break;
case DW_OP_dup:
printf ("DW_OP_plus");
break;
case DW_OP_plus_uconst:
- printf ("DW_OP_plus_uconst: %lu",
+ printf ("DW_OP_plus_uconst: %" BFD_VMA_FMT "u",
read_leb128 (data, &bytes_read, 0));
data += bytes_read;
break;
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): %" BFD_VMA_FMT "d",
+ op - DW_OP_breg0,
regname (op - DW_OP_breg0, 1),
read_leb128 (data, &bytes_read, 1));
data += bytes_read;
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: %" BFD_VMA_FMT "u (%s)",
+ 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: %" BFD_VMA_FMT "d",
+ read_leb128 (data, &bytes_read, 1));
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),
+ printf ("DW_OP_bregx: %" BFD_VMA_FMT "u (%s) %" BFD_VMA_FMT "d",
+ uvalue, regname (uvalue, 1),
read_leb128 (data, &bytes_read, 1));
data += bytes_read;
break;
case DW_OP_piece:
- printf ("DW_OP_piece: %lu", read_leb128 (data, &bytes_read, 0));
+ printf ("DW_OP_piece: %" BFD_VMA_FMT "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%" BFD_VMA_FMT "x>",
+ (bfd_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%" BFD_VMA_FMT "x>",
+ (bfd_signed_vma) byte_get (data, 4) + cu_offset);
data += 4;
break;
case DW_OP_call_ref:
break;
case DW_OP_bit_piece:
printf ("DW_OP_bit_piece: ");
- printf ("size: %lu ", read_leb128 (data, &bytes_read, 0));
+ printf ("size: %" BFD_VMA_FMT "u ",
+ read_leb128 (data, &bytes_read, 0));
data += bytes_read;
- printf ("offset: %lu ", read_leb128 (data, &bytes_read, 0));
+ printf ("offset: %" BFD_VMA_FMT "u ",
+ read_leb128 (data, &bytes_read, 0));
data += bytes_read;
break;
dwarf_vma addr;
encoding = *data++;
- addr = get_encoded_value (data, encoding);
- if ((encoding & 0x70) == DW_EH_PE_pcrel)
- addr += section->address + (data - section->start);
+ addr = get_encoded_value (data, encoding, section);
data += size_of_encoded_value (encoding);
printf ("DW_OP_GNU_encoded_addr: fmt:%02x addr:", 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%" BFD_VMA_FMT "x> %" BFD_VMA_FMT "d",
+ (bfd_vma) byte_get (data, pointer_size),
+ (bfd_signed_vma) read_leb128 (data + pointer_size,
+ &bytes_read, 1));
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%" BFD_VMA_FMT "x> %" BFD_VMA_FMT "d",
+ (bfd_vma) byte_get (data, offset_size),
+ (bfd_signed_vma) read_leb128 (data + offset_size,
+ &bytes_read, 1));
data += offset_size + bytes_read;
}
break;
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,
+ bfd_vma cu_offset,
+ bfd_vma pointer_size,
+ bfd_vma offset_size,
int dwarf_version,
debug_info * debug_info_p,
int do_loc,
struct dwarf_section * section)
{
- unsigned long uvalue = 0;
+ bfd_vma uvalue = 0;
unsigned char *block_start = NULL;
unsigned char * orig_data = data;
unsigned int bytes_read;
{
case DW_FORM_ref_addr:
if (!do_loc)
- printf (" <0x%lx>", uvalue);
+ printf (" <0x%" BFD_VMA_FMT "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%" BFD_VMA_FMT "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%" BFD_VMA_FMT "x", uvalue);
break;
case DW_FORM_flag_present:
case DW_FORM_sdata:
case DW_FORM_udata:
if (!do_loc)
- printf (" %ld", uvalue);
+ printf (" %" BFD_VMA_FMT "d", uvalue);
break;
case DW_FORM_ref8:
if (!do_loc)
{
uvalue = byte_get (data, 4);
- printf (" 0x%lx", uvalue);
+ printf (" 0x%" BFD_VMA_FMT "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 (bfd_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 (lmax == 0 || num >= lmax)
{
lmax += 1024;
- debug_info_p->loc_offsets = (long unsigned int *)
+ debug_info_p->loc_offsets = (bfd_vma *)
xcrealloc (debug_info_p->loc_offsets,
lmax, sizeof (*debug_info_p->loc_offsets));
debug_info_p->have_frame_base = (int *)
if (lmax == 0 || num >= lmax)
{
lmax += 1024;
- debug_info_p->range_lists = (long unsigned int *)
+ debug_info_p->range_lists = (bfd_vma *)
xcrealloc (debug_info_p->range_lists,
lmax, sizeof (*debug_info_p->range_lists));
debug_info_p->max_range_lists = lmax;
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: %" BFD_VMA_FMT "x)", uvalue);
else
- printf ("(Unknown: %lx)", uvalue);
+ printf ("(Unknown: %" BFD_VMA_FMT "x)", uvalue);
break;
}
break;
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;
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,
+ bfd_vma cu_offset,
+ bfd_vma pointer_size,
+ bfd_vma offset_size,
int dwarf_version,
debug_info * debug_info_p,
int do_loc,
unsigned char *hdrptr;
unsigned char *tags;
int level;
- unsigned long cu_offset;
+ bfd_vma cu_offset;
int offset_size;
int initial_length_size;
unsigned char signature[8] = { 0 };
if (!do_loc)
{
- printf (_(" Compilation Unit @ offset 0x%lx:\n"), cu_offset);
- printf (_(" Length: 0x%lx (%s)\n"), compunit.cu_length,
+ printf (_(" Compilation Unit @ offset 0x%s:\n"),
+ dwarf_vmatoa ("x", cu_offset));
+ printf (_(" Length: 0x%s (%s)\n"),
+ dwarf_vmatoa ("x", compunit.cu_length),
initial_length_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)
{
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;
}
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 ("%" BFD_VMA_FMT "u\t",
+ read_leb128 (data, & bytes_read, 0));
data += bytes_read;
- printf ("%lu\t", read_leb128 (data, & bytes_read, 0));
+ printf ("%" BFD_VMA_FMT "u\t",
+ read_leb128 (data, & bytes_read, 0));
data += bytes_read;
- printf ("%lu\t", read_leb128 (data, & bytes_read, 0));
+ printf ("%" BFD_VMA_FMT "u\t",
+ read_leb128 (data, & bytes_read, 0));
data += bytes_read;
printf ("%s\n", name);
}
for (i = standard_opcodes[op_code - 1]; i > 0 ; --i)
{
- printf ("0x%lx%s", read_leb128 (data, &bytes_read, 0),
+ printf ("0x%" BFD_VMA_FMT "x%s",
+ read_leb128 (data, &bytes_read, 0),
i == 1 ? "" : ", ");
data += bytes_read;
}
for (i = standard_opcodes[op_code - 1]; i > 0 ; --i)
{
- printf ("0x%lx%s", read_leb128 (data, &bytes_read, 0),
+ printf ("0x%" BFD_VMA_FMT "x%s",
+ read_leb128 (data, &bytes_read, 0),
i == 1 ? "" : ", ");
data += bytes_read;
}
&& 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"));
/* 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]));
printf (_("Contents of the %s section:\n\n"), section->name);
printf (_(" Offset Begin End Expression\n"));
&& 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);
segment_selector = byte_get (start, fc->segment_size);
start += fc->segment_size;
}
- fc->pc_begin = get_encoded_value (start, fc->fde_encoding);
- if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel)
- fc->pc_begin += section->address + (start - section_start);
+ 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;
break;
case DW_CFA_set_loc:
- vma = get_encoded_value (start, fc->fde_encoding);
- if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel)
- vma += section->address + (start - section_start);
+ vma = get_encoded_value (start, fc->fde_encoding, section);
start += encoded_ptr_size;
if (do_debug_frames_interp)
frame_display_row (fc, &need_col_headers, &max_regs);
#undef LEB
#undef SLEB
+static int
+display_gdb_index (struct dwarf_section *section,
+ void *file ATTRIBUTE_UNUSED)
+{
+ unsigned char *start = section->start;
+ uint32_t version;
+ uint32_t cu_list_offset, tu_list_offset;
+ uint32_t address_table_offset, symbol_table_offset, constant_pool_offset;
+ unsigned int cu_list_elements, tu_list_elements;
+ unsigned int address_table_size, symbol_table_slots;
+ unsigned char *cu_list, *tu_list;
+ unsigned char *address_table, *symbol_table, *constant_pool;
+ unsigned int i;
+
+ /* The documentation for the format of this file is in gdb/dwarf2read.c. */
+
+ printf (_("Contents of the %s section:\n"), section->name);
+
+ if (section->size < 6 * sizeof (uint32_t))
+ {
+ warn (_("Truncated header in the %s section.\n"), section->name);
+ return 0;
+ }
+
+ version = byte_get_little_endian (start, 4);
+ printf (_("Version %ld\n"), (long) version);
+
+ /* Prior versions are obsolete, and future versions may not be
+ backwards compatible. */
+ switch (version)
+ {
+ case 3:
+ warn (_("The address table data in version 3 may be wrong.\n"));
+ break;
+ case 4:
+ break;
+ default:
+ warn (_("Unsupported version %lu.\n"), (unsigned long) version);
+ return 0;
+ }
+
+ cu_list_offset = byte_get_little_endian (start + 4, 4);
+ tu_list_offset = byte_get_little_endian (start + 8, 4);
+ address_table_offset = byte_get_little_endian (start + 12, 4);
+ symbol_table_offset = byte_get_little_endian (start + 16, 4);
+ constant_pool_offset = byte_get_little_endian (start + 20, 4);
+
+ if (cu_list_offset > section->size
+ || tu_list_offset > section->size
+ || address_table_offset > section->size
+ || symbol_table_offset > section->size
+ || constant_pool_offset > section->size)
+ {
+ warn (_("Corrupt header in the %s section.\n"), section->name);
+ return 0;
+ }
+
+ cu_list_elements = (tu_list_offset - cu_list_offset) / 8;
+ tu_list_elements = (address_table_offset - tu_list_offset) / 8;
+ address_table_size = symbol_table_offset - address_table_offset;
+ symbol_table_slots = (constant_pool_offset - symbol_table_offset) / 8;
+
+ cu_list = start + cu_list_offset;
+ tu_list = start + tu_list_offset;
+ address_table = start + address_table_offset;
+ symbol_table = start + symbol_table_offset;
+ constant_pool = start + constant_pool_offset;
+
+ printf (_("\nCU table:\n"));
+ for (i = 0; i < cu_list_elements; i += 2)
+ {
+ uint64_t cu_offset = byte_get_little_endian (cu_list + i * 8, 8);
+ uint64_t cu_length = byte_get_little_endian (cu_list + i * 8 + 8, 8);
+
+ printf (_("[%3u] 0x%lx - 0x%lx\n"), i / 2,
+ (unsigned long) cu_offset,
+ (unsigned long) (cu_offset + cu_length - 1));
+ }
+
+ printf (_("\nTU table:\n"));
+ for (i = 0; i < tu_list_elements; i += 3)
+ {
+ uint64_t tu_offset = byte_get_little_endian (tu_list + i * 8, 8);
+ uint64_t type_offset = byte_get_little_endian (tu_list + i * 8 + 8, 8);
+ uint64_t signature = byte_get_little_endian (tu_list + i * 8 + 16, 8);
+
+ printf (_("[%3u] 0x%lx 0x%lx "), i / 3,
+ (unsigned long) tu_offset,
+ (unsigned long) type_offset);
+ print_dwarf_vma (signature, 8);
+ printf ("\n");
+ }
+
+ printf (_("\nAddress table:\n"));
+ for (i = 0; i < address_table_size; 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);
+ uint32_t cu_index = byte_get_little_endian (address_table + i + 16, 4);
+
+ print_dwarf_vma (low, 8);
+ print_dwarf_vma (high, 8);
+ printf (_("%lu\n"), (unsigned long) cu_index);
+ }
+
+ printf (_("\nSymbol table:\n"));
+ for (i = 0; i < symbol_table_slots; ++i)
+ {
+ uint32_t name_offset = byte_get_little_endian (symbol_table + i * 8, 4);
+ uint32_t cu_vector_offset = byte_get_little_endian (symbol_table + i * 8 + 4, 4);
+ uint32_t num_cus, cu;
+
+ if (name_offset != 0
+ || cu_vector_offset != 0)
+ {
+ unsigned int j;
+
+ printf ("[%3u] %s:", i, constant_pool + name_offset);
+ num_cus = byte_get_little_endian (constant_pool + cu_vector_offset, 4);
+ for (j = 0; j < num_cus; ++j)
+ {
+ 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));
+ else
+ printf (" %lu", (unsigned long) cu);
+ }
+ printf ("\n");
+ }
+ }
+
+ return 1;
+}
+
static int
display_debug_not_supported (struct dwarf_section *section,
void *file ATTRIBUTE_UNUSED)
return xrealloc (ptr, nmemb * size);
}
-void
-error (const char *message, ...)
-{
- va_list args;
-
- va_start (args, message);
- fprintf (stderr, _("%s: Error: "), program_name);
- vfprintf (stderr, message, args);
- va_end (args);
-}
-
-void
-warn (const char *message, ...)
-{
- va_list args;
-
- va_start (args, message);
- fprintf (stderr, _("%s: Warning: "), program_name);
- vfprintf (stderr, message, args);
- va_end (args);
-}
-
void
free_debug_memory (void)
{
with earlier versions of readelf. */
{ "ranges", & do_debug_aranges, 1 },
{ "str", & do_debug_str, 1 },
+ /* The special .gdb_index section. */
+ { "gdb_index", & do_gdb_index, 1 },
/* These trace_* sections are used by Itanium VMS. */
{ "trace_abbrev", & do_trace_abbrevs, 1 },
{ "trace_aranges", & do_trace_aranges, 1 },
do_debug_macinfo = 1;
do_debug_str = 1;
do_debug_loc = 1;
+ do_gdb_index = 1;
do_trace_info = 1;
do_trace_abbrevs = 1;
do_trace_aranges = 1;
display_debug_types, &do_debug_info, 1 },
{ { ".debug_weaknames", ".zdebug_weaknames", NULL, NULL, 0, 0 },
display_debug_not_supported, NULL, 0 },
+ { { ".gdb_index", "", NULL, NULL, 0, 0 },
+ display_gdb_index, &do_gdb_index, 0 },
{ { ".trace_info", "", NULL, NULL, 0, 0 },
display_trace_info, &do_trace_info, 1 },
{ { ".trace_abbrev", "", NULL, NULL, 0, 0 },