On 12/07/2018 08:26 AM, Cary Coutant wrote:
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().

This example shows local in %eax, which is a caller-save (i.e.,
scratch) register. GCC is right to show that the value is unknown upon
return from the call, because set() can clobber that register.

Try changing your code so that you use the value of local after the
call to set() -- say, make it "local += 123" -- and see the
difference. My copy of GCC moves local to %ebx, which is a caller-save
register, and the location list shows it live in that register all the
way through the call and return.

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>".

I think clang is wrong here. Because the call can clobber the
register, the compiler should not claim that the value is live upon
return.

I think clang is correct.

As I read the loclists, from 0x8 up to but not including 0xf, the
value is in reg0, from 0xf (after the call) up to but not including
0x16, the value is on the stack.

I don't see that this describes the value as live (in a register)
after the call, at PC = 0xf.

--
Michael Eager    ea...@eagerm.com
1960 Park Blvd., Palo Alto, CA 94306
_______________________________________________
Dwarf-Discuss mailing list
Dwarf-Discuss@lists.dwarfstd.org
http://lists.dwarfstd.org/listinfo.cgi/dwarf-discuss-dwarfstd.org

Reply via email to