debug_loc decoding error with readelf/objdump ?
Christian Bruel
christian.bruel@st.com
Tue Aug 31 13:00:00 GMT 2010
On 08/31/2010 02:19 PM, Andrew Burgess wrote:
> The Dwarf2 spec says, in section 2.4.6 that a location list entry with start and end addresses of zero indicate the end of a location list, and that no location description is present; this is why a hole is reported.
OK, that was the part I was looking for, thanks !
>
> In general an end address equal to the start address for a location list entry is valid, but does not make much sense, the end address is the first address *after* the range of addresses for which the location information is valid, so if start == end, then there are *no* addresses for which the location information is valid; why create such an entry? Especially when you consider that in general a start address of 0 is perfectly valid (the start / end addresses can be section relative) and so if we start creating entries where start == end then we can hit the case where start == end == 0 , which is just going to cause problems.
I fully agree, but when the labels was not at address 0, then we
correctly dump
00000000 00000001 00000001 () (start == end) which is equally
semantically non sense, but valid.
I think what happened with the 0 address is that a sequence as
.Ltext0:
foo:
.LVL0:
instr 2
.LVL1:
instr 3
.section .debug_loc
.LLST1:
.long .LVL0-.Ltext0
.long .LVL1-.Ltext0
.word 0x0
.long 0x0
.long 0x0
has a valid range of addresses, but then the instr2 instruction gets
optimized ...
.Ltext0:
foo:
.LVL0:
.LVL1:
instr 3
.section .debug_loc
.LLST1:
.long .LVL0-.Ltext0
.long .LVL1-.Ltext0
.word 0x0
.long 0x0
.long 0x0
The problem here is that this confuses objdump to produce invalid dumps
for subsequent entries, instead of just reporting "no entry" for the
required entry (or "empty entry") if it starts with 0.
>
> The problem is, I think, with gcc, though I've not yet figured out why (my knowledge of gcc internals is still pretty weak) but looking at at gcc/dwarf2out.c in the gcc source, in output_loc_list( ... ) there is code that looks like this:
I think this happened when code is optimized after the dwarf2 emission
(there are places where this can happen: relaxation, ...). I'll go back
to look at GCC to see where this occurred.
>
> /* Don't output an entry that starts and ends at the same address. */
> if (strcmp (curr->begin, curr->end) == 0)
> continue;
>
> I think in your code this has failed for some reason and allowed the generation of the list entry for LVL0 to LVL1 even though they are both at the same address.
Agree, the debug_loc should have been repaired. I think this was broken
after the code you cite.
Many thanks
Christian
>
> Hope this helps,
>
> Andrew
>
>> -----Original Message-----
>> From: binutils-owner@sourceware.org [mailto:binutils-
>> owner@sourceware.org] On Behalf Of Christian Bruel
>> Sent: 31 August 2010 12:37
>> To: binutils@sourceware.org
>> Subject: Re: debug_loc decoding error with readelf/objdump ?
>>
>> I reduced the case a little bit more, see new attachment.
>>
>> So basically what seem to happen is that the debug_loc entry is emitted
>> as
>>
>> .long 0 // .LVL0-.Ltext0
>> .long 0 // .LVL1-.Ltext0
>> .word 0 // length
>> .long 0 // entry terminator
>> .long 0
>>
>> So it looks like the objdump implementation takes the first two 0
>> addresses as the terminator, and then the other entries are shifted.
>>
>> The question is is it an implementation restriction or a DWARF2
>> restriction ?. Since the location list entry has a length field, the
>> terminator shouldn't be necessary, and consequently an entry with 0,0
>> addresses could be valid.
>>
>> Second hypothesis, if the 0,0 terminator is necessary by the
>> implementation, could the dwarf2 reader report a warning rather than
>> silently emitting a corrupted output ?
>>
>> Any comment ?
>>
>> Best Regards
>>
>> Christian
>>
>>
>> On 08/31/2010 11:39 AM, Christian Bruel wrote:
>>> Hello,
>>>
>>> When using a DWARF2 debug_loc entry, with 2 relative addresses at 0
>> and
>>> with a 0 size, I get a strange "There is a hole" warning message, and
>>> the entries are not decoded (subsequent ones are corrupted).
>>>
>>> for instance, using the attached reduced case from a more complex GCC
>>> generated DWARF2 : with
>>>
>>> as bad.s -o bad.o&& objdump --dwarf=loc bad.o
>>>
>>> I get:
>>> ------------------------------------------
>>> Contents of the .debug_loc section:
>>>
>>> Offset Begin End Expression
>>> 00000000<End of list>
>>> objdump: Warning: There is a hole [0x8 - 0x13] in .debug_loc section.
>>> 00000013<End of list>
>>> -------------------------------------------
>>>
>>> Note that the entry is not dumped, I expected to get:
>>>
>>> --------------------------------------------
>>> Contents of the .debug_loc section:
>>>
>>> Offset Begin End Expression
>>> 00000000 00000000 00000000 (DW_OP_reg4) (start == end)
>>> 00000000<End of list>
>>> ---------------------------------------------
>>>
>>> Reading the DWARF2 specifications, in chapter 7.7.2 on locations
>> lists,
>>> I don't see anything that prevents my example to be valid.
>>>
>>> Both readelf, dwarfdump report the same warning, but dwarfdump seems
>> to
>>> be OK with it.
>>>
>>> Could this be a bug with readelf and dwarfdump ? Or did I miss
>> something
>>> from the standard ? (and so would indicate a bug in GCC) ?
>>>
>>> many thanks.
>>>
>>> Christian
>>>
>>>
>>>
>>>
>>>
>>>
>
>
More information about the Binutils
mailing list