bug-gdb
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Dwarf2 bug?


From: Daniel Berlin
Subject: Re: Dwarf2 bug?
Date: 11 Jun 2001 21:37:17 -0400
User-agent: Gnus/5.090004 (Oort Gnus v0.04) XEmacs/21.5 (anise)

address@hidden (Tim Combs) writes:

> Working with the Arm ADS 1.1 compiler, I noticed a problem with
> typedefs and gdb 5.0.  The setup would be:
> 
>    In a header file
> foo.h
>   typedef INT32 int;
> 
> foo2.h
>   include "foo.h"
>   typedef RETCODE INT32;
> 
> foobar.c
>    include "foo2.h"
>    RETCODE = foobar(void);
> 
> foo.c
>    include "foo2.h"
>    RETCODE = foobar();   
> 
> The relevant sections of the dwarf2 dump looks like this:
> 
> ** Section #5 '.debug_info' (SHT_PROGBITS)
>     Size   : 684 bytes
> 
>   Header
>     size 0x44 bytes, dwarf version 2, abbrevp 0x0, address size 4
>   00000b: 11  = 0x11 (DW_TAG_compile_unit)
>   00000c:   DW_AT_name foo.c
>   000012:   DW_AT_producer Thumb C Compiler, ADS1.1 [Build 712]
>   000037:   DW_AT_language 0x1
>   000038:   DW_AT_macro_info 0x0
>   00003c:   DW_AT_stmt_list 0x0
>   000040:   4  = 0x24 (DW_TAG_base_type)
>   000041:     DW_AT_byte_size 0x4
>   000042:     DW_AT_encoding DW_ATE_signed
>   000043:     DW_AT_name int
>   000047:   0  null
>   Header
>     size 0x48 bytes, dwarf version 2, abbrevp 0x0, address size 4
>   000053: 8  = 0x11 (DW_TAG_compile_unit)
>   000054:   DW_AT_name foo.h
>   00005a:   DW_AT_producer Thumb C Compiler, ADS1.1 [Build 712]
>   00007f:   DW_AT_language 0x1
>   000080:   4  = 0x24 (DW_TAG_base_type)
>   000081:     DW_AT_byte_size 0x4
>   000082:     DW_AT_encoding DW_ATE_signed
>   000083:     DW_AT_name int
>   000087:   56  = 0x16 (DW_TAG_typedef)
>   000088:     DW_AT_name INT32
>   00008e:     DW_AT_type indirect DW_FORM_ref_udata 0x38 (0x80)
>   000090:   0  null
>   000091: 0  padding
>   000092: 0  padding
>   000093: 0  padding
>   Header
>     size 0x4c bytes, dwarf version 2, abbrevp 0x0, address size 4
>   00009f: 11  = 0x11 (DW_TAG_compile_unit)
>   0000a0:   DW_AT_name foo2.h
>   0000a7:   DW_AT_producer Thumb C Compiler, ADS1.1 [Build 712]
>   0000cc:   DW_AT_language 0x1
>   0000cd:   DW_AT_macro_info 0x17c
>   0000d1:   DW_AT_stmt_list 0xac
>   0000d5:   56  = 0x16 (DW_TAG_typedef)
>   0000d6:     DW_AT_name RETCODE
>   0000de:     DW_AT_type indirect DW_FORM_ref_addr 0x87
>   0000e3:   0  null
> 
> <snip> .... foo.c compilation unit missing
> 
>   Header
>     size 0xa8 bytes, dwarf version 2, abbrevp 0x0, address size 4
>   00020b: 5  = 0x11 (DW_TAG_compile_unit)
>   00020c:   DW_AT_name foobar.c
>   000215:   DW_AT_producer Thumb C Compiler, ADS1.1 [Build 712]
>   00023a:   DW_AT_language 0x1
>   00023b:   DW_AT_low_pc 0x138
>   00023f:   DW_AT_high_pc 0x144
>   000243:   DW_AT_stmt_list 0xdc
>   000247:   35  = 0x2e (DW_TAG_subprogram)
>   000248:     DW_AT_sibling 0xab (0x2ab)
>   00024b:     DW_AT_decl_file 0x1
>   00024c:     DW_AT_decl_line 0x4
>   00024d:     DW_AT_decl_column 0x0
>   00024e:     DW_AT_name foobar
>   000255:     DW_AT_external 0x1
>   000256:     DW_AT_type indirect DW_FORM_ref_addr 0xd5
>   00025b:     DW_AT_low_pc 0x138
>   00025f:     DW_AT_high_pc 0x144
> <snip> -- rest doesn't matter.
> 
> To get the DW_AT_type of function foobar():
> 1. Read at offset 0xd5 DW_FORM_ref_addr  (that tells you to go )
> 2. Read at offset 0x87 DW_FORM_ref_udata (that tells you to go read
>                                           offset of 0x38 of the compilation
>                                           unit.
> 
> The problem comes in when dwarf2_get_ref_die_offset() is called to figure
> this out.  The offset that is added to the attribute is set to the original
> compilation unit.  Since we have arrived by the "back door", we don't know
> the compilation unit's offset:
> dwarf2_get_ref_die_offset()
>     switch (attr->form)
>     {
>     case DW_FORM_ref_addr:
>       result = DW_ADDR (attr); 
>       break;
>     case DW_FORM_ref1: 
>     case DW_FORM_ref2:
>     case DW_FORM_ref4:
>     case DW_FORM_ref8:
>     case DW_FORM_ref_udata:
>       result = cu_header_offset + DW_UNSND (attr);
>                ^^^^^^^^^^^^^^^
> 
> All this to ask:
> Is there a way to find the compilation unit from deep inside the die?
> 
> The only way I know to fix this is to walk through the partial symbol
> table and look at the offset and length of each compilation unit. 
> Then find a compilation unit that contains this offset.
> 
> Any other ideas?

Yes. Rewrite the dwarf2 reader so it passes it maintains a table of
compilation  units[1], has a routine to get a compilation unit given an
offset (and a routine to read/get the compilation unit for a given
offset, in case you want it automatically read for you if it's not
read in yet) and pass the current compilation unit instance around to each
function.
This is exactly what I did, anyway.

I can send you the work if you want, i'm now in the midst of
temporarily removing the symbol evaluation related stuff from it so
while I wait 6 months for that to get approved, I can submit the base
rewrite and wait in parallel for the 6 months it'll take to get the
dwarf2 reader approved. 

--Dan
[1] DWARF2.1 will have inter-file compilation unit referencing
abilities, so it's not enough to just keep it with and objfile, unless
we never want to be able to free that objfile private data. STABS does
something like this, and it affects everything else.  It should have
been private to the STABS reader, just like this table is private to
the DWARF2 reader
> 
> 
> Thanks
> Tim
> --------------------------------------------------------
> address@hidden

-- 
"All the plants in my house are dead -- I shot them last night.
I was torturing them by watering them with ice cubes.
"-Steven Wright



reply via email to

[Prev in Thread] Current Thread [Next in Thread]