Deal with full path in .file 0 directive

Gas uses the directory part, if present, of the .file 0 directive to set
entry 0 of the directory table in DWARF 5, which represents the "current
directory".

Now Gas also uses the file part of the same directive to set entry 0 of the
file table, which represents the "current compilation file".  But the latter
need not be located in the former so GCC will use a full path in the file
part when it is passed a full path:

gcc -c /full/path/test.c -save-temps

yields:

 .file 0 "/current/directory" "/full/path/test.c"

in the assembly file and:

 The Directory Table (offset 0x22, lines 2, columns 1):
  Entry Name
  0     (indirect line string, offset: 0x25): /current/directory
  1     (indirect line string, offset: 0x38): /full/path

 The File Name Table (offset 0x30, lines 2, columns 2):
  Entry Dir     Name
  0     0       (indirect line string, offset: 0x43): /full/path/test.c

in the object file.  Note the full path and the questionable Dir value in
the 0 entry of the file table.
This commit is contained in:
Eric Botcazou 2021-11-15 12:50:51 +01:00
parent e6c46d0772
commit f9402ccaa9
8 changed files with 184 additions and 24 deletions

View File

@ -1,3 +1,16 @@
2021-11-15 Eric Botcazou <ebotcazou@adacore.com>
* doc/as.texi (File): Update description of .file 0 directive.
* dwarf2dbg.c (get_directory_table_entry): Remove obsolete comment
and pass file0_dirname in recursive call.
(allocate_filename_to_slot): Deal with a full path in the file name
if the index number is 0.
* testsuite/gas/elf/dwarf-5-file0.d: Fix pasto.
* testsuite/gas/elf/dwarf-5-file0-2.d: Likewise.
* testsuite/gas/elf/dwarf-5-file0-3.d: New file.
* testsuite/gas/elf/dwarf-5-file0-3.s: Likewise.
* testsuite/gas/elf/elf.exp: Run dwarf-5-file0-3.
2021-10-28 Markus Klein <markus.klein@sma.de>
PR 28436

View File

@ -5416,19 +5416,22 @@ table is shared with the @code{.debug_info} section of the DWARF2 debugging
information, and thus the user must know the exact indices that table
entries will have.
If DWARF-5 support has been enabled via the @option{-gdwarf-5} option then
an extended version of the @code{file} is also allowed:
If DWARF5 support has been enabled via the @option{-gdwarf-5} option then
an extended version of @code{.file} is also allowed:
@smallexample
.file @var{fileno} [@var{dirname}] @var{filename} [md5 @var{value}]
@end smallexample
With this version a separate directory name is allowed, although if this is
used then @var{filename} should not contain any directory components. In
addtion an md5 hash value of the contents of @var{filename} can be provided.
This will be stored in the the file table as well, and can be used by tools
reading the debug information to verify that the contents of the source file
match the contents of the compiled file.
used then @var{filename} should not contain any directory component, except
for @var{fileno} equal to 0: in this case, @var{dirname} is expected to be
the current directory and @var{filename} the currently processed file, and
the latter need not be located in the former. In addtion an MD5 hash value
of the contents of @var{filename} can be provided. This will be stored in
the the file table as well, and can be used by tools reading the debug
information to verify that the contents of the source file match the
contents of the compiled file.
@node Fill
@section @code{.fill @var{repeat} , @var{size} , @var{value}}

View File

@ -641,11 +641,9 @@ get_directory_table_entry (const char *dirname,
expected to be the same as the DW_AT_comp_dir (which
is set to the current build directory). Since we are
about to create a directory entry that is not the
same, allocate the current directory first.
FIXME: Alternatively we could generate an error
message here. */
(void) get_directory_table_entry (pwd, NULL, strlen (pwd),
true);
same, allocate the current directory first. */
(void) get_directory_table_entry (pwd, file0_dirname,
strlen (pwd), true);
d = 1;
}
else
@ -827,7 +825,7 @@ allocate_filename_to_slot (const char *dirname,
const char *file;
size_t dirlen;
unsigned int i, d;
const char *file0_dirname = dirname;
const char *file0_dirname;
/* Short circuit the common case of adding the same pathname
as last time. */
@ -906,20 +904,40 @@ allocate_filename_to_slot (const char *dirname,
return false;
}
if (dirname == NULL)
/* For file .0, the directory name is the current directory and the file
may be in another directory contained in the file name. */
if (num == 0)
{
dirname = filename;
file0_dirname = dirname;
file = get_basename (filename);
dirlen = file - filename;
if (dirname && file == filename)
dirlen = strlen (dirname);
else
{
dirname = filename;
dirlen = file - filename;
}
}
else
{
dirlen = strlen (dirname);
file = filename;
file0_dirname = NULL;
if (dirname == NULL)
{
dirname = filename;
file = get_basename (filename);
dirlen = file - filename;
}
else
{
dirlen = strlen (dirname);
file = filename;
}
}
d = get_directory_table_entry (dirname, file0_dirname, dirlen,
num == 0);
d = get_directory_table_entry (dirname, file0_dirname, dirlen, num == 0);
i = num;
if (! assign_file_to_slot (i, file, d))

View File

@ -1,11 +1,10 @@
#as: --gdwarf-5
#name: DWARF5 .file 0 dir file
#name: DWARF5 .file 0 (directory and relative file)
#readelf: -wl
#...
The Directory Table \(offset 0x.*, lines 1, columns 1\):
Entry Name
#...
0 \(indirect line string, offset: 0x.*\): /example
The File Name Table \(offset 0x.*, lines 2, columns 2\):

View File

@ -0,0 +1,15 @@
#as: --gdwarf-5
#name: DWARF5 .file 0 (directory and absolute file)
#readelf: -wl
#...
The Directory Table \(offset 0x.*, lines 2, columns 1\):
Entry Name
0 \(indirect line string, offset: 0x.*\): /current/directory
1 \(indirect line string, offset: 0x.*\): /full/path
The File Name Table \(offset 0x.*, lines 2, columns 2\):
Entry Dir Name
0 1 \(indirect line string, offset: 0x.*\): test.c
1 1 \(indirect line string, offset: 0x.*\): test.c
#pass

View File

@ -0,0 +1,111 @@
.file "test.c"
.text
.Ltext0:
.file 0 "/current/directory" "/full/path/test.c"
.globl x
.section .bss
.balign 4
.type x, %object
.size x, 4
x:
.zero 4
.text
.Letext0:
.file 1 "/full/path/test.c"
.section .debug_info,"",%progbits
.Ldebug_info0:
.4byte 0x32
.2byte 0x5
.byte 0x1
.byte 0x4
.4byte .Ldebug_abbrev0
.uleb128 0x1
.4byte .LASF2
.byte 0x1d
.4byte .LASF0
.4byte .LASF1
.4byte .Ldebug_line0
.uleb128 0x2
.asciz "x"
.byte 0x1
.byte 0x1
.byte 0x5
.4byte 0x2e
.uleb128 0x5
.byte 0x3
.4byte x
.uleb128 0x3
.byte 0x4
.byte 0x5
.asciz "int"
.byte 0
.section .debug_abbrev,"",%progbits
.Ldebug_abbrev0:
.uleb128 0x1
.uleb128 0x11
.byte 0x1
.uleb128 0x25
.uleb128 0xe
.uleb128 0x13
.uleb128 0xb
.uleb128 0x3
.uleb128 0x1f
.uleb128 0x1b
.uleb128 0x1f
.uleb128 0x10
.uleb128 0x17
.byte 0
.byte 0
.uleb128 0x2
.uleb128 0x34
.byte 0
.uleb128 0x3
.uleb128 0x8
.uleb128 0x3a
.uleb128 0xb
.uleb128 0x3b
.uleb128 0xb
.uleb128 0x39
.uleb128 0xb
.uleb128 0x49
.uleb128 0x13
.uleb128 0x3f
.uleb128 0x19
.uleb128 0x2
.uleb128 0x18
.byte 0
.byte 0
.uleb128 0x3
.uleb128 0x24
.byte 0
.uleb128 0xb
.uleb128 0xb
.uleb128 0x3e
.uleb128 0xb
.uleb128 0x3
.uleb128 0x8
.byte 0
.byte 0
.byte 0
.section .debug_aranges,"",%progbits
.4byte 0x14
.2byte 0x2
.4byte .Ldebug_info0
.byte 0x4
.byte 0
.2byte 0
.2byte 0
.4byte 0
.4byte 0
.section .debug_line,"",%progbits
.Ldebug_line0:
.section .debug_str,"MS",%progbits,1
.LASF2:
.asciz "GNU C17 11.2.1 -g"
.section .debug_line_str,"MS",%progbits,1
.LASF1:
.asciz "/working/directory"
.LASF0:
.asciz "/full/path/test.c"
.ident "GCC: (GNU) 11.2.1"
.section .note.GNU-stack,"",%progbits

View File

@ -1,5 +1,5 @@
#as: --gdwarf-3
#name: DWARF5 .line 0
#as: --gdwarf-5
#name: DWARF5 .file 0 (no directory)
#readelf: -wl
#...

View File

@ -300,6 +300,7 @@ if { [is_elf_format] } then {
run_dump_test "dwarf2-21" $dump_opts
run_dump_test "dwarf-5-file0" $dump_opts
run_dump_test "dwarf-5-file0-2" $dump_opts
run_dump_test "dwarf-5-file0-3" $dump_opts
run_dump_test "dwarf-5-dir0" $dump_opts
run_dump_test "dwarf-5-loc0" $dump_opts
run_dump_test "dwarf-4-cu" $dump_opts