[Dwarf-Discuss] Location list entries for caller-saved registers at time of call

Michael Eager eager at eagerm.com
Fri Dec 7 08:28:06 PST 2018


On 12/07/2018 08:12 AM, Jakub Jelinek wrote:
> On Fri, Dec 07, 2018 at 07:57:23AM -0800, Michael Eager wrote:
>> On 12/07/2018 04:54 AM, Jakub Jelinek wrote:
>>> On Fri, Dec 07, 2018 at 12:36:39PM +0000, David Stenberg via Dwarf-Discuss wrote:
>>>
>>> For calls, we need to distinguish the locations that are valid in the caller
>>> on the call instruction before the call instruction has been executed, then
>>> locations that are valid while inside of the call and finally locations that
>>> are valid after the call has returned.
>>
>> But the call instruction is atomic.  There are not distinct PC locations
>> within an individual call instruction.
> 
> The instruction itself is, but the invocation of the called procedure is
> not.

So?  The return address doesn't slowly creep through the call
instruction as the called procedure executes.

>> I know what the PC is before the call, I know what the
>> return address is in the called routine, and I know what the PC is
>> after the return.  None of these addresses is in the middle of the call.
>>
>> Why not generate the label as the next address following the call?
> 
> Because there is some other code there and some other locations might be
> valid at that point, but not during the call.  E.g. something could live in
> the register holding return value from the function, which won't be there
> until the function returns.  The labels can be:
> .L0:
>    whatever1
> .L1:
>    call foo
> .L2:
>    whatever2
> .L3:
> 
> and in .debug_loc etc., I can provide say one location description for the
> range .L0 to .L1 (i.e. for instructions before the call
> instruction, another one e.g. for .L1 to .L2-1, valid on the call
> instruction, but not inside of the foo call, another one from .L2-1 to .L2,
> valid after the call foo instruction is done but before the call returned
> (i.e. inside of the foo call or whatever it calls) and finally .L2 to .L3
> range which covers the instructions after the call.

The reason that the loclist is [start, end) is so that you do not need
to pretend that there is a valid .L2-1 PC value.  There is no valid PC
range of [.L1, .L2-1) or [.L2-1, .L2).  When inside the called
procedure, the return address is .L2, NOT .L2-1.

When generating a loclist for the calling function, you don't need to be
concerned about the called procedure.  All you need to do is list the
valid range of PC values in that function.

> The debug info consumers usually subtract one from the return address with
> the exception of signal frames so that they locate something in the middle
> of the call instruction rather than whatever is after it (there could be
> e.g. a completely different function be there already, or completely
> unrelated code e.g. for calls that never return).

As mentioned before, producers should generate DWARF which describes the
code generated, and not attempt to compensate for what it believes a
consumer is doing.

None of the reasons you give seem to call for generating an invalid PC
in the loclist.   In the case of a call which is the last instruction
in a function. the loclist would have an end address which is after the
function.  This is OK, and the address is explicitly excluded from the
range.

-- 
Michael Eager    eager at eagerm.com
1960 Park Blvd., Palo Alto, CA 94306


More information about the Dwarf-Discuss mailing list