So I've been successful with funneling

class X { public: X(int r) : res(r) {} int get() { return res; }
private: int res; };
int main() { X x(0); return x.get (); }

all the way through LTO and gdb recognizing all the nice early debug info
for X:

> gdb ./a.out
(gdb) start
Temporary breakpoint 1 at 0x400514: file t.C, line 2.
Starting program: /home/abuild/rguenther/obj-debug-early-g/gcc/a.out

Temporary breakpoint 1, main () at t.C:2
2       int main() { X x(0); return x.get (); }
(gdb) info locals
x = {res = -8560}
(gdb) ptype x
type = class X {
  private:
    int res;

  public:
    X(int);
    int get(void);
}

the late dwarf generation is a bit awkward because it insists on creating
type DIEs for all sort of contexts when we process scope vars.  The type
DIEs already exist, but only in early debug info.  I suspect we need to do
quite some dwarf2out refactoring to split early from late debug generation
in areas like that.  For the C++ example above we get some stray unused
type DIEs still.

So what is missing?  Missing is the driver side - currently you need to
re-link the executable with the compile-time object file:

> ./xg++ -B. -B ../x86_64-unknown-linux-gnu/libstdc++-v3/src/.libs t.C -g -dA 
> -flto -flto-partition=none -save-temps
/tmp/ccY1C3Bg.lto.o:(.debug_info+0x23): undefined reference to `t.C.14231d22'
/tmp/ccY1C3Bg.lto.o:(.debug_info+0x28): undefined reference to `t.C.14231d22'
/tmp/ccY1C3Bg.lto.o:(.debug_info+0x47): undefined reference to `t.C.14231d22'
/tmp/ccY1C3Bg.lto.o:(.debug_info+0x4f): undefined reference to `t.C.14231d22'
/tmp/ccY1C3Bg.lto.o:(.debug_info+0x58): undefined reference to `t.C.14231d22'
/tmp/ccY1C3Bg.lto.o:(.debug_info+0x77): more undefined references to
`t.C.14231d22' follow
collect2: error: ld returned 1 exit status
> ./as --64 -o /tmp/ccY1C3Bg.lto.o t.s
> ./xgcc -B. t.o /tmp/ccY1C3Bg.lto.o -fno-lto

that's for tomorrow to simplify.  I've attached the current patch
ontop of the branch as well
as a.out.

I'm now creating a sinlge CU DIE during LTRANS and import the early
generated CUs
there, re-parenting all generated code to the LTRANS CU DIE.  That
seems to work best
with current gdb.

For the above example the early generated DWARF part is

 <0><166>: Abbrev Number: 1 (DW_TAG_compile_unit)
    <167>   DW_AT_producer    : (indirect string, offset: 0x195): GNU C++ 5.0.0
20150316 (experimental) -mtune=generic -march=x86-64 -g -flto -flto-partition=no
ne
    <16b>   DW_AT_language    : 4       (C++)
    <16c>   DW_AT_name        : t.C
    <170>   DW_AT_comp_dir    : (indirect string, offset: 0x16d):
/abuild/rguenther/obj-debug-early-g/gcc
 <1><174>: Abbrev Number: 2 (DW_TAG_class_type)
    <175>   DW_AT_name        : X
    <177>   DW_AT_byte_size   : 4
    <178>   DW_AT_decl_file   : 1
    <179>   DW_AT_decl_line   : 1
    <17a>   DW_AT_sibling     : <0x1c2>
 <2><17e>: Abbrev Number: 3 (DW_TAG_member)
    <17f>   DW_AT_name        : res
    <183>   DW_AT_decl_file   : 1
    <184>   DW_AT_decl_line   : 1
    <185>   DW_AT_type        : <0x1c2>
    <189>   DW_AT_data_member_location: 0
 <2><18a>: Abbrev Number: 4 (DW_TAG_subprogram)
    <18b>   DW_AT_external    : 1
    <18b>   DW_AT_name        : X
    <18d>   DW_AT_decl_file   : 1
    <18e>   DW_AT_decl_line   : 1
    <18f>   DW_AT_linkage_name: (indirect string, offset: 0x163): _ZN1XC4Ei
    <193>   DW_AT_accessibility: 1      (public)
    <194>   DW_AT_declaration : 1
    <194>   DW_AT_object_pointer: <0x19c>
    <198>   DW_AT_sibling     : <0x1a7>
 <3><19c>: Abbrev Number: 5 (DW_TAG_formal_parameter)
    <19d>   DW_AT_type        : <0x1c9>
    <1a1>   DW_AT_artificial  : 1
 <3><1a1>: Abbrev Number: 6 (DW_TAG_formal_parameter)
    <1a2>   DW_AT_type        : <0x1c2>
 <3><1a6>: Abbrev Number: 0
 <2><1a7>: Abbrev Number: 7 (DW_TAG_subprogram)
    <1a8>   DW_AT_external    : 1
    <1a8>   DW_AT_name        : get
    <1ac>   DW_AT_decl_file   : 1
    <1ad>   DW_AT_decl_line   : 1
    <1ae>   DW_AT_linkage_name: (indirect string, offset: 0x200): _ZN1X3getEv
    <1b2>   DW_AT_type        : <0x1c2>
    <1b6>   DW_AT_accessibility: 1      (public)
    <1b7>   DW_AT_declaration : 1
    <1b7>   DW_AT_object_pointer: <0x1bb>
 <3><1bb>: Abbrev Number: 5 (DW_TAG_formal_parameter)
    <1bc>   DW_AT_type        : <0x1c9>
    <1c0>   DW_AT_artificial  : 1
 <3><1c0>: Abbrev Number: 0
 <2><1c1>: Abbrev Number: 0
 <1><1c2>: Abbrev Number: 8 (DW_TAG_base_type)
    <1c3>   DW_AT_byte_size   : 4
    <1c4>   DW_AT_encoding    : 5       (signed)
    <1c5>   DW_AT_name        : int
 <1><1c9>: Abbrev Number: 9 (DW_TAG_pointer_type)
    <1ca>   DW_AT_byte_size   : 8
    <1cb>   DW_AT_type        : <0x174>
 <1><1cf>: Abbrev Number: 10 (DW_TAG_subprogram)
    <1d0>   DW_AT_external    : 1
    <1d0>   DW_AT_name        : (indirect string, offset: 0x211): main
    <1d4>   DW_AT_decl_file   : 1
    <1d5>   DW_AT_decl_line   : 2
    <1d6>   DW_AT_type        : <0x1c2>
    <1da>   DW_AT_sibling     : <0x1e8>
 <2><1de>: Abbrev Number: 11 (DW_TAG_variable)
    <1df>   DW_AT_name        : x
    <1e1>   DW_AT_decl_file   : 1
    <1e2>   DW_AT_decl_line   : 2
    <1e3>   DW_AT_type        : <0x174>
 <2><1e7>: Abbrev Number: 0
 <1><1e8>: Abbrev Number: 12 (DW_TAG_subprogram)
    <1e9>   DW_AT_specification: <0x1a7>
    <1ed>   DW_AT_object_pointer: <0x1f5>
    <1f1>   DW_AT_sibling     : <0x1ff>
 <2><1f5>: Abbrev Number: 13 (DW_TAG_formal_parameter)
    <1f6>   DW_AT_name        : (indirect string, offset: 0x20c): this
    <1fa>   DW_AT_type        : <0x1ff>
    <1fe>   DW_AT_artificial  : 1
 <2><1fe>: Abbrev Number: 0
 <1><1ff>: Abbrev Number: 14 (DW_TAG_const_type)
    <200>   DW_AT_type        : <0x1c9>
 <1><204>: Abbrev Number: 15 (DW_TAG_subprogram)
    <205>   DW_AT_specification: <0x18a>
    <209>   DW_AT_inline      : 2       (declared as inline but ignored)
    <20a>   DW_AT_object_pointer: <0x212>
    <20e>   DW_AT_sibling     : <0x225>
 <2><212>: Abbrev Number: 13 (DW_TAG_formal_parameter)
    <213>   DW_AT_name        : (indirect string, offset: 0x20c): this
    <217>   DW_AT_type        : <0x1ff>
    <21b>   DW_AT_artificial  : 1
 <2><21b>: Abbrev Number: 16 (DW_TAG_formal_parameter)
    <21c>   DW_AT_name        : r
    <21e>   DW_AT_decl_file   : 1
    <21f>   DW_AT_decl_line   : 1
    <220>   DW_AT_type        : <0x1c2>
 <2><224>: Abbrev Number: 0
 <1><225>: Abbrev Number: 17 (DW_TAG_subprogram)
    <226>   DW_AT_abstract_origin: <0x204>
    <22a>   DW_AT_linkage_name: (indirect string, offset: 0x1f6): _ZN1XC2Ei
    <22e>   DW_AT_object_pointer: <0x232>
 <2><232>: Abbrev Number: 18 (DW_TAG_formal_parameter)
    <233>   DW_AT_abstract_origin: <0x212>
 <2><237>: Abbrev Number: 18 (DW_TAG_formal_parameter)
    <238>   DW_AT_abstract_origin: <0x21b>
 <2><23c>: Abbrev Number: 0
 <1><23d>: Abbrev Number: 0

while late during LTRANS we generate

 <0><249>: Abbrev Number: 1 (DW_TAG_compile_unit)
    <24a>   DW_AT_producer    :
    <24b>   DW_AT_language    : 4       (C++)
    <24c>   DW_AT_low_pc      : 0x4004e6
    <254>   DW_AT_high_pc     : 0x4d
    <25c>   DW_AT_stmt_list   : 0x10c
 <1><260>: Abbrev Number: 2 (DW_TAG_imported_unit)
    <261>   DW_AT_import      : <0x166> [Abbrev Number: 1]
 <1><265>: Abbrev Number: 3 (DW_TAG_subprogram)
    <266>   DW_AT_abstract_origin: <0x225>
    <26a>   DW_AT_low_pc      : 0x4004e6
    <272>   DW_AT_high_pc     : 0x16
    <27a>   DW_AT_frame_base  : 1 byte block: 9c        (DW_OP_call_frame_cfa)
    <27c>   DW_AT_object_pointer: <0x284>
    <280>   DW_AT_GNU_all_call_sites: 1
    <280>   DW_AT_sibling     : <0x295>
 <2><284>: Abbrev Number: 4 (DW_TAG_formal_parameter)
    <285>   DW_AT_abstract_origin: <0x232>
    <289>   DW_AT_artificial  : 1
    <289>   DW_AT_location    : 2 byte block: 91 68     (DW_OP_fbreg: -24)
 <2><28c>: Abbrev Number: 5 (DW_TAG_formal_parameter)
    <28d>   DW_AT_abstract_origin: <0x237>
    <291>   DW_AT_location    : 2 byte block: 91 64     (DW_OP_fbreg: -28)
 <2><294>: Abbrev Number: 0
 <1><295>: Abbrev Number: 3 (DW_TAG_subprogram)
    <296>   DW_AT_abstract_origin: <0x1e8>
    <29a>   DW_AT_low_pc      : 0x4004fc
    <2a2>   DW_AT_high_pc     : 0x10
    <2aa>   DW_AT_frame_base  : 1 byte block: 9c        (DW_OP_call_frame_cfa)
    <2ac>   DW_AT_object_pointer: <0x2b4>
    <2b0>   DW_AT_GNU_all_call_sites: 1
    <2b0>   DW_AT_sibling     : <0x2bd>
 <2><2b4>: Abbrev Number: 4 (DW_TAG_formal_parameter)
    <2b5>   DW_AT_abstract_origin: <0x1f5>
    <2b9>   DW_AT_artificial  : 1
    <2b9>   DW_AT_location    : 2 byte block: 91 68     (DW_OP_fbreg: -24)
 <2><2bc>: Abbrev Number: 0
 <1><2bd>: Abbrev Number: 6 (DW_TAG_subprogram)
    <2be>   DW_AT_abstract_origin: <0x1cf>
    <2c2>   DW_AT_low_pc      : 0x40050c
    <2ca>   DW_AT_high_pc     : 0x27
    <2d2>   DW_AT_frame_base  : 1 byte block: 9c        (DW_OP_call_frame_cfa)
    <2d4>   DW_AT_GNU_all_tail_call_sites: 1
    <2d4>   DW_AT_sibling     : <0x2e1>
 <2><2d8>: Abbrev Number: 7 (DW_TAG_variable)
    <2d9>   DW_AT_abstract_origin: <0x1de>
    <2dd>   DW_AT_location    : 2 byte block: 91 60     (DW_OP_fbreg: -32)
 <2><2e0>: Abbrev Number: 0
 <1><2e1>: Abbrev Number: 8 (DW_TAG_structure_type)
    <2e2>   DW_AT_name        : X
    <2e4>   DW_AT_byte_size   : 4
    <2e5>   DW_AT_decl_file   : 1
    <2e6>   DW_AT_decl_line   : 1
    <2e7>   DW_AT_sibling     : <0x2f9>
 <2><2eb>: Abbrev Number: 9 (DW_TAG_member)
    <2ec>   DW_AT_name        : res
    <2f0>   DW_AT_decl_file   : 1
    <2f1>   DW_AT_decl_line   : 1
    <2f2>   DW_AT_type        : <0x2f9>
    <2f6>   DW_AT_data_member_location: 0
    <2f7>   DW_AT_accessibility: 3      (private)
 <2><2f8>: Abbrev Number: 0
 <1><2f9>: Abbrev Number: 10 (DW_TAG_base_type)
    <2fa>   DW_AT_byte_size   : 4
    <2fb>   DW_AT_encoding    : 5       (signed)
    <2fc>   DW_AT_name        : int
 <1><300>: Abbrev Number: 0

notice the stray unused type DIEs at 0x2e1 and following.

We'll ultimatively have issues with fat LTO objects and with the
linker refusing to link
objects with slim LTO data just for its debug info.  Currently I'm
working to make
the slim-LTO but not marked as slim mode work only.

Richard.

Attachment: early-lto-debug-day2
Description: Binary data

Attachment: a.out
Description: Binary data

Reply via email to