I have been hacking a bit on dwarf2out.c to make gcc generate DWARF 
information that gets discarded along with the appropriate function section 
code when compiled with -ffunction-sections and then linked with 
--gc-sections. Currently, debug information for discarded functions is not 
removed, and this could cause the debugger to get confused.

The assembler already has a -gdwarf-sections flag to generate per
function sections for whatever debug information it generates, so I
figured I would do it for the compiler. Based on a previous discussion
on the binutils mailing list, I thought I'd generate separate
debug_info sections (for starters) for each function, and then tie it 
with the code section for that function by assigning them both to the 
same section group.

Based on the approach suggested by section E.3.3 of the DWARF 4
standard (using DW_TAG_imported_unit and the DW_AT_import attribute), I
managed to make the compiler to generate DWARF info as shown below.

Before going on, I thought I'd ask if my approach is right (and doable). 
Did I read the standard right? 

gdb currently crashes when presented with this DWARF. I guess both gcc and 
gdb currently use DW_TAG_imported_unit only to refer to other (partial) 
units from a DW_TAG_compile_unit, not the other way around?

Regards
Senthil

~  cat test.c
int _exit(int code) { return code; }

volatile int x;
static inline int add()
{
    return x++;
}
int foo()
{
    return add();
}

int doo()
{
    x--;
    return add();
}
int main() { 
    return doo();
}
~  /scratch/arm/install/bin/arm-none-eabi-gcc test.c -g3 -ffunction-sections
<warning snipped>

~  /scratch/arm/install/bin/arm-none-eabi-objdump -Wi a.out

a.out:     file format elf32-littlearm

Contents of the .debug_info section:

  Compilation Unit @ offset 0x0:
   Length:        0x41 (32-bit)
   Version:       4
   Abbrev Offset: 0x0
   Pointer Size:  4
 <0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
    <c>   DW_AT_producer    : (indirect string, offset: 0x13f7): GNU C 4.9.0 
20131226 (experimental) -g3 -ffunction-sections
    <10>   DW_AT_language    : 1    (ANSI C)
    <11>   DW_AT_name        : (indirect string, offset: 0x6b3): test.c
    <15>   DW_AT_comp_dir    : (indirect string, offset: 0x23): /home/saaadhu
    <19>   DW_AT_ranges      : 0x0
    <1d>   DW_AT_low_pc      : 0x0
    <21>   DW_AT_stmt_list   : 0x0
    <25>   DW_AT_GNU_macros  : 0x0
 <1><29>: Abbrev Number: 4 (DW_TAG_base_type)
    <2a>   DW_AT_byte_size   : 4
    <2b>   DW_AT_encoding    : 5    (signed)
    <2c>   DW_AT_name        : int
 <1><30>: Abbrev Number: 8 (DW_TAG_variable)
    <31>   DW_AT_name        : x
    <33>   DW_AT_decl_file   : 1
    <34>   DW_AT_decl_line   : 3
    <35>   DW_AT_type        : <0x3f>
    <39>   DW_AT_external    : 1
    <39>   DW_AT_location    : 5 byte block: 3 f0 c 1 0     (DW_OP_addr: 10cf0)
 <1><3f>: Abbrev Number: 9 (DW_TAG_volatile_type)
    <40>   DW_AT_type        : <0x29>
 <1><44>: Abbrev Number: 0
  Compilation Unit @ offset 0x45:
   Length:        0x31 (32-bit)
   Version:       4
   Abbrev Offset: 0x0
   Pointer Size:  4
 <0><50>: Abbrev Number: 10 (DW_TAG_imported_unit)
    <51>   DW_AT_import      : <0xb>    [Abbrev Number: 1]
 <1><55>: Abbrev Number: 2 (DW_TAG_subprogram)
    <56>   DW_AT_external    : 1
    <56>   DW_AT_name        : (indirect string, offset: 0xcf8): _exit
    <5a>   DW_AT_decl_file   : 1
    <5b>   DW_AT_decl_line   : 1
    <5c>   DW_AT_prototyped  : 1
    <5c>   DW_AT_type        : <0x6e>
    <60>   DW_AT_low_pc      : 0x8350
    <64>   DW_AT_high_pc     : 0x24
    <68>   DW_AT_frame_base  : 1 byte block: 9c     (DW_OP_call_frame_cfa)
    <6a>   DW_AT_GNU_all_call_sites: 1
 <2><6a>: Abbrev Number: 3 (DW_TAG_formal_parameter)
    <6b>   DW_AT_name        : (indirect string, offset: 0x1d41): code
    <6f>   DW_AT_decl_file   : 1
    <70>   DW_AT_decl_line   : 1
    <71>   DW_AT_type        : <0x6e>
    <75>   DW_AT_location    : 2 byte block: 91 74  (DW_OP_fbreg: -12)
 <2><78>: Abbrev Number: 0
 <1><79>: Abbrev Number: 0
  Compilation Unit @ offset 0x7a:
   Length:        0x22 (32-bit)
   Version:       4
   Abbrev Offset: 0x0
   Pointer Size:  4
 <0><85>: Abbrev Number: 10 (DW_TAG_imported_unit)
    <86>   DW_AT_import      : <0xb>    [Abbrev Number: 1]
 <1><8a>: Abbrev Number: 5 (DW_TAG_subprogram)
    <8b>   DW_AT_name        : add
    <8f>   DW_AT_decl_file   : 1
    <90>   DW_AT_decl_line   : 4
    <91>   DW_AT_type        : <0xa3>
    <95>   DW_AT_low_pc      : 0x8374
    <99>   DW_AT_high_pc     : 0x30
    <9d>   DW_AT_frame_base  : 1 byte block: 9c     (DW_OP_call_frame_cfa)
    <9f>   DW_AT_GNU_all_call_sites: 1
 <1><9f>: Abbrev Number: 0
  Compilation Unit @ offset 0xa0:
   Length:        0x22 (32-bit)
   Version:       4
   Abbrev Offset: 0x0
   Pointer Size:  4
 <0><ab>: Abbrev Number: 10 (DW_TAG_imported_unit)
    <ac>   DW_AT_import      : <0xb>    [Abbrev Number: 1]
 <1><b0>: Abbrev Number: 6 (DW_TAG_subprogram)
    <b1>   DW_AT_external    : 1
    <b1>   DW_AT_name        : foo
    <b5>   DW_AT_decl_file   : 1
    <b6>   DW_AT_decl_line   : 8
    <b7>   DW_AT_type        : <0xc9>
    <bb>   DW_AT_low_pc      : 0x83a4
    <bf>   DW_AT_high_pc     : 0x20
    <c3>   DW_AT_frame_base  : 1 byte block: 9c     (DW_OP_call_frame_cfa)
    <c5>   DW_AT_GNU_all_tail_call_sites: 1
 <1><c5>: Abbrev Number: 0
  Compilation Unit @ offset 0xc6:
   Length:        0x22 (32-bit)
   Version:       4
   Abbrev Offset: 0x0
   Pointer Size:  4
 <0><d1>: Abbrev Number: 10 (DW_TAG_imported_unit)
    <d2>   DW_AT_import      : <0xb>    [Abbrev Number: 1]
 <1><d6>: Abbrev Number: 6 (DW_TAG_subprogram)
    <d7>   DW_AT_external    : 1
    <d7>   DW_AT_name        : doo
    <db>   DW_AT_decl_file   : 1
    <dc>   DW_AT_decl_line   : 13
    <dd>   DW_AT_type        : <0xef>
    <e1>   DW_AT_low_pc      : 0x83c4
    <e5>   DW_AT_high_pc     : 0x38
    <e9>   DW_AT_frame_base  : 1 byte block: 9c     (DW_OP_call_frame_cfa)
    <eb>   DW_AT_GNU_all_tail_call_sites: 1
 <1><eb>: Abbrev Number: 0
  Compilation Unit @ offset 0xec:
   Length:        0x22 (32-bit)
   Version:       4
   Abbrev Offset: 0x0
   Pointer Size:  4
 <0><f7>: Abbrev Number: 10 (DW_TAG_imported_unit)
    <f8>   DW_AT_import      : <0xb>    [Abbrev Number: 1]
 <1><fc>: Abbrev Number: 7 (DW_TAG_subprogram)
    <fd>   DW_AT_external    : 1
    <fd>   DW_AT_name        : (indirect string, offset: 0x2105): main
    <101>   DW_AT_decl_file   : 1
    <102>   DW_AT_decl_line   : 18
    <103>   DW_AT_type        : <0x115>
    <107>   DW_AT_low_pc      : 0x83fc
    <10b>   DW_AT_high_pc     : 0x20
    <10f>   DW_AT_frame_base  : 1 byte block: 9c    (DW_OP_call_frame_cfa)
    <111>   DW_AT_GNU_all_tail_call_sites: 1
 <1><111>: Abbrev Number: 0

Reply via email to