+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
 
 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}}
 
                 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
   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.  */
       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))
 
 #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\):
 
--- /dev/null
+#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
 
--- /dev/null
+       .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
 
-#as: --gdwarf-3
-#name: DWARF5 .line 0
+#as: --gdwarf-5
+#name: DWARF5 .file 0 (no directory)
 #readelf: -wl
 
 #...
 
     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