summaryrefslogtreecommitdiffstats
path: root/binutils-2.25/binutils/dwarf.c
diff options
context:
space:
mode:
Diffstat (limited to 'binutils-2.25/binutils/dwarf.c')
-rw-r--r--binutils-2.25/binutils/dwarf.c926
1 files changed, 676 insertions, 250 deletions
diff --git a/binutils-2.25/binutils/dwarf.c b/binutils-2.25/binutils/dwarf.c
index 84e628a2..4777baba 100644
--- a/binutils-2.25/binutils/dwarf.c
+++ b/binutils-2.25/binutils/dwarf.c
@@ -365,6 +365,9 @@ typedef struct State_Machine_Registers
unsigned int file;
unsigned int line;
unsigned int column;
+ unsigned int discriminator;
+ unsigned int context;
+ unsigned int subprogram;
int is_stmt;
int basic_block;
unsigned char op_index;
@@ -384,19 +387,65 @@ reset_state_machine (int is_stmt)
state_machine_regs.file = 1;
state_machine_regs.line = 1;
state_machine_regs.column = 0;
+ state_machine_regs.discriminator = 0;
+ state_machine_regs.context = 0;
+ state_machine_regs.subprogram = 0;
state_machine_regs.is_stmt = is_stmt;
state_machine_regs.basic_block = 0;
state_machine_regs.end_sequence = 0;
state_machine_regs.last_file_entry = 0;
}
+/* Build a logicals table for reference when reading the actuals table. */
+
+static SMR *logicals_table = NULL;
+static unsigned int logicals_allocated = 0;
+static unsigned int logicals_count = 0;
+
+static void
+free_logicals (void)
+{
+ free (logicals_table);
+ logicals_allocated = 0;
+ logicals_count = 0;
+ logicals_table = NULL;
+}
+
+static void
+append_logical (void)
+{
+ if (logicals_allocated == 0)
+ {
+ logicals_allocated = 4;
+ logicals_table = (SMR *) xmalloc (logicals_allocated * sizeof (SMR));
+ }
+ if (logicals_count >= logicals_allocated)
+ {
+ logicals_allocated *= 2;
+ logicals_table = (SMR *)
+ xrealloc (logicals_table, logicals_allocated * sizeof (SMR));
+ }
+ logicals_table[logicals_count++] = state_machine_regs;
+ printf (_("\t\tLogical %u: 0x%s[%u] file %u line %u discrim %u context %u subprog %u is_stmt %d\n"),
+ logicals_count,
+ dwarf_vmatoa ("x", state_machine_regs.address),
+ state_machine_regs.op_index,
+ state_machine_regs.file,
+ state_machine_regs.line,
+ state_machine_regs.discriminator,
+ state_machine_regs.context,
+ state_machine_regs.subprogram,
+ state_machine_regs.is_stmt);
+}
+
/* Handled an extend line op.
Returns the number of bytes read. */
static int
process_extended_line_op (unsigned char * data,
int is_stmt,
- unsigned char * end)
+ unsigned char * end,
+ int is_logical)
{
unsigned char op_code;
unsigned int bytes_read;
@@ -423,6 +472,8 @@ process_extended_line_op (unsigned char * data,
{
case DW_LNE_end_sequence:
printf (_("End of Sequence\n\n"));
+ if (is_logical)
+ append_logical ();
reset_state_machine (is_stmt);
break;
@@ -453,8 +504,14 @@ process_extended_line_op (unsigned char * data,
break;
case DW_LNE_set_discriminator:
- printf (_("set Discriminator to %s\n"),
- dwarf_vmatoa ("u", read_uleb128 (data, & bytes_read, end)));
+ {
+ unsigned int discrim;
+
+ discrim = read_uleb128 (data, & bytes_read, end);
+ data += bytes_read;
+ printf (_("set Discriminator to %u\n"), discrim);
+ state_machine_regs.discriminator = discrim;
+ }
break;
/* HP extensions. */
@@ -567,7 +624,7 @@ fetch_indirect_string (dwarf_vma offset)
if (section->start == NULL)
return (const unsigned char *) _("<no .debug_str section>");
- if (offset > section->size)
+ if (offset >= section->size)
{
warn (_("DW_FORM_strp offset too big: %s\n"),
dwarf_vmatoa ("x", offset));
@@ -577,6 +634,24 @@ fetch_indirect_string (dwarf_vma offset)
return (const unsigned char *) section->start + offset;
}
+static const unsigned char *
+fetch_indirect_line_string (dwarf_vma offset)
+{
+ struct dwarf_section *section = &debug_displays [line_str].section;
+
+ if (section->start == NULL)
+ return (const unsigned char *) _("<no .debug_line_str section>");
+
+ if (offset >= section->size)
+ {
+ warn (_("DW_FORM_line_strp offset too big: %s\n"),
+ dwarf_vmatoa ("x", offset));
+ return (const unsigned char *) _("<offset is too big>");
+ }
+
+ return (const unsigned char *) section->start + offset;
+}
+
static const char *
fetch_indexed_string (dwarf_vma idx, struct cu_tu_set *this_set,
dwarf_vma offset_size, int dwo)
@@ -594,7 +669,7 @@ fetch_indexed_string (dwarf_vma idx, struct cu_tu_set *this_set,
if (this_set != NULL)
index_offset += this_set->section_offsets [DW_SECT_STR_OFFSETS];
- if (index_offset > index_section->size)
+ if (index_offset + offset_size > index_section->size)
{
warn (_("DW_FORM_GNU_str_index offset too big: %s\n"),
dwarf_vmatoa ("x", index_offset));
@@ -607,7 +682,7 @@ fetch_indexed_string (dwarf_vma idx, struct cu_tu_set *this_set,
str_offset = byte_get (index_section->start + index_offset, offset_size);
str_offset -= str_section->address;
- if (str_offset > str_section->size)
+ if (str_offset >= str_section->size)
{
warn (_("DW_FORM_GNU_str_index indirect offset too big: %s\n"),
dwarf_vmatoa ("x", str_offset));
@@ -2616,6 +2691,10 @@ load_debug_info (void * file)
return 0;
}
+/* Experimental DWARF 5 extensions.
+ See http://wiki.dwarfstd.org/index.php?title=TwoLevelLineTables. */
+#define DWARF2_LINE_EXPERIMENTAL_VERSION 0xf006
+
/* Read a DWARF .debug_line section header starting at DATA.
Upon success returns an updated DATA pointer and the LINFO
structure and the END_OF_SEQUENCE pointer will be filled in.
@@ -2626,7 +2705,9 @@ read_debug_line_header (struct dwarf_section * section,
unsigned char * data,
unsigned char * end,
DWARF2_Internal_LineInfo * linfo,
- unsigned char ** end_of_sequence)
+ unsigned char ** end_of_sequence,
+ unsigned int * pinitial_length_size,
+ unsigned int * poffset_size)
{
unsigned char *hdrptr;
unsigned int offset_size;
@@ -2651,6 +2732,8 @@ read_debug_line_header (struct dwarf_section * section,
offset_size = 4;
initial_length_size = 4;
}
+ *pinitial_length_size = initial_length_size;
+ *poffset_size = offset_size;
if (linfo->li_length + initial_length_size > section->size)
{
@@ -2673,15 +2756,30 @@ read_debug_line_header (struct dwarf_section * section,
/* Get and check the version number. */
SAFE_BYTE_GET_AND_INC (linfo->li_version, hdrptr, 2, end);
+ /* Version 0xf006 is for experimental two-level line tables. */
if (linfo->li_version != 2
&& linfo->li_version != 3
- && linfo->li_version != 4)
+ && linfo->li_version != 4
+ && linfo->li_version != 5
+ && linfo->li_version != DWARF2_LINE_EXPERIMENTAL_VERSION)
{
- warn (_("Only DWARF version 2, 3 and 4 line info is currently supported.\n"));
+ warn (_("Only DWARF versions 2-5 line info are currently supported.\n"));
return NULL;
}
+ if (linfo->li_version < 5)
+ {
+ linfo->li_address_size = 0;
+ linfo->li_segment_size = 0;
+ }
+ else if (linfo->li_version != DWARF2_LINE_EXPERIMENTAL_VERSION)
+ {
+ SAFE_BYTE_GET_AND_INC (linfo->li_address_size, hdrptr, 1, end);
+ SAFE_BYTE_GET_AND_INC (linfo->li_segment_size, hdrptr, 1, end);
+ }
+
SAFE_BYTE_GET_AND_INC (linfo->li_prologue_length, hdrptr, offset_size, end);
+
SAFE_BYTE_GET_AND_INC (linfo->li_min_insn_length, hdrptr, 1, end);
if (linfo->li_version >= 4)
@@ -2706,12 +2804,473 @@ read_debug_line_header (struct dwarf_section * section,
return hdrptr;
}
+static void
+display_directory_table_v4 (unsigned char *start, unsigned char *end,
+ unsigned char **pdata)
+{
+ unsigned char *data = *pdata;
+ unsigned int last_dir_entry = 0;
+
+ if (*data == 0)
+ printf (_("\n The Directory Table is empty.\n"));
+ else
+ {
+ printf (_("\n The Directory Table (offset 0x%lx):\n"),
+ (long)(data - start));
+
+ while (data < end && *data != 0)
+ {
+ printf (" %d\t%.*s\n", ++last_dir_entry, (int) (end - data), data);
+
+ data += strnlen ((char *) data, end - data) + 1;
+ }
+ }
+
+ /* Skip the NUL at the end of the table. */
+ *pdata = data + 1;
+}
+
+static void
+display_file_name_table_v4 (unsigned char *start, unsigned char *end,
+ unsigned char **pdata)
+{
+ unsigned char *data = *pdata;
+
+ if (*data == 0)
+ printf (_("\n The File Name Table is empty.\n"));
+ else
+ {
+ printf (_("\n The File Name Table (offset 0x%lx):\n"),
+ (long)(data - start));
+ printf (_(" Entry\tDir\tTime\tSize\tName\n"));
+
+ while (data < end && *data != 0)
+ {
+ unsigned char *name;
+ unsigned int bytes_read;
+
+ printf (" %d\t", ++state_machine_regs.last_file_entry);
+ name = data;
+ data += strnlen ((char *) data, end - data) + 1;
+
+ printf ("%s\t",
+ dwarf_vmatoa ("u", read_uleb128 (data, & bytes_read, end)));
+ data += bytes_read;
+ printf ("%s\t",
+ dwarf_vmatoa ("u", read_uleb128 (data, & bytes_read, end)));
+ data += bytes_read;
+ printf ("%s\t",
+ dwarf_vmatoa ("u", read_uleb128 (data, & bytes_read, end)));
+ data += bytes_read;
+ printf ("%.*s\n", (int)(end - name), name);
+
+ if (data == end)
+ {
+ warn (_("Corrupt file name table entry\n"));
+ break;
+ }
+ }
+ }
+
+ /* Skip the NUL at the end of the table. */
+ *pdata = data + 1;
+}
+
+static int
+display_dir_file_table_v5 (unsigned char *start, unsigned char *end,
+ unsigned char **pdata, char *table_name,
+ unsigned int offset_size)
+{
+ unsigned char *data = *pdata;
+ unsigned int bytes_read;
+ unsigned int format_count;
+ unsigned int *content_types;
+ unsigned int *content_forms;
+ unsigned int entry_count;
+ unsigned int i, j;
+ const unsigned char *name;
+ dwarf_vma offset;
+ unsigned int val;
+
+ format_count = read_uleb128 (data, & bytes_read, end);
+ data += bytes_read;
+ content_types = (unsigned int *) xmalloc (format_count *
+ sizeof (unsigned int));
+ content_forms = (unsigned int *) xmalloc (format_count *
+ sizeof (unsigned int));
+ for (j = 0; j < format_count; j++)
+ {
+ content_types[j] = read_uleb128 (data, & bytes_read, end);
+ data += bytes_read;
+ content_forms[j] = read_uleb128 (data, & bytes_read, end);
+ data += bytes_read;
+ }
+
+ entry_count = read_uleb128 (data, & bytes_read, end);
+ data += bytes_read;
+
+ if (entry_count == 0)
+ printf (_("\n The %s Table is empty.\n"), table_name);
+ else
+ {
+ printf (_("\n The %s Table (offset 0x%lx):\n"),
+ table_name, (long)(data - start));
+
+ printf (_(" Entry"));
+ for (j = 0; j < format_count; j++)
+ {
+ printf ("\t");
+ switch (content_types[j])
+ {
+ case DW_LNCT_path:
+ printf (_("Path"));
+ break;
+ case DW_LNCT_subprogram_name:
+ printf (_("Name"));
+ break;
+ case DW_LNCT_directory_index:
+ printf (_("Dir"));
+ break;
+ case DW_LNCT_decl_file:
+ printf (_("File"));
+ break;
+ case DW_LNCT_decl_line:
+ printf (_("Line"));
+ break;
+ }
+ }
+ printf ("\n");
+ }
+
+ for (i = 0; i < entry_count; i++)
+ {
+ printf (" %d", i + 1);
+ for (j = 0; j < format_count; j++)
+ {
+ if (data >= end)
+ break;
+ switch (content_forms[j])
+ {
+ case DW_FORM_string:
+ printf ("\t%.*s", (int) (end - data), data);
+ data += strnlen ((char *) data, end - data) + 1;
+ break;
+ case DW_FORM_line_strp:
+ SAFE_BYTE_GET_AND_INC (offset, data, offset_size, end);
+ name = fetch_indirect_line_string (offset);
+ printf ("\t%s", name);
+ break;
+ case DW_FORM_udata:
+ val = read_uleb128 (data, & bytes_read, end);
+ data += bytes_read;
+ printf ("\t%u", val);
+ break;
+ default:
+ printf ("\t%s", _("(unrecognized FORM code)"));
+ data = end;
+ break;
+ }
+ }
+ printf ("\n");
+
+ /* PR 17512: file: 002-132094-0.004. */
+ if (data >= end - 1)
+ break;
+ }
+
+ free (content_types);
+ free (content_forms);
+
+ *pdata = data;
+ return entry_count;
+}
+
+static void
+display_line_program (unsigned char *start, unsigned char *end,
+ unsigned char **pdata, char *table_name,
+ DWARF2_Internal_LineInfo *linfo,
+ unsigned char *standard_opcodes,
+ int is_logical)
+{
+ unsigned char *data = *pdata;
+
+ if (data >= end)
+ {
+ printf (_(" No %s.\n"), table_name);
+ return;
+ }
+
+ printf (" %s:\n", table_name);
+
+ while (data < end)
+ {
+ unsigned char op_code;
+ dwarf_signed_vma adv;
+ dwarf_vma uladv;
+ unsigned int bytes_read;
+ unsigned int logical;
+ int i;
+
+ printf (" [0x%08lx]", (long)(data - start));
+
+ op_code = *data++;
+
+ if (op_code >= linfo->li_opcode_base)
+ {
+ op_code -= linfo->li_opcode_base;
+ uladv = (op_code / linfo->li_line_range);
+ if (linfo->li_max_ops_per_insn == 1)
+ {
+ uladv *= linfo->li_min_insn_length;
+ state_machine_regs.address += uladv;
+ 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.address
+ += ((state_machine_regs.op_index + uladv)
+ / linfo->li_max_ops_per_insn)
+ * linfo->li_min_insn_length;
+ state_machine_regs.op_index
+ = (state_machine_regs.op_index + uladv)
+ % linfo->li_max_ops_per_insn;
+ 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 %s to %d\n"),
+ dwarf_vmatoa ("d", adv), state_machine_regs.line);
+ if (is_logical)
+ append_logical ();
+ state_machine_regs.discriminator = 0;
+ }
+ else
+ {
+ switch (op_code)
+ {
+ case DW_LNS_extended_op:
+ data += process_extended_line_op (data, linfo->li_default_is_stmt,
+ end, is_logical);
+ break;
+
+ case DW_LNS_copy:
+ printf (_(" Copy\n"));
+ if (is_logical)
+ append_logical ();
+ state_machine_regs.discriminator = 0;
+ break;
+
+ case DW_LNS_advance_pc:
+ uladv = read_uleb128 (data, & bytes_read, end);
+ data += bytes_read;
+ if (linfo->li_max_ops_per_insn == 1)
+ {
+ uladv *= linfo->li_min_insn_length;
+ state_machine_regs.address += uladv;
+ printf (_(" Advance PC by %s to 0x%s\n"),
+ dwarf_vmatoa ("u", uladv),
+ dwarf_vmatoa ("x", state_machine_regs.address));
+ }
+ else
+ {
+ state_machine_regs.address
+ += ((state_machine_regs.op_index + uladv)
+ / linfo->li_max_ops_per_insn)
+ * linfo->li_min_insn_length;
+ state_machine_regs.op_index
+ = (state_machine_regs.op_index + uladv)
+ % linfo->li_max_ops_per_insn;
+ 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_sleb128 (data, & bytes_read, end);
+ data += bytes_read;
+ state_machine_regs.line += adv;
+ printf (_(" Advance Line by %s to %d\n"),
+ dwarf_vmatoa ("d", adv),
+ state_machine_regs.line);
+ break;
+
+ case DW_LNS_set_file:
+ adv = read_uleb128 (data, & bytes_read, end);
+ data += bytes_read;
+ 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_uleb128 (data, & bytes_read, end);
+ data += bytes_read;
+ 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 %s\n"), dwarf_vmatoa ("d", adv));
+ state_machine_regs.is_stmt = adv;
+ break;
+
+ case DW_LNS_set_basic_block:
+ printf (_(" Set basic block\n"));
+ state_machine_regs.basic_block = 1;
+ break;
+
+ case DW_LNS_const_add_pc:
+ uladv = ((255 - linfo->li_opcode_base) / linfo->li_line_range);
+ if (linfo->li_max_ops_per_insn)
+ {
+ uladv *= linfo->li_min_insn_length;
+ state_machine_regs.address += uladv;
+ 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.address
+ += ((state_machine_regs.op_index + uladv)
+ / linfo->li_max_ops_per_insn)
+ * linfo->li_min_insn_length;
+ state_machine_regs.op_index
+ = (state_machine_regs.op_index + uladv)
+ % linfo->li_max_ops_per_insn;
+ 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;
+
+ case DW_LNS_fixed_advance_pc:
+ SAFE_BYTE_GET_AND_INC (uladv, data, 2, end);
+ state_machine_regs.address += uladv;
+ state_machine_regs.op_index = 0;
+ printf (_(" Advance PC by fixed size amount %s to 0x%s\n"),
+ dwarf_vmatoa ("u", uladv),
+ dwarf_vmatoa ("x", state_machine_regs.address));
+ break;
+
+ case DW_LNS_set_prologue_end:
+ printf (_(" Set prologue_end to true\n"));
+ break;
+
+ case DW_LNS_set_epilogue_begin:
+ printf (_(" Set epilogue_begin to true\n"));
+ break;
+
+ case DW_LNS_set_isa:
+ uladv = read_uleb128 (data, & bytes_read, end);
+ data += bytes_read;
+ printf (_(" Set ISA to %s\n"), dwarf_vmatoa ("u", uladv));
+ break;
+
+ case DW_LNS_set_subprogram:
+ /* This opcode is aliased with: */
+ /* case DW_LNS_set_address_from_logical: */
+ if (is_logical)
+ {
+ /* DW_LNS_set_subprogram */
+ state_machine_regs.context = 0;
+ state_machine_regs.subprogram = read_uleb128 (data, & bytes_read, end);
+ data += bytes_read;
+ printf (_(" Set subprogram to %u and reset context to 0\n"),
+ state_machine_regs.subprogram);
+ }
+ else
+ {
+ /* DW_LNS_set_address_from_logical */
+ adv = read_sleb128 (data, & bytes_read, end);
+ data += bytes_read;
+ state_machine_regs.line += adv;
+ logical = state_machine_regs.line;
+ if (logical - 1 < logicals_count)
+ {
+ state_machine_regs.address = logicals_table[logical - 1].address;
+ state_machine_regs.op_index = logicals_table[logical - 1].op_index;
+ }
+ else
+ warn (_("Logical row number outside range of logicals table\n"));
+ printf (_(" Advance Line by %s to %u and set address from logical to 0x%s[%u]\n"),
+ dwarf_vmatoa ("d", adv),
+ logical,
+ dwarf_vmatoa ("x", state_machine_regs.address),
+ state_machine_regs.op_index);
+ }
+ break;
+
+ case DW_LNS_inlined_call:
+ adv = read_sleb128 (data, & bytes_read, end);
+ data += bytes_read;
+ state_machine_regs.context = logicals_count + adv;
+ state_machine_regs.subprogram = read_uleb128 (data, & bytes_read, end);
+ data += bytes_read;
+ printf (_(" Set context to %u and subprogram to %u\n"),
+ state_machine_regs.context,
+ state_machine_regs.subprogram);
+ break;
+
+ case DW_LNS_pop_context:
+ logical = state_machine_regs.context;
+ printf (_(" Pop context to logical %u\n"), logical);
+ if (logical - 1 < logicals_count)
+ {
+ state_machine_regs.file = logicals_table[logical - 1].file;
+ state_machine_regs.line = logicals_table[logical - 1].line;
+ state_machine_regs.column = logicals_table[logical - 1].column;
+ state_machine_regs.discriminator = logicals_table[logical - 1].discriminator;
+ state_machine_regs.is_stmt = logicals_table[logical - 1].is_stmt;
+ state_machine_regs.context = logicals_table[logical - 1].context;
+ state_machine_regs.subprogram = logicals_table[logical - 1].subprogram;
+ }
+ else
+ warn (_("Context register outside range of logicals table\n"));
+ break;
+
+ default:
+ printf (_(" Unknown opcode %d with operands: "), op_code);
+
+ if (standard_opcodes != NULL)
+ for (i = standard_opcodes[op_code - 1]; i > 0 ; --i)
+ {
+ printf ("0x%s%s", dwarf_vmatoa ("x", read_uleb128 (data,
+ &bytes_read, end)),
+ i == 1 ? "" : ", ");
+ data += bytes_read;
+ }
+ putchar ('\n');
+ break;
+ }
+ }
+ }
+
+ putchar ('\n');
+ *pdata = data;
+}
+
static int
display_debug_lines_raw (struct dwarf_section *section,
unsigned char *data,
unsigned char *end)
{
unsigned char *start = section->start;
+ unsigned int initial_length_size;
+ unsigned int offset_size;
printf (_("Raw dump of debug contents of section %s:\n\n"),
section->name);
@@ -2720,10 +3279,15 @@ display_debug_lines_raw (struct dwarf_section *section,
{
static DWARF2_Internal_LineInfo saved_linfo;
DWARF2_Internal_LineInfo linfo;
+ unsigned int logicals_table_offset = 0;
+ unsigned int actuals_table_offset = 0;
+ unsigned char *end_of_header_length;
unsigned char *standard_opcodes;
+ unsigned char *start_of_line_program;
+ unsigned char *end_of_logicals;
unsigned char *end_of_sequence;
- unsigned int last_dir_entry = 0;
int i;
+ unsigned char *hdrptr = NULL;
if (const_strneq (section->name, ".debug_line.")
/* Note: the following does not apply to .debug_line.dwo sections.
@@ -2740,22 +3304,30 @@ display_debug_lines_raw (struct dwarf_section *section,
Since the section is a fragment it does not have the details
needed to fill out a LineInfo structure, so instead we use the
details from the last full debug_line section that we processed. */
+ start_of_line_program = data;
end_of_sequence = end;
+ end_of_logicals = end;
standard_opcodes = NULL;
linfo = saved_linfo;
reset_state_machine (linfo.li_default_is_stmt);
}
else
{
- unsigned char * hdrptr;
-
if ((hdrptr = read_debug_line_header (section, data, end, & linfo,
- & end_of_sequence)) == NULL)
+ & end_of_sequence,
+ & initial_length_size,
+ & offset_size)) == NULL)
return 0;
printf (_(" Offset: 0x%lx\n"), (long)(data - start));
printf (_(" Length: %ld\n"), (long) linfo.li_length);
printf (_(" DWARF Version: %d\n"), linfo.li_version);
+ if (linfo.li_version >= 5
+ && linfo.li_version != DWARF2_LINE_EXPERIMENTAL_VERSION)
+ {
+ printf (_(" Address Size: %u\n"), linfo.li_address_size);
+ printf (_(" Segment Size: %u\n"), linfo.li_segment_size);
+ }
printf (_(" Prologue Length: %d\n"), linfo.li_prologue_length);
printf (_(" Minimum Instruction Length: %d\n"), linfo.li_min_insn_length);
if (linfo.li_version >= 4)
@@ -2765,6 +3337,13 @@ display_debug_lines_raw (struct dwarf_section *section,
printf (_(" Line Range: %d\n"), linfo.li_line_range);
printf (_(" Opcode Base: %d\n"), linfo.li_opcode_base);
+ end_of_header_length = data + initial_length_size + 2 + offset_size;
+ if (linfo.li_version >= 5
+ && linfo.li_version != DWARF2_LINE_EXPERIMENTAL_VERSION)
+ end_of_header_length += 2;
+ start_of_line_program = end_of_header_length + linfo.li_prologue_length;
+ end_of_logicals = end;
+
reset_state_machine (linfo.li_default_is_stmt);
/* Display the contents of the Opcodes table. */
@@ -2775,261 +3354,100 @@ display_debug_lines_raw (struct dwarf_section *section,
for (i = 1; i < linfo.li_opcode_base; i++)
printf (_(" Opcode %d has %d args\n"), i, standard_opcodes[i - 1]);
- /* Display the contents of the Directory table. */
data = standard_opcodes + linfo.li_opcode_base - 1;
- if (*data == 0)
- printf (_("\n The Directory Table is empty.\n"));
- else
+ if (linfo.li_version == DWARF2_LINE_EXPERIMENTAL_VERSION)
{
- printf (_("\n The Directory Table (offset 0x%lx):\n"),
- (long)(data - start));
+ /* Skip the fake directory and filename table. */
+ data += 2;
- while (*data != 0)
- {
- printf (" %d\t%s\n", ++last_dir_entry, data);
+ /* Skip the fake extended opcode that wraps the rest
+ of the section. */
+ data += 5;
- data += strnlen ((char *) data, end - data) + 1;
- }
- }
+ /* Read the logicals table offset and actuals table offset. */
+ SAFE_BYTE_GET_AND_INC (logicals_table_offset, data, offset_size, end);
+ SAFE_BYTE_GET_AND_INC (actuals_table_offset, data, offset_size, end);
- /* Skip the NUL at the end of the table. */
- data++;
+ start_of_line_program = end_of_header_length + logicals_table_offset;
- /* Display the contents of the File Name table. */
- if (*data == 0)
- printf (_("\n The File Name Table is empty.\n"));
- else
- {
- printf (_("\n The File Name Table (offset 0x%lx):\n"),
- (long)(data - start));
- printf (_(" Entry\tDir\tTime\tSize\tName\n"));
+ if (actuals_table_offset > 0)
+ end_of_logicals = end_of_header_length + actuals_table_offset;
- while (*data != 0)
- {
- unsigned char *name;
- unsigned int bytes_read;
+ putchar ('\n');
+ printf (_(" Logicals Table Offset: 0x%x\n"), logicals_table_offset);
+ printf (_(" Actuals Table Offset: 0x%x\n"), actuals_table_offset);
+ }
- printf (" %d\t", ++state_machine_regs.last_file_entry);
- name = data;
- data += strnlen ((char *) data, end - data) + 1;
+ /* Display the contents of the Directory table. */
+ if (linfo.li_version >= 5)
+ display_dir_file_table_v5 (start, end, &data, _("Directory"),
+ offset_size);
+ else
+ display_directory_table_v4 (start, end, &data);
- printf ("%s\t",
- dwarf_vmatoa ("u", read_uleb128 (data, & bytes_read, end)));
- data += bytes_read;
- printf ("%s\t",
- dwarf_vmatoa ("u", read_uleb128 (data, & bytes_read, end)));
- data += bytes_read;
- printf ("%s\t",
- dwarf_vmatoa ("u", read_uleb128 (data, & bytes_read, end)));
- data += bytes_read;
- printf ("%s\n", name);
+ /* PR 17512: file: 002-132094-0.004. */
+ if (data >= end - 1)
+ break;
- if (data == end)
- {
- warn (_("Corrupt file name table entry\n"));
- break;
- }
- }
+ /* Display the contents of the File Name table. */
+ if (linfo.li_version >= 5)
+ {
+ unsigned int count;
+
+ count = display_dir_file_table_v5 (start, end, &data,
+ _("File Name"), offset_size);
+ state_machine_regs.last_file_entry = count - 1;
}
+ else
+ display_file_name_table_v4 (start, end, &data);
+
+ /* Display the contents of the Subprogram table. */
+ if (linfo.li_version == DWARF2_LINE_EXPERIMENTAL_VERSION)
+ display_dir_file_table_v5 (start, end, &data, _("Subprogram"),
+ offset_size);
- /* Skip the NUL at the end of the table. */
- data++;
putchar ('\n');
saved_linfo = linfo;
}
- /* Now display the statements. */
- if (data >= end_of_sequence)
- printf (_(" No Line Number Statements.\n"));
- else
- {
- printf (_(" Line Number Statements:\n"));
+ if (data > start_of_line_program)
+ warn (_("Line table header is longer than header_length indicates\n"));
+ else if (data < start_of_line_program)
+ warn (_("Line table header is shorter than header_length indicates\n"));
+ data = start_of_line_program;
- while (data < end_of_sequence)
+ if (linfo.li_version == DWARF2_LINE_EXPERIMENTAL_VERSION
+ && hdrptr != NULL
+ && actuals_table_offset > 0)
+ {
+ if (end_of_logicals > end)
{
- unsigned char op_code;
- dwarf_signed_vma adv;
- dwarf_vma uladv;
- unsigned int bytes_read;
-
- printf (" [0x%08lx]", (long)(data - start));
-
- op_code = *data++;
-
- if (op_code >= linfo.li_opcode_base)
- {
- op_code -= linfo.li_opcode_base;
- uladv = (op_code / linfo.li_line_range);
- if (linfo.li_max_ops_per_insn == 1)
- {
- uladv *= linfo.li_min_insn_length;
- state_machine_regs.address += uladv;
- 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.address
- += ((state_machine_regs.op_index + uladv)
- / linfo.li_max_ops_per_insn)
- * linfo.li_min_insn_length;
- state_machine_regs.op_index
- = (state_machine_regs.op_index + uladv)
- % linfo.li_max_ops_per_insn;
- 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 %s to %d\n"),
- dwarf_vmatoa ("d", adv), state_machine_regs.line);
- }
- else switch (op_code)
- {
- case DW_LNS_extended_op:
- data += process_extended_line_op (data, linfo.li_default_is_stmt, end);
- break;
-
- case DW_LNS_copy:
- printf (_(" Copy\n"));
- break;
-
- case DW_LNS_advance_pc:
- uladv = read_uleb128 (data, & bytes_read, end);
- data += bytes_read;
- if (linfo.li_max_ops_per_insn == 1)
- {
- uladv *= linfo.li_min_insn_length;
- state_machine_regs.address += uladv;
- printf (_(" Advance PC by %s to 0x%s\n"),
- dwarf_vmatoa ("u", uladv),
- dwarf_vmatoa ("x", state_machine_regs.address));
- }
- else
- {
- state_machine_regs.address
- += ((state_machine_regs.op_index + uladv)
- / linfo.li_max_ops_per_insn)
- * linfo.li_min_insn_length;
- state_machine_regs.op_index
- = (state_machine_regs.op_index + uladv)
- % linfo.li_max_ops_per_insn;
- 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_sleb128 (data, & bytes_read, end);
- data += bytes_read;
- state_machine_regs.line += adv;
- printf (_(" Advance Line by %s to %d\n"),
- dwarf_vmatoa ("d", adv),
- state_machine_regs.line);
- break;
-
- case DW_LNS_set_file:
- adv = read_uleb128 (data, & bytes_read, end);
- data += bytes_read;
- 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_uleb128 (data, & bytes_read, end);
- data += bytes_read;
- 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 %s\n"), dwarf_vmatoa ("d", adv));
- state_machine_regs.is_stmt = adv;
- break;
-
- case DW_LNS_set_basic_block:
- printf (_(" Set basic block\n"));
- state_machine_regs.basic_block = 1;
- break;
-
- case DW_LNS_const_add_pc:
- uladv = ((255 - linfo.li_opcode_base) / linfo.li_line_range);
- if (linfo.li_max_ops_per_insn)
- {
- uladv *= linfo.li_min_insn_length;
- state_machine_regs.address += uladv;
- 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.address
- += ((state_machine_regs.op_index + uladv)
- / linfo.li_max_ops_per_insn)
- * linfo.li_min_insn_length;
- state_machine_regs.op_index
- = (state_machine_regs.op_index + uladv)
- % linfo.li_max_ops_per_insn;
- 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;
-
- case DW_LNS_fixed_advance_pc:
- SAFE_BYTE_GET_AND_INC (uladv, data, 2, end);
- state_machine_regs.address += uladv;
- state_machine_regs.op_index = 0;
- printf (_(" Advance PC by fixed size amount %s to 0x%s\n"),
- dwarf_vmatoa ("u", uladv),
- dwarf_vmatoa ("x", state_machine_regs.address));
- break;
-
- case DW_LNS_set_prologue_end:
- printf (_(" Set prologue_end to true\n"));
- break;
-
- case DW_LNS_set_epilogue_begin:
- printf (_(" Set epilogue_begin to true\n"));
- break;
-
- case DW_LNS_set_isa:
- uladv = read_uleb128 (data, & bytes_read, end);
- data += bytes_read;
- printf (_(" Set ISA to %s\n"), dwarf_vmatoa ("u", uladv));
- break;
-
- default:
- printf (_(" Unknown opcode %d with operands: "), op_code);
-
- if (standard_opcodes != NULL)
- for (i = standard_opcodes[op_code - 1]; i > 0 ; --i)
- {
- printf ("0x%s%s", dwarf_vmatoa ("x", read_uleb128 (data,
- &bytes_read, end)),
- i == 1 ? "" : ", ");
- data += bytes_read;
- }
- putchar ('\n');
- break;
- }
+ warn (_("Actuals table offset %s extends beyond end of section\n"),
+ dwarf_vmatoa ("u", actuals_table_offset));
+ end_of_logicals = end;
}
- putchar ('\n');
- }
+ display_line_program (start, end_of_logicals, &data,
+ _("Logicals Statements"),
+ &linfo, standard_opcodes, 1);
+ if (data > end_of_logicals)
+ warn (_("Logicals table is longer than actuals_table_offset indicates\n"));
+ else if (data < end_of_logicals)
+ warn (_("Line table header is shorter than actuals_table_offset indicates\n"));
+ data = end_of_logicals;
+ reset_state_machine (linfo.li_default_is_stmt);
+ display_line_program (start, end_of_sequence, &data,
+ _("Actuals Statements"),
+ &linfo, standard_opcodes, 0);
+ free_logicals ();
+ }
+ else
+ {
+ display_line_program (start, end_of_sequence, &data,
+ _("Line Number Statements"),
+ &linfo, standard_opcodes, 0);
+ }
+
}
return 1;
@@ -3051,6 +3469,8 @@ display_debug_lines_decoded (struct dwarf_section *section,
unsigned char *end)
{
static DWARF2_Internal_LineInfo saved_linfo;
+ unsigned int initial_length_size;
+ unsigned int offset_size;
printf (_("Decoded dump of debug contents of section %s:\n\n"),
section->name);
@@ -3083,7 +3503,9 @@ display_debug_lines_decoded (struct dwarf_section *section,
unsigned char *hdrptr;
if ((hdrptr = read_debug_line_header (section, data, end, & linfo,
- & end_of_sequence)) == NULL)
+ & end_of_sequence,
+ & initial_length_size,
+ & offset_size)) == NULL)
return 0;
reset_state_machine (linfo.li_default_is_stmt);
@@ -3501,7 +3923,7 @@ display_debug_lines_decoded (struct dwarf_section *section,
}
static int
-display_debug_lines (struct dwarf_section *section, void *file ATTRIBUTE_UNUSED)
+display_debug_lines (struct dwarf_section *section, void *file)
{
unsigned char *data = section->start;
unsigned char *end = data + section->size;
@@ -3511,6 +3933,8 @@ display_debug_lines (struct dwarf_section *section, void *file ATTRIBUTE_UNUSED)
if (do_debug_lines == 0)
do_debug_lines |= FLAG_DEBUG_LINES_RAW;
+ load_debug_section (line_str, file);
+
if (do_debug_lines & FLAG_DEBUG_LINES_RAW)
retValRaw = display_debug_lines_raw (section, data, end);
@@ -7045,6 +7469,8 @@ struct dwarf_section_display debug_displays[] =
display_debug_macro, &do_debug_macinfo, 1 },
{ { ".debug_str", ".zdebug_str", NULL, NULL, 0, 0, 0 },
display_debug_str, &do_debug_str, 0 },
+ { { ".debug_line_str", ".zdebug_line_str", NULL, NULL, 0, 0, 0 },
+ display_debug_str, &do_debug_str, 0 },
{ { ".debug_loc", ".zdebug_loc", NULL, NULL, 0, 0, 0 },
display_debug_loc, &do_debug_loc, 1 },
{ { ".debug_pubtypes", ".zdebug_pubtypes", NULL, NULL, 0, 0, 0 },