int do_debug_info;
int do_debug_abbrevs;
int do_debug_lines;
+int do_debug_lines_decoded;
int do_debug_pubnames;
int do_debug_aranges;
int do_debug_ranges;
int do_debug_macinfo;
int do_debug_str;
int do_debug_loc;
+int do_wide;
dwarf_vma (*byte_get) (unsigned char *, int);
}
}
+static int
+size_of_encoded_value (int encoding)
+{
+ switch (encoding & 0x7)
+ {
+ default: /* ??? */
+ case 0: return eh_addr_size;
+ case 2: return 2;
+ case 3: return 4;
+ case 4: return 8;
+ }
+}
+
+static dwarf_vma
+get_encoded_value (unsigned char *data, int encoding)
+{
+ int size = size_of_encoded_value (encoding);
+
+ if (encoding & DW_EH_PE_signed)
+ return byte_get_signed (data, size);
+ else
+ return byte_get (data, size);
+}
+
+/* Print a dwarf_vma value (typically an address, offset or length) in
+ hexadecimal format, followed by a space. The length of the value (and
+ hence the precision displayed) is determined by the byte_size parameter. */
+
+static void
+print_dwarf_vma (dwarf_vma val, unsigned byte_size)
+{
+ static char buff[18];
+
+ /* 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__
+ snprintf (buff, sizeof (buff), "%16.16llx ", val);
+#else
+ snprintf (buff, sizeof (buff), "%016I64x ", val);
+#endif
+#else
+ snprintf (buff, sizeof (buff), "%16.16lx ", val);
+#endif
+
+ fputs (buff + (byte_size == 4 ? 8 : 0), stdout);
+}
+
static unsigned long int
read_leb128 (unsigned char *data, unsigned int *length_return, int sign)
{
case DW_LNE_HP_define_proc:
printf ("DW_LNE_HP_define_proc");
break;
-
+
default:
if (op_code >= DW_LNE_lo_user
/* The test against DW_LNW_hi_user is redundant due to
decode_location_expression (unsigned char * data,
unsigned int pointer_size,
unsigned long length,
- unsigned long cu_offset)
+ unsigned long cu_offset,
+ struct dwarf_section * section)
{
unsigned op;
unsigned int bytes_read;
printf ("DW_OP_GNU_uninit");
/* FIXME: Is there data associated with this OP ? */
break;
+ case DW_OP_GNU_encoded_addr:
+ {
+ int encoding;
+ dwarf_vma addr;
+
+ encoding = *data++;
+ addr = get_encoded_value (data, encoding);
+ if ((encoding & 0x70) == DW_EH_PE_pcrel)
+ addr += section->address + (data - section->start);
+ data += size_of_encoded_value (encoding);
+
+ printf ("DW_OP_GNU_encoded_addr: fmt:%02x addr:", encoding);
+ print_dwarf_vma (addr, pointer_size);
+ }
+ break;
/* HP extensions. */
case DW_OP_HP_is_value:
/* FIXME: Is there data associated with this OP ? */
break;
+ /* PGI (STMicroelectronics) extensions. */
+ case DW_OP_PGI_omp_thread_num:
+ /* Pushes the thread number for the current thread as it would be
+ returned by the standard OpenMP library function:
+ omp_get_thread_num(). The "current thread" is the thread for
+ which the expression is being evaluated. */
+ printf ("DW_OP_PGI_omp_thread_num");
+ break;
+
default:
if (op >= DW_OP_lo_user
&& op <= DW_OP_hi_user)
case DW_AT_data_location:
case DW_AT_stride:
case DW_AT_upper_bound:
- case DW_AT_lower_bound:
+ case DW_AT_lower_bound:
if (block_start)
{
int need_frame_base;
need_frame_base = decode_location_expression (block_start,
pointer_size,
uvalue,
- cu_offset);
+ cu_offset, section);
printf (")");
if (need_frame_base && !have_frame_base)
printf (_(" [without DW_AT_frame_base]"));
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, (long int)(orig_data - section->start));
+ uvalue, (unsigned long) (orig_data - section->start));
else
{
unsigned long abbrev_number;
abbrev_entry * entry;
abbrev_number = read_leb128 (section->start + uvalue, NULL, 0);
-
+
printf ("[Abbrev Number: %ld", abbrev_number);
for (entry = first_abbrev; entry != NULL; entry = entry->next)
if (entry->entry == abbrev_number)
case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines";
/* HP Extensions. */
- case DW_AT_HP_block_index: return "DW_AT_HP_block_index";
+ case DW_AT_HP_block_index: return "DW_AT_HP_block_index";
case DW_AT_HP_actuals_stmt_list: return "DW_AT_HP_actuals_stmt_list";
case DW_AT_HP_proc_per_section: return "DW_AT_HP_proc_per_section";
case DW_AT_HP_raw_data_ptr: return "DW_AT_HP_raw_data_ptr";
/* One value is shared by the MIPS and HP extensions: */
case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde or DW_AT_HP_unmodifiable";
-
+
/* GNU extensions. */
case DW_AT_sf_names: return "DW_AT_sf_names";
case DW_AT_src_info: return "DW_AT_src_info";
if (!do_loc)
printf (_(" <%d><%lx>: Abbrev Number: %lu"),
level, die_offset, abbrev_number);
-
+
/* Scan through the abbreviation list until we reach the
correct entry. */
for (entry = first_abbrev;
if (!do_loc)
printf (_(" (%s)\n"), get_TAG_name (entry->tag));
-
+
switch (entry->tag)
{
default:
debug_information + unit,
do_loc, section);
}
-
+
if (entry->children)
++level;
}
}
-
+
/* Set num_debug_info_entries here so that it can be used to check if
we need to process .debug_loc and .debug_ranges sections. */
if ((do_loc || do_debug_loc || do_debug_ranges)
&& num_debug_info_entries == 0)
num_debug_info_entries = num_units;
-
+
if (!do_loc)
{
printf ("\n");
}
-
+
return 1;
}
}
static int
-display_debug_lines (struct dwarf_section *section, void *file)
+display_debug_lines_raw (struct dwarf_section *section,
+ unsigned char *data,
+ unsigned char *end)
{
unsigned char *start = section->start;
- unsigned char *data = start;
- unsigned char *end = start + section->size;
- printf (_("\nDump of debug contents of section %s:\n\n"),
- section->name);
-
- if (load_debug_info (file) == 0)
- {
- warn (_("Unable to load/parse the .debug_info section, so cannot interpret the %s section.\n"),
- section->name);
- return 0;
- }
+ printf (_("Raw dump of debug contents of section %s:\n\n"),
+ section->name);
while (data < end)
{
return 1;
}
+typedef struct
+{
+ 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. */
+
+static int
+display_debug_lines_decoded (struct dwarf_section *section,
+ unsigned char *data,
+ unsigned char *end)
+{
+ printf (_("Decoded dump of debug contents of section %s:\n\n"),
+ section->name);
+
+ while (data < end)
+ {
+ /* This loop amounts to one iteration per compilation unit. */
+ DWARF2_Internal_LineInfo info;
+ unsigned char *standard_opcodes;
+ unsigned char *end_of_sequence;
+ unsigned char *hdrptr;
+ int initial_length_size;
+ int offset_size;
+ int i;
+ File_Entry *file_table = NULL;
+ unsigned char **directory_table = NULL;
+ unsigned int prev_line = 0;
+
+ hdrptr = data;
+
+ /* Extract information from the Line Number Program Header.
+ (section 6.2.4 in the Dwarf3 doc). */
+
+ /* Get the length of this CU's line number information block. */
+ info.li_length = byte_get (hdrptr, 4);
+ hdrptr += 4;
+
+ if (info.li_length == 0xffffffff)
+ {
+ /* This section is 64-bit DWARF 3. */
+ info.li_length = byte_get (hdrptr, 8);
+ hdrptr += 8;
+ offset_size = 8;
+ initial_length_size = 12;
+ }
+ else
+ {
+ offset_size = 4;
+ initial_length_size = 4;
+ }
+
+ if (info.li_length + initial_length_size > section->size)
+ {
+ warn (_("The line info appears to be corrupt - "
+ "the section is too small\n"));
+ return 0;
+ }
+
+ /* Get this CU's Line Number Block version number. */
+ info.li_version = byte_get (hdrptr, 2);
+ hdrptr += 2;
+ if (info.li_version != 2 && info.li_version != 3)
+ {
+ warn (_("Only DWARF version 2 and 3 line info is currently "
+ "supported.\n"));
+ return 0;
+ }
+
+ info.li_prologue_length = byte_get (hdrptr, offset_size);
+ hdrptr += offset_size;
+ info.li_min_insn_length = byte_get (hdrptr, 1);
+ hdrptr++;
+ info.li_default_is_stmt = byte_get (hdrptr, 1);
+ hdrptr++;
+ info.li_line_base = byte_get (hdrptr, 1);
+ hdrptr++;
+ info.li_line_range = byte_get (hdrptr, 1);
+ hdrptr++;
+ info.li_opcode_base = byte_get (hdrptr, 1);
+ hdrptr++;
+
+ /* Sign extend the line base field. */
+ info.li_line_base <<= 24;
+ info.li_line_base >>= 24;
+
+ /* Find the end of this CU's Line Number Information Block. */
+ end_of_sequence = data + info.li_length + initial_length_size;
+
+ reset_state_machine (info.li_default_is_stmt);
+
+ /* Save a pointer to the contents of the Opcodes table. */
+ standard_opcodes = hdrptr;
+
+ /* Traverse the Directory table just to count entries. */
+ data = standard_opcodes + info.li_opcode_base - 1;
+ if (*data != 0)
+ {
+ unsigned int n_directories = 0;
+ unsigned char *ptr_directory_table = data;
+ int i;
+
+ while (*data != 0)
+ {
+ data += strlen ((char *) data) + 1;
+ n_directories++;
+ }
+
+ /* Go through the directory table again to save the directories. */
+ directory_table = xmalloc (n_directories * sizeof (unsigned char *));
+
+ i = 0;
+ while (*ptr_directory_table != 0)
+ {
+ directory_table[i] = ptr_directory_table;
+ ptr_directory_table += strlen ((char *) ptr_directory_table) + 1;
+ i++;
+ }
+ }
+ /* Skip the NUL at the end of the table. */
+ data++;
+
+ /* Traverse the File Name table just to count the entries. */
+ if (*data != 0)
+ {
+ unsigned int n_files = 0;
+ unsigned char *ptr_file_name_table = data;
+ int i;
+
+ while (*data != 0)
+ {
+ unsigned int bytes_read;
+
+ /* Skip Name, directory index, last modification time and length
+ of file. */
+ data += strlen ((char *) data) + 1;
+ read_leb128 (data, & bytes_read, 0);
+ data += bytes_read;
+ read_leb128 (data, & bytes_read, 0);
+ data += bytes_read;
+ read_leb128 (data, & bytes_read, 0);
+ data += bytes_read;
+
+ n_files++;
+ }
+
+ /* Go through the file table again to save the strings. */
+ file_table = xmalloc (n_files * sizeof (File_Entry));
+
+ i = 0;
+ while (*ptr_file_name_table != 0)
+ {
+ unsigned int bytes_read;
+
+ file_table[i].name = ptr_file_name_table;
+ ptr_file_name_table += strlen ((char *) ptr_file_name_table) + 1;
+
+ /* We are not interested in directory, time or size. */
+ file_table[i].directory_index = read_leb128 (ptr_file_name_table,
+ & bytes_read, 0);
+ ptr_file_name_table += bytes_read;
+ file_table[i].modification_date = read_leb128 (ptr_file_name_table,
+ & bytes_read, 0);
+ ptr_file_name_table += bytes_read;
+ file_table[i].length = read_leb128 (ptr_file_name_table, & bytes_read, 0);
+ ptr_file_name_table += bytes_read;
+ i++;
+ }
+ i = 0;
+
+ /* Print the Compilation Unit's name and a header. */
+ if (directory_table == NULL)
+ {
+ printf (_("CU: %s:\n"), file_table[0].name);
+ printf (_("File name Line number Starting address\n"));
+ }
+ else
+ {
+ if (do_wide || strlen ((char *) directory_table[0]) < 76)
+ {
+ printf (_("CU: %s/%s:\n"), directory_table[0],
+ file_table[0].name);
+ }
+ else
+ {
+ printf (_("%s:\n"), file_table[0].name);
+ }
+ printf (_("File name Line number Starting address\n"));
+ }
+ }
+
+ /* Skip the NUL at the end of the table. */
+ data++;
+
+ /* This loop iterates through the Dwarf Line Number Program. */
+ while (data < end_of_sequence)
+ {
+ unsigned char op_code;
+ int adv;
+ unsigned long int uladv;
+ unsigned int bytes_read;
+ int is_special_opcode = 0;
+
+ op_code = *data++;
+ prev_line = state_machine_regs.line;
+
+ if (op_code >= info.li_opcode_base)
+ {
+ op_code -= info.li_opcode_base;
+ uladv = (op_code / info.li_line_range) * info.li_min_insn_length;
+ state_machine_regs.address += uladv;
+
+ adv = (op_code % info.li_line_range) + info.li_line_base;
+ state_machine_regs.line += adv;
+ is_special_opcode = 1;
+ }
+ else switch (op_code)
+ {
+ case DW_LNS_extended_op:
+ {
+ unsigned int ext_op_code_len;
+ unsigned int bytes_read;
+ unsigned char ext_op_code;
+ unsigned char *op_code_data = data;
+
+ ext_op_code_len = read_leb128 (op_code_data, &bytes_read, 0);
+ op_code_data += bytes_read;
+
+ if (ext_op_code_len == 0)
+ {
+ warn (_("badly formed extended line op encountered!\n"));
+ break;
+ }
+ ext_op_code_len += bytes_read;
+ ext_op_code = *op_code_data++;
+
+ switch (ext_op_code)
+ {
+ case DW_LNE_end_sequence:
+ reset_state_machine (info.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);
+ break;
+ case DW_LNE_define_file:
+ {
+ unsigned int dir_index = 0;
+
+ ++state_machine_regs.last_file_entry;
+ op_code_data += strlen ((char *) op_code_data) + 1;
+ dir_index = read_leb128 (op_code_data, & bytes_read, 0);
+ op_code_data += bytes_read;
+ read_leb128 (op_code_data, & bytes_read, 0);
+ op_code_data += bytes_read;
+ read_leb128 (op_code_data, & bytes_read, 0);
+
+ printf (_("%s:\n"), directory_table[dir_index]);
+ break;
+ }
+ default:
+ printf (_("UNKNOWN: length %d\n"), ext_op_code_len - bytes_read);
+ break;
+ }
+ data += ext_op_code_len;
+ break;
+ }
+ case DW_LNS_copy:
+ break;
+
+ case DW_LNS_advance_pc:
+ uladv = read_leb128 (data, & bytes_read, 0);
+ uladv *= info.li_min_insn_length;
+ data += bytes_read;
+ state_machine_regs.address += uladv;
+ break;
+
+ case DW_LNS_advance_line:
+ adv = read_leb128 (data, & bytes_read, 1);
+ data += bytes_read;
+ state_machine_regs.line += adv;
+ break;
+
+ case DW_LNS_set_file:
+ adv = read_leb128 (data, & bytes_read, 0);
+ data += bytes_read;
+ state_machine_regs.file = adv;
+ if (file_table[state_machine_regs.file - 1].directory_index == 0)
+ {
+ /* If directory index is 0, that means current directory. */
+ printf (_("\n./%s:[++]\n"),
+ file_table[state_machine_regs.file - 1].name);
+ }
+ else
+ {
+ /* The directory index starts counting at 1. */
+ printf (_("\n%s/%s:\n"),
+ directory_table[file_table[state_machine_regs.file - 1].directory_index - 1],
+ file_table[state_machine_regs.file - 1].name);
+ }
+ break;
+
+ case DW_LNS_set_column:
+ uladv = read_leb128 (data, & bytes_read, 0);
+ data += bytes_read;
+ state_machine_regs.column = uladv;
+ break;
+
+ case DW_LNS_negate_stmt:
+ adv = state_machine_regs.is_stmt;
+ adv = ! adv;
+ state_machine_regs.is_stmt = adv;
+ break;
+
+ case DW_LNS_set_basic_block:
+ state_machine_regs.basic_block = 1;
+ break;
+
+ case DW_LNS_const_add_pc:
+ uladv = (((255 - info.li_opcode_base) / info.li_line_range)
+ * info.li_min_insn_length);
+ state_machine_regs.address += uladv;
+ break;
+
+ case DW_LNS_fixed_advance_pc:
+ uladv = byte_get (data, 2);
+ data += 2;
+ state_machine_regs.address += uladv;
+ break;
+
+ case DW_LNS_set_prologue_end:
+ break;
+
+ case DW_LNS_set_epilogue_begin:
+ break;
+
+ case DW_LNS_set_isa:
+ uladv = read_leb128 (data, & bytes_read, 0);
+ data += bytes_read;
+ printf (_(" Set ISA to %lu\n"), uladv);
+ break;
+
+ default:
+ printf (_(" Unknown opcode %d with operands: "), op_code);
+
+ for (i = standard_opcodes[op_code - 1]; i > 0 ; --i)
+ {
+ printf ("0x%lx%s", read_leb128 (data, &bytes_read, 0),
+ i == 1 ? "" : ", ");
+ data += bytes_read;
+ }
+ putchar ('\n');
+ break;
+ }
+
+ /* Only Special opcodes, DW_LNS_copy and DW_LNE_end_sequence adds a row
+ to the DWARF address/line matrix. */
+ if ((is_special_opcode) || (op_code == DW_LNE_end_sequence)
+ || (op_code == DW_LNS_copy))
+ {
+ const unsigned int MAX_FILENAME_LENGTH = 35;
+ char *fileName = (char *)file_table[state_machine_regs.file - 1].name;
+ char *newFileName = NULL;
+ size_t fileNameLength = strlen (fileName);
+
+ if ((fileNameLength > MAX_FILENAME_LENGTH) && (!do_wide))
+ {
+ newFileName = xmalloc (MAX_FILENAME_LENGTH + 1);
+ /* Truncate file name */
+ strncpy (newFileName,
+ fileName + fileNameLength - MAX_FILENAME_LENGTH,
+ MAX_FILENAME_LENGTH + 1);
+ }
+ else
+ {
+ newFileName = xmalloc (fileNameLength + 1);
+ strncpy (newFileName, fileName, fileNameLength + 1);
+ }
+
+ if (!do_wide || (fileNameLength <= MAX_FILENAME_LENGTH))
+ {
+ printf (_("%-35s %11d %#18lx\n"), newFileName,
+ state_machine_regs.line, state_machine_regs.address);
+ }
+ else
+ {
+ printf (_("%s %11d %#18lx\n"), newFileName,
+ state_machine_regs.line, state_machine_regs.address);
+ }
+
+ if (op_code == DW_LNE_end_sequence)
+ printf ("\n");
+
+ free (newFileName);
+ }
+ }
+ free (file_table);
+ file_table = NULL;
+ free (directory_table);
+ directory_table = NULL;
+ putchar ('\n');
+ }
+
+ return 1;
+}
+
+static int
+display_debug_lines (struct dwarf_section *section, void *file)
+{
+ unsigned char *data = section->start;
+ unsigned char *end = data + section->size;
+ int retValRaw = 0;
+ int retValDecoded = 0;
+
+ if (load_debug_info (file) == 0)
+ {
+ warn (_("Unable to load/parse the .debug_info section, so cannot interpret the %s section.\n"),
+ section->name);
+ return 0;
+ }
+
+ if (do_debug_lines)
+ retValRaw = display_debug_lines_raw (section, data, end);
+
+ if (do_debug_lines_decoded)
+ retValDecoded = display_debug_lines_decoded (section, data, end);
+
+ if ((do_debug_lines && !retValRaw)
+ || (do_debug_lines_decoded && !retValDecoded))
+ return 0;
+
+ return 1;
+}
+
static debug_info *
find_debug_info_for_offset (unsigned long offset)
{
&& find_debug_info_for_offset (pubnames.pn_offset) == NULL)
warn (_(".debug_info offset of 0x%lx in %s section does not point to a CU header.\n"),
pubnames.pn_offset, section->name);
-
+
pubnames.pn_size = byte_get (data, offset_size);
data += offset_size;
seen_first_offset = 0;
for (i = first; i < num_debug_info_entries; i++)
{
- unsigned long begin;
- unsigned long end;
- unsigned long minus_one;
+ dwarf_vma begin;
+ dwarf_vma end;
unsigned short length;
unsigned long offset;
unsigned int pointer_size;
{
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;
+ offset = debug_information [i].loc_offsets [j] - section->address;
next = section_begin + offset;
base_address = debug_information [i].base_address;
{
if (start < next)
warn (_("There is a hole [0x%lx - 0x%lx] in .debug_loc section.\n"),
- (long)(start - section_begin), (long)(next - section_begin));
+ (unsigned long) (start - section_begin),
+ (unsigned long) (next - section_begin));
else if (start > next)
warn (_("There is an overlap [0x%lx - 0x%lx] in .debug_loc section.\n"),
- (long)(start - section_begin), (long)(next - section_begin));
+ (unsigned long) (start - section_begin),
+ (unsigned long) (next - section_begin));
}
start = next;
break;
}
- begin = byte_get (start, pointer_size);
+ /* Note: we use sign extension here in order to be sure that
+ we can detect 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 (start, pointer_size);
+ end = byte_get_signed (start, pointer_size);
start += pointer_size;
+ printf (" %8.8lx ", offset);
+
if (begin == 0 && end == 0)
{
- printf (_(" %8.8lx <End of list>\n"), offset);
+ printf (_("<End of list>\n"));
break;
}
/* Check base address specifiers. */
- minus_one = -1;
- if (pointer_size < sizeof (minus_one))
- minus_one = (1L << (pointer_size * 8)) - 1;
- if (begin == minus_one && end != minus_one)
+ if (begin == (dwarf_vma) -1 && end != (dwarf_vma) -1)
{
base_address = end;
- printf (_(" %8.8lx %8.8lx %8.8lx (base address)\n"),
- offset, begin, end);
+ print_dwarf_vma (begin, pointer_size);
+ print_dwarf_vma (end, pointer_size);
+ printf (_("(base address)\n"));
continue;
}
break;
}
- printf (" %8.8lx %8.8lx %8.8lx (",
- offset, begin + base_address, end + base_address);
+ print_dwarf_vma (begin + base_address, pointer_size);
+ print_dwarf_vma (end + base_address, pointer_size);
+
+ putchar ('(');
need_frame_base = decode_location_expression (start,
pointer_size,
length,
- cu_offset);
+ cu_offset, section);
putchar (')');
if (need_frame_base && !has_frame_base)
unsigned char *hdrptr;
DWARF2_Internal_ARange arange;
unsigned char *ranges;
- unsigned long length;
- unsigned long address;
+ dwarf_vma length;
+ dwarf_vma address;
unsigned char address_size;
int excess;
int offset_size;
warn (_("Pointer size + Segment size is not a power of two.\n"));
break;
}
-
+
if (address_size > 4)
printf (_("\n Address Length\n"));
else
ranges += address_size;
- if (address_size > 4)
- printf (" 0x%16.16lx 0x%lx\n", address, length);
- else
- printf (" 0x%8.8lx 0x%lx\n", address, length);
+ print_dwarf_vma (address, address_size);
+ print_dwarf_vma (length, address_size);
+ putchar ('\n');
}
}
seen_first_offset = 0;
for (i = first; i < num_debug_info_entries; i++)
{
- unsigned long begin;
- unsigned long end;
+ dwarf_vma begin;
+ dwarf_vma end;
unsigned long offset;
unsigned int pointer_size;
unsigned long base_address;
{
if (start < next)
warn (_("There is a hole [0x%lx - 0x%lx] in %s section.\n"),
- (long)(start - section_begin),
- (long)(next - section_begin), section->name);
+ (unsigned long) (start - section_begin),
+ (unsigned long) (next - section_begin), section->name);
else if (start > next)
warn (_("There is an overlap [0x%lx - 0x%lx] in %s section.\n"),
- (long)(start - section_begin),
- (long)(next - section_begin), section->name);
+ (unsigned long) (start - section_begin),
+ (unsigned long) (next - section_begin), section->name);
}
start = next;
while (1)
{
- begin = byte_get (start, pointer_size);
+ /* Note: we use sign extension here in order to be sure that
+ we can detect 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 (start, pointer_size);
+ end = byte_get_signed (start, pointer_size);
start += pointer_size;
+ printf (" %8.8lx ", offset);
+
if (begin == 0 && end == 0)
{
- printf (_(" %8.8lx <End of list>\n"), offset);
+ printf (_("<End of list>\n"));
break;
}
+ print_dwarf_vma (begin, pointer_size);
+ print_dwarf_vma (end, pointer_size);
+
/* Check base address specifiers. */
- if (begin == -1UL && end != -1UL)
+ if (begin == (dwarf_vma) -1 && end != (dwarf_vma) -1)
{
base_address = end;
- printf (" %8.8lx %8.8lx %8.8lx (base address)\n",
- offset, begin, end);
+ printf ("(base address)\n");
continue;
}
- printf (" %8.8lx %8.8lx %8.8lx",
- offset, begin + base_address, end + base_address);
-
if (begin == end)
- fputs (_(" (start == end)"), stdout);
+ fputs (_("(start == end)"), stdout);
else if (begin > end)
- fputs (_(" (start > end)"), stdout);
+ fputs (_("(start > end)"), stdout);
putchar ('\n');
}
printf ("\n");
}
-static int
-size_of_encoded_value (int encoding)
-{
- switch (encoding & 0x7)
- {
- default: /* ??? */
- case 0: return eh_addr_size;
- case 2: return 2;
- case 3: return 4;
- case 4: return 8;
- }
-}
-
-static dwarf_vma
-get_encoded_value (unsigned char *data, int encoding)
-{
- int size = size_of_encoded_value (encoding);
-
- if (encoding & DW_EH_PE_signed)
- return byte_get_signed (data, size);
- else
- return byte_get (data, size);
-}
-
#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
if (! do_debug_frames_interp)
{
printf (" DW_CFA_def_cfa_expression (");
- decode_location_expression (start, eh_addr_size, ul, 0);
+ decode_location_expression (start, eh_addr_size, ul, 0,
+ section);
printf (")\n");
}
fc->cfa_exp = 1;
printf (" DW_CFA_expression: %s (",
regname (reg, 0));
decode_location_expression (start, eh_addr_size,
- ul, 0);
+ ul, 0, section);
printf (")\n");
}
fc->col_type[reg] = DW_CFA_expression;
{
printf (" DW_CFA_val_expression: %s (",
regname (reg, 0));
- decode_location_expression (start, eh_addr_size, ul, 0);
+ decode_location_expression (start, eh_addr_size, ul, 0,
+ section);
printf (")\n");
}
fc->col_type[reg] = DW_CFA_val_expression;
if (op >= DW_CFA_lo_user && op <= DW_CFA_hi_user)
printf (_(" DW_CFA_??? (User defined call frame op: %#x)\n"), op);
else
- warn (_("unsupported or unknown Dwarf Call Frame Instruction number: %#x\n"), op);
+ warn (_("unsupported or unknown Dwarf Call Frame Instruction number: %#x\n"), op);
start = block_end;
}
}
struct dwarf_section_display debug_displays[] =
{
- { { ".debug_abbrev", NULL, 0, 0 },
+ { { ".debug_abbrev", ".zdebug_abbrev", NULL, NULL, 0, 0 },
display_debug_abbrev, 0, 0 },
- { { ".debug_aranges", NULL, 0, 0 },
+ { { ".debug_aranges", ".zdebug_aranges", NULL, NULL, 0, 0 },
display_debug_aranges, 0, 0 },
- { { ".debug_frame", NULL, 0, 0 },
+ { { ".debug_frame", ".zdebug_frame", NULL, NULL, 0, 0 },
display_debug_frames, 1, 0 },
- { { ".debug_info", NULL, 0, 0 },
+ { { ".debug_info", ".zdebug_info", NULL, NULL, 0, 0 },
display_debug_info, 1, 0 },
- { { ".debug_line", NULL, 0, 0 },
+ { { ".debug_line", ".zdebug_line", NULL, NULL, 0, 0 },
display_debug_lines, 0, 0 },
- { { ".debug_pubnames", NULL, 0, 0 },
+ { { ".debug_pubnames", ".zdebug_pubnames", NULL, NULL, 0, 0 },
display_debug_pubnames, 0, 0 },
- { { ".eh_frame", NULL, 0, 0 },
+ { { ".eh_frame", "", NULL, NULL, 0, 0 },
display_debug_frames, 1, 1 },
- { { ".debug_macinfo", NULL, 0, 0 },
+ { { ".debug_macinfo", ".zdebug_macinfo", NULL, NULL, 0, 0 },
display_debug_macinfo, 0, 0 },
- { { ".debug_str", NULL, 0, 0 },
+ { { ".debug_str", ".zdebug_str", NULL, NULL, 0, 0 },
display_debug_str, 0, 0 },
- { { ".debug_loc", NULL, 0, 0 },
+ { { ".debug_loc", ".zdebug_loc", NULL, NULL, 0, 0 },
display_debug_loc, 0, 0 },
- { { ".debug_pubtypes", NULL, 0, 0 },
+ { { ".debug_pubtypes", ".zdebug_pubtypes", NULL, NULL, 0, 0 },
display_debug_pubnames, 0, 0 },
- { { ".debug_ranges", NULL, 0, 0 },
+ { { ".debug_ranges", ".zdebug_ranges", NULL, NULL, 0, 0 },
display_debug_ranges, 0, 0 },
- { { ".debug_static_func", NULL, 0, 0 },
+ { { ".debug_static_func", ".zdebug_static_func", NULL, NULL, 0, 0 },
display_debug_not_supported, 0, 0 },
- { { ".debug_static_vars", NULL, 0, 0 },
+ { { ".debug_static_vars", ".zdebug_static_vars", NULL, NULL, 0, 0 },
display_debug_not_supported, 0, 0 },
- { { ".debug_types", NULL, 0, 0 },
+ { { ".debug_types", ".zdebug_types", NULL, NULL, 0, 0 },
display_debug_not_supported, 0, 0 },
- { { ".debug_weaknames", NULL, 0, 0 },
+ { { ".debug_weaknames", ".zdebug_weaknames", NULL, NULL, 0, 0 },
display_debug_not_supported, 0, 0 }
};