Add support for generating DWARF-5 format directory and file name tables from the assembler.

PR 25611
	PR 25614
	* dwarf.h (DWARF2_Internal_LineInfo): Add li_address_size and
	li_segment_size fields.
	* dwarf.c (read_debug_line_header): Record the address size and
	segment selector size values (if present) in the lineinfo
	structure.
	(display_formatted_table): Warn if the format count is empty but
	the table itself is not empty.
	Display the format count and entry count at the start of the table
	dump.
	(display_debug_lines_raw): Display the address size and segement
	selector size fields, if present.
	* testsuite/binutils-all/dw5.W: Update expected output.

gas	* dwarf2dbg.c (DWARF2_FILE_TIME_NAME): Default to -1.
	(DWARF2_FILE_SIZE_NAME): Default to -1.
	(DWARF2_LINE_VERSION): Default to the current dwarf level or 3,
	whichever is higher.
	(DWARF2_LINE_MAX_OPS_PER_INSN): Provide a default value of 1.
	(NUM_MD5_BYTES): Define.
	(struct file entry): Add md5 field.
	(get_filenum): Delete and replace with...
	(get_basename): New function.
	(get_directory_table_entry): New function.
	(allocate_filenum): New function.
	(allocate_filename_to_slot): New function.
	(dwarf2_where): Use new functions.
	(dwarf2_directive_filename): Add support for extended .file
	pseudo-op.
	(dwarf2_directive_loc): Allow the use of file number zero with
	DWARF 5 or higher.
	(out_file_list): Rename to...
	(out_dir_and_file_list): Add DWARF 5 support.
	(out_debug_line): Emit extra values into the section header for
	DWARF 5.
	(out_debug_str): Allow for file 0 to be used with DWARF 5.
	* doc/as.texi (.file): Update the description of this pseudo-op.
	* testsuite/gas/elf-dwarf-5-file0.s: Add more lines.
	* testsuite/gas/elf-dwarf-5-file0.d: Update expected dump output.
	* testsuite/gas/lns/lns-diag-1.l: Update expected error message.
	* NEWS: Mention the new feature.
This commit is contained in:
Nick Clifton
2020-03-11 10:17:14 +00:00
parent b76f3a4237
commit 5496f3c635
11 changed files with 672 additions and 196 deletions

View File

@@ -1,3 +1,20 @@
2020-03-11 Nick Clifton <nickc@redhat.com>
PR 25611
PR 25614
* dwarf.h (DWARF2_Internal_LineInfo): Add li_address_size and
li_segment_size fields.
* dwarf.c (read_debug_line_header): Record the address size and
segment selector size values (if present) in the lineinfo
structure.
(display_formatted_table): Warn if the format count is empty but
the table itself is not empty.
Display the format count and entry count at the start of the table
dump.
(display_debug_lines_raw): Display the address size and segement
selector size fields, if present.
* testsuite/binutils-all/dw5.W: Update expected output.
2020-03-11 Alan Modra <amodra@gmail.com>
PR 25651

View File

@@ -3622,7 +3622,6 @@ read_debug_line_header (struct dwarf_section * section,
{
unsigned char *hdrptr;
unsigned int initial_length_size;
unsigned char address_size, segment_selector_size;
/* Extract information from the Line Number Program Header.
(section 6.2.4 in the Dwarf3 doc). */
@@ -3679,15 +3678,15 @@ read_debug_line_header (struct dwarf_section * section,
if (linfo->li_version >= 5)
{
SAFE_BYTE_GET_AND_INC (address_size, hdrptr, 1, end);
SAFE_BYTE_GET_AND_INC (linfo->li_address_size, hdrptr, 1, end);
SAFE_BYTE_GET_AND_INC (segment_selector_size, hdrptr, 1, end);
if (segment_selector_size != 0)
SAFE_BYTE_GET_AND_INC (linfo->li_segment_size, hdrptr, 1, end);
if (linfo->li_segment_size != 0)
{
warn (_("The %s section contains "
"unsupported segment selector size: %d.\n"),
section->name, segment_selector_size);
return 0;
section->name, linfo->li_segment_size);
return NULL;
}
}
@@ -3737,7 +3736,8 @@ display_formatted_table (unsigned char * data,
unsigned char *format_start, format_count, *format, formati;
dwarf_vma data_count, datai;
unsigned int namepass, last_entry = 0;
const char * table_name = is_dir ? N_("Directory Table") : N_("File Name Table");
SAFE_BYTE_GET_AND_INC (format_count, data, 1, end);
format_start = data;
for (formati = 0; formati < format_count; formati++)
@@ -3746,10 +3746,7 @@ display_formatted_table (unsigned char * data,
SKIP_ULEB (data, end);
if (data == end)
{
if (is_dir)
warn (_("Corrupt directory format table entry\n"));
else
warn (_("Corrupt file name format table entry\n"));
warn (_("%s: Corrupt format description entry\n"), table_name);
return data;
}
}
@@ -3757,28 +3754,25 @@ display_formatted_table (unsigned char * data,
READ_ULEB (data_count, data, end);
if (data == end)
{
if (is_dir)
warn (_("Corrupt directory list\n"));
else
warn (_("Corrupt file name list\n"));
warn (_("%s: Corrupt entry count\n"), table_name);
return data;
}
if (data_count == 0)
{
if (is_dir)
printf (_("\n The Directory Table is empty.\n"));
else
printf (_("\n The File Name Table is empty.\n"));
printf (_("\n The %s is empty.\n"), table_name);
return data;
}
else if (format_count == 0)
{
warn (_("%s: format count is zero, but the table is not empty\n"),
table_name);
return end;
}
if (is_dir)
printf (_("\n The Directory Table (offset 0x%lx):\n"),
(long) (data - start));
else
printf (_("\n The File Name Table (offset 0x%lx):\n"),
(long) (data - start));
printf (_("\n The %s (offset 0x%lx, lines %s, columns %u):\n"),
table_name, (long) (data - start), dwarf_vmatoa ("u", data_count),
format_count);
printf (_(" Entry"));
/* Delay displaying name as the last entry for better screen layout. */
@@ -3806,7 +3800,7 @@ display_formatted_table (unsigned char * data,
printf (_("\tSize"));
break;
case DW_LNCT_MD5:
printf (_("\tMD5"));
printf (_("\tMD5\t\t\t"));
break;
default:
printf (_("\t(Unknown format content type %s)"),
@@ -3840,12 +3834,10 @@ display_formatted_table (unsigned char * data,
section, NULL, '\t', -1);
}
}
if (data == end)
if (data == end && (datai < data_count - 1))
{
if (is_dir)
warn (_("Corrupt directory entries list\n"));
else
warn (_("Corrupt file name entries list\n"));
warn (_("\n%s: Corrupt entries list\n"), table_name);
return data;
}
putchar ('\n');
@@ -3909,6 +3901,11 @@ display_debug_lines_raw (struct dwarf_section * section,
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)
{
printf (_(" Address size (bytes): %d\n"), linfo.li_address_size);
printf (_(" Segment selector (bytes): %d\n"), linfo.li_segment_size);
}
printf (_(" Prologue Length: %d\n"), (int) linfo.li_prologue_length);
printf (_(" Minimum Instruction Length: %d\n"), linfo.li_min_insn_length);
if (linfo.li_version >= 4)

View File

@@ -29,6 +29,8 @@ typedef struct
{
dwarf_vma li_length;
unsigned short li_version;
unsigned char li_address_size;
unsigned char li_segment_size;
dwarf_vma li_prologue_length;
unsigned char li_min_insn_length;
unsigned char li_max_ops_per_insn;

View File

@@ -291,6 +291,8 @@ Raw dump of debug contents of section .debug_line:
Offset: 0x0
Length: 144
DWARF Version: 5
Address size \(bytes\): 8
Segment selector \(bytes\): 0
Prologue Length: 60
Minimum Instruction Length: 1
Maximum Ops per Instruction: 1
@@ -313,13 +315,13 @@ Raw dump of debug contents of section .debug_line:
Opcode 11 has 0 args
Opcode 12 has 1 arg
The Directory Table \(offset 0x22\):
The Directory Table \(offset 0x22, lines 3, columns 1\):
Entry Name
0 \(indirect line string, offset: 0x0\):
1 \(indirect line string, offset: 0x1\):
2 \(indirect line string, offset: 0x22\): /usr/include
The File Name Table \(offset 0x34\):
The File Name Table \(offset 0x34, lines 4, columns 2\):
Entry Dir Name
0 0 \(indirect line string, offset: 0x14\): main.c
1 1 \(indirect line string, offset: 0x1b\): main.c