[Dwarf-Discuss] DWARF v5 and "file 0"

Omar Sandoval osandov@osandov.com
Thu Jul 8 22:12:20 GMT 2021

On Thu, Jul 08, 2021 at 07:23:14PM +0000, Paul Robinson via Dwarf-Discuss wrote:
> Tom Russell asked me about this, and I think it's a bug in the
> v5 specification.

Coincidentally, I just joined this list to ask about the same thing, as
I am currently implementing DWARF 5 support in my debugger.

> In v5, the line-table header's directory table added an entry for
> directory 0.  Previous versions had directory 0 mean the current
> compilation directory, i.e. DW_AT_comp_dir from the compile unit DIE.
> The file table also added an entry for file 0, claiming that it
> similarly used to mean the primary compilation file.  I can't find
> any evidence that was actually true, though; the default value for
> the line-number program's "file" register was (and still is) 1, not
> 0, and in fact section 2.14 says that DW_AT_decl_file = 0 means
> there is no source file (analogous to line 0 meaning no specific
> source line).
> If DW_AT_decl_file = 0 means "no source file" then the file table
> pretty much has to have two entries for the primary source file, 
> entry 0 to satisfy the line-table specification and another non-zero
> entry to satisfy the DW_AT_decl_file requirements.  That's wasteful.

FWIW, that seems to be what GCC does:

  $ cat foo/bar/baz.c
  int my_var = 1;
  $ gcc -g -gdwarf-5 -c foo/bar/baz.c -o gcc.o
  $ eu-readelf --debug-dump=line gcc.o
  Directory table:
   0     /home/osandov/test (33)
   1     foo/bar (52)
  File name table:
        [path(line_strp), directory_index(udata)]
   0     foo/bar/baz.c (60),  0
   1     baz.c (74),  1
  $ eu-readelf --debug-dump=info gcc.o
   [    1e]    variable             abbrev: 2
               name                 (strp) "my_var"
               decl_file            (data1) baz.c (1)
               decl_line            (data1) 1
               decl_column          (data1) 5
               type                 (ref4) [    34]
               external             (flag_present) yes
               location             (exprloc) 
                [ 0] addr .data+0 <my_var>

Versus Clang, which uses DW_AT_decl_file = 0:

  $ clang -g -gdwarf-5 -c foo/bar/baz.c -o clang.o
  $ eu-readelf --debug-dump=line clang.o
  Directory table:
   0     /home/osandov/test (0)
  File name table:
        [path(line_strp), directory_index(udata), MD5(data16)]
   0     foo/bar/baz.c (19),  0, b4 cb df ed f1 92 ab ec a4 0b b6 87 8f 7c 6e 43
  $ eu-readelf --debug-dump=info clang.o
   [    1e]    variable             abbrev: 2
               name                 (strx1) "my_var"
               type                 (ref4) [    29]
               external             (flag_present) yes
               decl_file            (data1) baz.c (0)
               decl_line            (data1) 1
               location             (exprloc)
                [ 0] addrx [0] .data+0 <my_var>

Notice that elfutils seems to interpret Clang's output as it was presumably
intended, as does GDB:

  $ gdb -batch clang.o -ex 'info variables'
  All defined variables:
  File foo/bar/baz.c:
  1:      int my_var;

My reading of the spec is that Clang is technically incorrect here, but
it seems like at least some consumers are forgiving.

> Am I missing something?  Happy to be wrong here, but it helps
> explain why it has been such a bear to get file 0 working properly
> in LLVM.

Tangentially related, I found a bug in Clang's file 0 generation when
using -no-integrated-as (which the Linux kernel uses when compiling with
Clang) that you may be interested in: https://reviews.llvm.org/D105662.

> If I'm not wrong I will file an issue to get this fixed in DWARF v6.
> Thanks,
> --paulr
> _______________________________________________
> Dwarf-Discuss mailing list
> Dwarf-Discuss at lists.dwarfstd.org
> http://lists.dwarfstd.org/listinfo.cgi/dwarf-discuss-dwarfstd.org

More information about the Dwarf-discuss mailing list