From f9402ccaa9fac7858713a7672fae5760ae3d5ce7 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Mon, 15 Nov 2021 12:50:51 +0100 Subject: [PATCH] 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. --- gas/ChangeLog | 13 +++ gas/doc/as.texi | 17 ++-- gas/dwarf2dbg.c | 44 +++++++--- gas/testsuite/gas/elf/dwarf-5-file0-2.d | 3 +- gas/testsuite/gas/elf/dwarf-5-file0-3.d | 15 ++++ gas/testsuite/gas/elf/dwarf-5-file0-3.s | 111 ++++++++++++++++++++++++ gas/testsuite/gas/elf/dwarf-5-file0.d | 4 +- gas/testsuite/gas/elf/elf.exp | 1 + 8 files changed, 184 insertions(+), 24 deletions(-) create mode 100644 gas/testsuite/gas/elf/dwarf-5-file0-3.d create mode 100644 gas/testsuite/gas/elf/dwarf-5-file0-3.s diff --git a/gas/ChangeLog b/gas/ChangeLog index 1133847e820..e9761e9a901 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,16 @@ +2021-11-15 Eric Botcazou + + * 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 PR 28436 diff --git a/gas/doc/as.texi b/gas/doc/as.texi index 0cc7455d3ae..9c1924d4bbd 100644 --- a/gas/doc/as.texi +++ b/gas/doc/as.texi @@ -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}} diff --git a/gas/dwarf2dbg.c b/gas/dwarf2dbg.c index c6e439aa862..256412f9c79 100644 --- a/gas/dwarf2dbg.c +++ b/gas/dwarf2dbg.c @@ -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)) diff --git a/gas/testsuite/gas/elf/dwarf-5-file0-2.d b/gas/testsuite/gas/elf/dwarf-5-file0-2.d index 4b3ed29f4c9..dfd8431a505 100644 --- a/gas/testsuite/gas/elf/dwarf-5-file0-2.d +++ b/gas/testsuite/gas/elf/dwarf-5-file0-2.d @@ -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\): diff --git a/gas/testsuite/gas/elf/dwarf-5-file0-3.d b/gas/testsuite/gas/elf/dwarf-5-file0-3.d new file mode 100644 index 00000000000..6c55d3266aa --- /dev/null +++ b/gas/testsuite/gas/elf/dwarf-5-file0-3.d @@ -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 diff --git a/gas/testsuite/gas/elf/dwarf-5-file0-3.s b/gas/testsuite/gas/elf/dwarf-5-file0-3.s new file mode 100644 index 00000000000..b33c3645088 --- /dev/null +++ b/gas/testsuite/gas/elf/dwarf-5-file0-3.s @@ -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 diff --git a/gas/testsuite/gas/elf/dwarf-5-file0.d b/gas/testsuite/gas/elf/dwarf-5-file0.d index f60411c8034..2502b80d1f9 100644 --- a/gas/testsuite/gas/elf/dwarf-5-file0.d +++ b/gas/testsuite/gas/elf/dwarf-5-file0.d @@ -1,5 +1,5 @@ -#as: --gdwarf-3 -#name: DWARF5 .line 0 +#as: --gdwarf-5 +#name: DWARF5 .file 0 (no directory) #readelf: -wl #... diff --git a/gas/testsuite/gas/elf/elf.exp b/gas/testsuite/gas/elf/elf.exp index 16b9b565614..08105f88419 100644 --- a/gas/testsuite/gas/elf/elf.exp +++ b/gas/testsuite/gas/elf/elf.exp @@ -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 -- 2.30.2