* dwarf.c (display_debug_lines): Rename to
display_debug_lines_raw. (display_debug_lines_decoded): New function. Displays the interpreted contents of a .debug_line section. (display_debug_lines): New function: Selects either a raw dump or a decoded dump (or both) as requested by the user. * dwarf.h (do_debug_lines_decoded): New extern. * readelf.c: Add support for -wL or --debug-dump=decodedline option to display the decoded contents of a .debug_line section. * doc/binutils.texi: Document the new option. * NEWS: Mention the new feature.
This commit is contained in:
parent
5bcb0e6433
commit
a262ae964e
|
@ -1,3 +1,17 @@
|
||||||
|
2008-04-11 Torleif Sandnes <torleif.sandnes@gmail.com>
|
||||||
|
|
||||||
|
* dwarf.c (display_debug_lines): Rename to
|
||||||
|
display_debug_lines_raw.
|
||||||
|
(display_debug_lines_decoded): New function. Displays the
|
||||||
|
interpreted contents of a .debug_line section.
|
||||||
|
(display_debug_lines): New function: Selects either a raw dump or
|
||||||
|
a decoded dump (or both) as requested by the user.
|
||||||
|
* dwarf.h (do_debug_lines_decoded): New extern.
|
||||||
|
* readelf.c: Add support for -wL or --debug-dump=decodedline
|
||||||
|
option to display the decoded contents of a .debug_line section.
|
||||||
|
* doc/binutils.texi: Document the new option.
|
||||||
|
* NEWS: Mention the new feature.
|
||||||
|
|
||||||
2008-04-08 Alan Modra <amodra@bigpond.net.au>
|
2008-04-08 Alan Modra <amodra@bigpond.net.au>
|
||||||
|
|
||||||
* dwarf.c: Remove trailing whitespace throughout file.
|
* dwarf.c: Remove trailing whitespace throughout file.
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
-*- text -*-
|
-*- text -*-
|
||||||
|
* Added -wL switch to dump decoded contents of .debug_line.
|
||||||
|
|
||||||
* Added support for "thin" archives which contain pathnames pointing to
|
* Added support for "thin" archives which contain pathnames pointing to
|
||||||
object files rather than the files themselves and which contain a
|
object files rather than the files themselves and which contain a
|
||||||
flattened symbol index for all objects, and archives, which have been
|
flattened symbol index for all objects, and archives, which have been
|
||||||
|
|
|
@ -3705,8 +3705,8 @@ readelf [@option{-a}|@option{--all}]
|
||||||
[@option{-x} <number or name>|@option{--hex-dump=}<number or name>]
|
[@option{-x} <number or name>|@option{--hex-dump=}<number or name>]
|
||||||
[@option{-p} <number or name>|@option{--string-dump=}<number or name>]
|
[@option{-p} <number or name>|@option{--string-dump=}<number or name>]
|
||||||
[@option{-c}|@option{--archive-index}]
|
[@option{-c}|@option{--archive-index}]
|
||||||
[@option{-w[liaprmfFsoR]}|
|
[@option{-w[lLiaprmfFsoR]}|
|
||||||
@option{--debug-dump}[=line,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges]]
|
@option{--debug-dump}[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges]]
|
||||||
[@option{-I}|@option{-histogram}]
|
[@option{-I}|@option{-histogram}]
|
||||||
[@option{-v}|@option{--version}]
|
[@option{-v}|@option{--version}]
|
||||||
[@option{-W}|@option{--wide}]
|
[@option{-W}|@option{--wide}]
|
||||||
|
@ -3843,12 +3843,16 @@ Displays the file symbol index infomation contained in the header part
|
||||||
of binary archives. Performs the same function as the @option{t}
|
of binary archives. Performs the same function as the @option{t}
|
||||||
command to @command{ar}, but without using the BFD library. @xref{ar}.
|
command to @command{ar}, but without using the BFD library. @xref{ar}.
|
||||||
|
|
||||||
@item -w[liaprmfFsoR]
|
@item -w[lLiaprmfFsoR]
|
||||||
@itemx --debug-dump[=line,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges]
|
@itemx --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges]
|
||||||
Displays the contents of the debug sections in the file, if any are
|
Displays the contents of the debug sections in the file, if any are
|
||||||
present. If one of the optional letters or words follows the switch
|
present. If one of the optional letters or words follows the switch
|
||||||
then only data found in those specific sections will be dumped.
|
then only data found in those specific sections will be dumped.
|
||||||
|
|
||||||
|
Note: the @option{=decodedline} option will display the interpreted
|
||||||
|
contents of a .debug_line section whereas the @option{=rawline} option
|
||||||
|
dumps the contents in a raw format.
|
||||||
|
|
||||||
@item -I
|
@item -I
|
||||||
@itemx --histogram
|
@itemx --histogram
|
||||||
Display a histogram of bucket list lengths when displaying the contents
|
Display a histogram of bucket list lengths when displaying the contents
|
||||||
|
|
456
binutils/dwarf.c
456
binutils/dwarf.c
|
@ -44,6 +44,7 @@ int eh_addr_size;
|
||||||
int do_debug_info;
|
int do_debug_info;
|
||||||
int do_debug_abbrevs;
|
int do_debug_abbrevs;
|
||||||
int do_debug_lines;
|
int do_debug_lines;
|
||||||
|
int do_debug_lines_decoded;
|
||||||
int do_debug_pubnames;
|
int do_debug_pubnames;
|
||||||
int do_debug_aranges;
|
int do_debug_aranges;
|
||||||
int do_debug_ranges;
|
int do_debug_ranges;
|
||||||
|
@ -52,6 +53,7 @@ int do_debug_frames_interp;
|
||||||
int do_debug_macinfo;
|
int do_debug_macinfo;
|
||||||
int do_debug_str;
|
int do_debug_str;
|
||||||
int do_debug_loc;
|
int do_debug_loc;
|
||||||
|
int do_wide;
|
||||||
|
|
||||||
dwarf_vma (*byte_get) (unsigned char *, int);
|
dwarf_vma (*byte_get) (unsigned char *, int);
|
||||||
|
|
||||||
|
@ -2051,21 +2053,14 @@ load_debug_info (void * file)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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 *start = section->start;
|
||||||
unsigned char *data = start;
|
|
||||||
unsigned char *end = start + section->size;
|
|
||||||
|
|
||||||
printf (_("\nDump of debug contents of section %s:\n\n"),
|
printf (_("Raw dump of debug contents of section %s:\n\n"),
|
||||||
section->name);
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (data < end)
|
while (data < end)
|
||||||
{
|
{
|
||||||
|
@ -2332,6 +2327,443 @@ display_debug_lines (struct dwarf_section *section, void *file)
|
||||||
return 1;
|
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 *
|
static debug_info *
|
||||||
find_debug_info_for_offset (unsigned long offset)
|
find_debug_info_for_offset (unsigned long offset)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* dwwrf.h - DWARF support header file
|
/* dwwrf.h - DWARF support header file
|
||||||
Copyright 2005, 2007
|
Copyright 2005, 2007, 2008
|
||||||
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is part of GNU Binutils.
|
This file is part of GNU Binutils.
|
||||||
|
@ -96,6 +96,7 @@ extern int eh_addr_size;
|
||||||
extern int do_debug_info;
|
extern int do_debug_info;
|
||||||
extern int do_debug_abbrevs;
|
extern int do_debug_abbrevs;
|
||||||
extern int do_debug_lines;
|
extern int do_debug_lines;
|
||||||
|
extern int do_debug_lines_decoded;
|
||||||
extern int do_debug_pubnames;
|
extern int do_debug_pubnames;
|
||||||
extern int do_debug_aranges;
|
extern int do_debug_aranges;
|
||||||
extern int do_debug_ranges;
|
extern int do_debug_ranges;
|
||||||
|
|
|
@ -161,6 +161,7 @@
|
||||||
#include "safe-ctype.h"
|
#include "safe-ctype.h"
|
||||||
|
|
||||||
char *program_name = "readelf";
|
char *program_name = "readelf";
|
||||||
|
int do_wide;
|
||||||
static long archive_file_offset;
|
static long archive_file_offset;
|
||||||
static unsigned long archive_file_size;
|
static unsigned long archive_file_size;
|
||||||
static unsigned long dynamic_addr;
|
static unsigned long dynamic_addr;
|
||||||
|
@ -197,7 +198,6 @@ static int do_using_dynamic;
|
||||||
static int do_header;
|
static int do_header;
|
||||||
static int do_dump;
|
static int do_dump;
|
||||||
static int do_version;
|
static int do_version;
|
||||||
static int do_wide;
|
|
||||||
static int do_histogram;
|
static int do_histogram;
|
||||||
static int do_debugging;
|
static int do_debugging;
|
||||||
static int do_arch;
|
static int do_arch;
|
||||||
|
@ -2880,8 +2880,8 @@ usage (FILE *stream)
|
||||||
Dump the contents of section <number|name> as bytes\n\
|
Dump the contents of section <number|name> as bytes\n\
|
||||||
-p --string-dump=<number|name>\n\
|
-p --string-dump=<number|name>\n\
|
||||||
Dump the contents of section <number|name> as strings\n\
|
Dump the contents of section <number|name> as strings\n\
|
||||||
-w[liaprmfFsoR] or\n\
|
-w[lLiaprmfFsoR] or\n\
|
||||||
--debug-dump[=line,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=str,=loc,=Ranges]\n\
|
--debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=str,=loc,=Ranges]\n\
|
||||||
Display the contents of DWARF2 debug sections\n"));
|
Display the contents of DWARF2 debug sections\n"));
|
||||||
#ifdef SUPPORT_DISASSEMBLY
|
#ifdef SUPPORT_DISASSEMBLY
|
||||||
fprintf (stream, _("\
|
fprintf (stream, _("\
|
||||||
|
@ -3083,6 +3083,10 @@ parse_args (int argc, char **argv)
|
||||||
do_debug_lines = 1;
|
do_debug_lines = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'L':
|
||||||
|
do_debug_lines_decoded = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'p':
|
case 'p':
|
||||||
do_debug_pubnames = 1;
|
do_debug_pubnames = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -3141,7 +3145,9 @@ parse_args (int argc, char **argv)
|
||||||
{ "frames", & do_debug_frames },
|
{ "frames", & do_debug_frames },
|
||||||
{ "frames-interp", & do_debug_frames_interp },
|
{ "frames-interp", & do_debug_frames_interp },
|
||||||
{ "info", & do_debug_info },
|
{ "info", & do_debug_info },
|
||||||
{ "line", & do_debug_lines },
|
{ "line", & do_debug_lines }, /* For backwards compatibility. */
|
||||||
|
{ "rawline", & do_debug_lines },
|
||||||
|
{ "decodedline", & do_debug_lines_decoded },
|
||||||
{ "loc", & do_debug_loc },
|
{ "loc", & do_debug_loc },
|
||||||
{ "macro", & do_debug_macinfo },
|
{ "macro", & do_debug_macinfo },
|
||||||
{ "pubnames", & do_debug_pubnames },
|
{ "pubnames", & do_debug_pubnames },
|
||||||
|
@ -4303,9 +4309,9 @@ process_section_headers (FILE *file)
|
||||||
else if (section->sh_type == SHT_RELA)
|
else if (section->sh_type == SHT_RELA)
|
||||||
CHECK_ENTSIZE (section, i, Rela);
|
CHECK_ENTSIZE (section, i, Rela);
|
||||||
else if ((do_debugging || do_debug_info || do_debug_abbrevs
|
else if ((do_debugging || do_debug_info || do_debug_abbrevs
|
||||||
|| do_debug_lines || do_debug_pubnames || do_debug_aranges
|
|| do_debug_lines || do_debug_lines_decoded || do_debug_pubnames
|
||||||
|| do_debug_frames || do_debug_macinfo || do_debug_str
|
|| do_debug_aranges || do_debug_frames || do_debug_macinfo
|
||||||
|| do_debug_loc || do_debug_ranges)
|
|| do_debug_str || do_debug_loc || do_debug_ranges)
|
||||||
&& const_strneq (name, ".debug_"))
|
&& const_strneq (name, ".debug_"))
|
||||||
{
|
{
|
||||||
name += 7;
|
name += 7;
|
||||||
|
@ -4313,7 +4319,8 @@ process_section_headers (FILE *file)
|
||||||
if (do_debugging
|
if (do_debugging
|
||||||
|| (do_debug_info && streq (name, "info"))
|
|| (do_debug_info && streq (name, "info"))
|
||||||
|| (do_debug_abbrevs && streq (name, "abbrev"))
|
|| (do_debug_abbrevs && streq (name, "abbrev"))
|
||||||
|| (do_debug_lines && streq (name, "line"))
|
|| ((do_debug_lines || do_debug_lines_decoded)
|
||||||
|
&& streq (name, "line"))
|
||||||
|| (do_debug_pubnames && streq (name, "pubnames"))
|
|| (do_debug_pubnames && streq (name, "pubnames"))
|
||||||
|| (do_debug_aranges && streq (name, "aranges"))
|
|| (do_debug_aranges && streq (name, "aranges"))
|
||||||
|| (do_debug_ranges && streq (name, "ranges"))
|
|| (do_debug_ranges && streq (name, "ranges"))
|
||||||
|
@ -4324,7 +4331,7 @@ process_section_headers (FILE *file)
|
||||||
)
|
)
|
||||||
request_dump_bynumber (i, DEBUG_DUMP);
|
request_dump_bynumber (i, DEBUG_DUMP);
|
||||||
}
|
}
|
||||||
/* linkonce section to be combined with .debug_info at link time. */
|
/* Linkonce section to be combined with .debug_info at link time. */
|
||||||
else if ((do_debugging || do_debug_info)
|
else if ((do_debugging || do_debug_info)
|
||||||
&& const_strneq (name, ".gnu.linkonce.wi."))
|
&& const_strneq (name, ".gnu.linkonce.wi."))
|
||||||
request_dump_bynumber (i, DEBUG_DUMP);
|
request_dump_bynumber (i, DEBUG_DUMP);
|
||||||
|
|
Loading…
Reference in New Issue