public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [patch] Deal with full path in .file 0 directive
@ 2021-11-06 11:55 Eric Botcazou
  0 siblings, 0 replies; only message in thread
From: Eric Botcazou @ 2021-11-06 11:55 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 2192 bytes --]

Hi,

after https://sourceware.org/pipermail/binutils/2021-September/117880.html, 
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.

The proposed change is to deal with a full path in the file part of the .file 
0 directive, so as to yield:

 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     1       (indirect line string, offset: 0x43): test.c

in the object file instead.  Tested on x86-64/Linux, OK for the trunk?


2021-11-06  Eric Botcazou  <ebotcazou@adacore.com>

gas/
	* 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.

-- 
Eric Botcazou

[-- Attachment #2: p.diff --]
[-- Type: text/x-patch, Size: 8097 bytes --]

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

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-11-06 11:58 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-06 11:55 [patch] Deal with full path in .file 0 directive Eric Botcazou

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).