SIZE, to find the current location of variable of TYPE in the context
of FRAME. */
-static struct value *
+struct value *
dwarf2_evaluate_loc_desc (struct type *type, struct frame_info *frame,
const gdb_byte *data, unsigned short size,
struct dwarf2_per_cu_data *per_cu)
struct symbol *framefunc;
int frame_reg = 0;
LONGEST frame_offset;
- const gdb_byte *base_data, *new_data;
+ const gdb_byte *base_data, *new_data, *save_data = data;
size_t base_size;
LONGEST base_offset = 0;
{
/* We don't know what to do with the frame base expression,
so we can't trace this variable; give up. */
- error (_("Cannot describe location of symbol \"%s\"; "
- "DWARF 2 encoding not handled, "
- "first opcode in base data is 0x%x."),
- SYMBOL_PRINT_NAME (symbol), base_data[0]);
+ return save_data;
}
regno = gdbarch_dwarf2_reg_to_regnum (gdbarch, frame_reg);
DW_AT_location : 10 byte block: 3 4 0 0 0 0 0 0 0 e0
(DW_OP_addr: 4; DW_OP_GNU_push_tls_address)
-
+
0x3 is the encoding for DW_OP_addr, which has an operand as long
as the size of an address on the target machine (here is 8
- bytes). 0xe0 is the encoding for DW_OP_GNU_push_tls_address.
- The operand represents the offset at which the variable is within
- the thread local storage. */
+ bytes). Note that more recent version of GCC emit DW_OP_const4u
+ or DW_OP_const8u, depending on address size, rather than
+ DW_OP_addr. 0xe0 is the encoding for
+ DW_OP_GNU_push_tls_address. The operand represents the offset at
+ which the variable is within the thread local storage. */
else if (data + 1 + addr_size < end
- && data[0] == DW_OP_addr
+ && (data[0] == DW_OP_addr
+ || (addr_size == 4 && data[0] == DW_OP_const4u)
+ || (addr_size == 8 && data[0] == DW_OP_const8u))
&& data[1 + addr_size] == DW_OP_GNU_push_tls_address
&& piece_end_p (data + 2 + addr_size, end))
{