[patch] DwarfDebug problem with line section

Hi all,
While implementing debug info for our backend, we’ve noticed a problem with debug_line section. We believe that the following code is wrong:

// DW_AT_stmt_list is a offset of line number information for this
// compile unit in debug_line section. It is always zero when only one
// compile unit is emitted in one object file.
addUInt(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4, 0);

After compiling several files and linking them together (not only using our backend, but also x86) debug information was incorrect.
I’m not 100% sure if this fix is correct, but patch attached.

Artur

section_line_debug.patch (1.25 KB)

DW_AT_stmt_list attribute's value is a section offset to the line no
info for current compilation unit. If there is only one compilation
unit generated per .o file then it is always zero. What kind of errors
are you seeing ?

I updated DwarfDebug to use section offset, instead of hard coding 0,
to handle LTO properly.
r107202.

Thanks for brining this up.

Hi Devang,

Thanks for working on that. Unfortunately after your change it still doesn’t work (I’ve tried x86 and our backend under Linux).
The problem is that you put difference between two labels

.Lset7 = .Lsection_line_begin-.Lsection_line ## DW_AT_stmt_list

and that will be evaluated by assembler to a constant. It has to be a label, not a constant, because it is the linker who knows the correct offset.

Artur

Hi Devang,
Thanks for working on that. Unfortunately after your change it still doesn't
work (I've tried x86 and our backend under Linux).

What errors exactly you are seeing ?

The problem is that you put difference between two labels
.Lset7 = .Lsection_line_begin-.Lsection_line ## DW_AT_stmt_list
and that will be evaluated by assembler to a constant. It has to be a label,
not a constant, because it is the linker who knows the correct offset.

How will linker translate a label into correct offset ?

Sorry for reviving an old thread (I'm going through my 10000 message backlog from llvmdev), but it seems this hasn't been changed yet in the the mean time.

On ELF platforms (at least Linux and FreeBSD) and on Windows, both of the following are labels (i.e., absolute addresses to be relocated by the linker) as opposed to offsets relative to the relevant section's start, even though the DWARF standard says they are offsets:
* address of the abbreviation table
* DW_AT_stmt_list

At least that's what I learned when I looked at what GCC and GNU AS generated, and changing them into offsets (I tried that in our compiler) results in GDB not understanding the debug information.

Jonas

On ELF platforms (at least Linux and FreeBSD) and on Windows, both of
the following are labels (i.e., absolute addresses to be relocated by
the linker) as opposed to offsets relative to the relevant section’s
start, even though the DWARF standard says they are offsets:

  • address of the abbreviation table
  • DW_AT_stmt_list

As you say, dwarf standard says it is an offset.

  1. A DW_AT_stmt_list attribute whose value is a section offset to the line number information for this compilation unit.

This information is placed in a separate object file section from the debugging information entries themselves. The value of the statement list attribute is the offset in the .debug_line section of the first byte of the line number information for this compilation unit (see Section 6.2).

At least that’s what I learned when I looked at what GCC and GNU AS
generated, and changing them into offsets (I tried that in our
compiler) results in GDB not understanding the debug information.

AFAICT, GCC in darwin uses offset here. Using absolute address breaks debugger on darwin.

At least that's what I learned when I looked at what GCC and GNU AS
generated, and changing them into offsets (I tried that in our
compiler) results in GDB not understanding the debug information.

AFAICT, GCC in darwin uses offset here.

Indeed.

Using absolute address breaks
debugger on darwin.

Yes, I know. Our compiler has a target flag indicating whether a target requires offsets or absolute addresses for the address of the abbreviation table and the DW_AT_stmt_list. It's actually more complex than I wrote in my previous mail:

* Darwin uses a precomputed offset via the construct
.section __DWARF,__debug_info,regular,debug
        .long L$set$2
        .set L$set$2,Ldebug_abbrev0-Ldebug_abbrevsection0
       ...
        .long L$set$3
        .set L$set$3,Ldebug_line0-Ldebug_linesection0

* Windows uses a secrel32 symbol (so it's also relative):
.section .debug_info
      ...
        .secrel32 .Ldebug_abbrev0
      ...
        .secrel32 .Ldebug_line0

* Linux and FreeBSD use an absolute address:
.section .debug_info
      ...
        .long .Ldebug_abbrev0
      ...
        .long .Ldebug_line0

I don't know about other OSes.

Jonas