Reputation: 11
How to calculate the value of DW_AT_location can anybody help?
And I also want to know when to use DW_OP_addr
and DW_OP_fbreg
with this attribute
.uleb128 0x2 # (DIE (0x75) DW_TAG_variable)
.ascii "c\0" # DW_AT_name
.byte 0x1 # DW_AT_decl_file (DW_TAG_const_type_1.c)
.byte 0x5 # DW_AT_decl_line
.long 0x88 # DW_AT_type
# DW_AT_external
.uleb128 0x9 # DW_AT_location
.byte 0x3 # DW_OP_addr
.uleb128 0x6 # (DIE (0x6d) DW_TAG_variable)
.ascii "obj\0" # DW_AT_name
.byte 0x1 # DW_AT_decl_file (DW_TAG_base_type_1.c)
.byte 0x5 # DW_AT_decl_line
.long 0x84 # DW_AT_type
.uleb128 0x3 # DW_AT_location
.byte 0x91 # DW_OP_fbreg
.sleb128 -96
Upvotes: 1
Views: 2651
Reputation: 1562
There's not enough information in your question to provide a complete answer.
In each case it looks as though the DW_AT_location
has been expressed with the form DW_FORM_exprloc
, which is a ULEB128-encoded length followed by a corresponding number of bytes that, in this case, constitute a DWARF expression that is used as a location description.
In the first case, the length is 9 but only the first byte has been shown, i.e. DW_OP_addr
. The DWARF 4 standard contains the following useful explanations:
2.5.1 General Operations
Each general operation represents a postfix operation on a simple stack machine. Each element of the stack is the size of an address on the target machine. The value on the top of the stack after “executing” the DWARF expression is taken to be the result (the address of the object, the value of the array bound, the length of a dynamic string, the desired value itself, and so on).
2.5.1.1 Literal Encodings
The following operations all push a value onto the DWARF stack. If the value of a constant in one of these operations is larger than can be stored in a single stack element, the value is truncated to the element size and the low-order bits are pushed on the stack.
- DW_OP_addr
The DW_OP_addr operation has a single operand that encodes a machine address and whose size is the size of an address on the target machine.
Therefore the eight bytes following the end of your first example would have been the address of the variable c
before any relocations have been applied.
The second example is also incomplete. Encoding decimal -96 in SLEB128 consumes two bytes, 0xa0
0x7f
, so you have the whole of the location description, i.e. DW_OP_fbreg(-96)
. However, as the standard explains:
2.5.1.2 Register Based Addressing
The following operations push a value onto the stack that is the result of adding the contents of a register to a given signed offset.
- DW_OP_fbreg
The DW_OP_fbreg operation provides a signed LEB128 offset from the address specified by the location description in the DW_AT_frame_base attribute of the current function. (This is typically a “stack pointer” register plus or minus some offset. On more sophisticated systems it might be a location list that adjusts the offset according to changes in the stack pointer as the PC changes.)
Therefore you need to find the DIE for the function that owns obj
and evaluate its DW_AT_frame_base
. obj
is stored ninety-six bytes below that address.
Upvotes: 3