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

David Stenberg david.stenberg@ericsson.com
Fri Dec 7 12:36:39 GMT 2018


On tor, 2018-12-06 at 17:47 -0800, Cary Coutant via Dwarf-Discuss
wrote:
> But we're getting sidetracked from the OP's question: Does GCC in
> fact
> subtract one from the upper bound of a location list entry for a
> variable contained in a caller-saved register? I can think of no
> reason why it should do this. If the compiled code does something
> like
> this:
> 
> ??? A: promote variable X into caller-save register R
> ?????? ...
> ?????? call f
> ??? B: ...
> ?????? spill register R back to X
> ??? C: ...
> 
> The location list entry for x should show it live in register R in
> the
> range [A..C). The call should not interrupt the range.
> 
> It sounds like David has an example where the range list entry shows
> x
> in register R in the range [A..B-1), then presumably again for
> [B..C),
> leaving [B-1..B) uncovered. That would be a bug, in my opinion.
> 
> David, can you show us an example?

In the following example I used GCC 7.3.0, and compiled the below
listed C code using `-O1 -gstrict-dwarf -gdwarf-5'.

? extern int get();
? extern void set(int);
??
? int main() {
? ? int local = get();
? ? set(local);
? ? local = 123;
? ? return local;
? }

This produces the following location list for `local':

? ? 0000000c 000000000000000e 0000000000000014 (DW_OP_reg0 (rax))
????00000011 0000000000000015 000000000000001f (DW_OP_const1u: 123; ? ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? DW_OP_stack_value)

? ?9:???e8 00 00 00 00??????????callq??e <main+0xe>
???e:???89 c7???????????????????mov????%eax,%edi
? 10:???e8 00 00 00 00??????????callq??15 <main+0x15>
? 15:???b8 7b 00 00 00??????????mov????$0x7b,%eax

As seen, there is a one-byte gap at the end of the call instruction to
set().

As far as I have understood it, GCC emits a location list like this
because it knows that the producer will subtract one from the return
address when doing virtual unwinding. In this way, GDB will print the
variable as "<optimized out>" when unwinding from set() to main(), even
though it does not have knowledge of whether or not RAX is caller-
saved.

If we instead use Clang, there is no gap in the location list for the
same code:

? ? [0x0000000000000008, 0x000000000000000f): DW_OP_reg0 RAX
????[0x000000000000000f, 0x0000000000000016): DW_OP_consts +123,
??????????????????????????????????????????????DW_OP_stack_value)

? ?3:???e8 00 00 00 00??????????callq??8 <main+0x8>
???8:???89 c7???????????????????mov????%eax,%edi
???a:???e8 00 00 00 00??????????callq??f <main+0xf>
???f:???b8 7b 00 00 00??????????mov????$0x7b,%eax

When debugging the Clang-built binary in GDB, when unwinding from set()
to main(), `local' will be evaluated using the value RAX has in set(),
rather then being printed as "<optimized out>".

Best regards,
David



More information about the Dwarf-discuss mailing list