From 49f6c8397d2fc0daf0bad3b832388a36feceb6c6 Mon Sep 17 00:00:00 2001 From: Doug Evans Date: Tue, 19 Jun 2012 00:37:18 +0000 Subject: [PATCH] * dwarf2expr.c (execute_stack_op): Handle DW_OP_GNU_const_index. Adjust address for DW_OP_GNU_addr_index. * dwarf2expr.h (dwarf_expr_context): Update comment. * dwarf2loc.c (locexpr_describe_location_piece): New arg per_cu, all callers updated. Handle TLS vars described with DW_OP_GNU_const_index. (disassemble_dwarf_expression): Handle DW_OP_GNU_addr_index and DW_OP_GNU_const_index. * dwarf2read.c (decode_locdesc): Handle DW_OP_GNU_addr_index. --- gdb/ChangeLog | 10 ++++++++++ gdb/dwarf2expr.c | 6 ++++++ gdb/dwarf2expr.h | 2 +- gdb/dwarf2loc.c | 38 +++++++++++++++++++++++++++++++++++++- gdb/dwarf2read.c | 1 + 5 files changed, 55 insertions(+), 2 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 821c8d0b911..78208b7331c 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,15 @@ 2012-06-18 Doug Evans + * dwarf2expr.c (execute_stack_op): Handle DW_OP_GNU_const_index. + Adjust address for DW_OP_GNU_addr_index. + * dwarf2expr.h (dwarf_expr_context): Update comment. + * dwarf2loc.c (locexpr_describe_location_piece): New arg per_cu, + all callers updated. Handle TLS vars described with + DW_OP_GNU_const_index. + (disassemble_dwarf_expression): Handle DW_OP_GNU_addr_index + and DW_OP_GNU_const_index. + * dwarf2read.c (decode_locdesc): Handle DW_OP_GNU_addr_index. + * block.c (find_block_in_blockvector): Make explicit the fact that we ignore GLOBAL_BLOCK. diff --git a/gdb/dwarf2expr.c b/gdb/dwarf2expr.c index 40ce6087318..214b371e569 100644 --- a/gdb/dwarf2expr.c +++ b/gdb/dwarf2expr.c @@ -725,6 +725,12 @@ execute_stack_op (struct dwarf_expr_context *ctx, break; case DW_OP_GNU_addr_index: + op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset); + result = (ctx->funcs->get_addr_index) (ctx->baton, uoffset); + result += ctx->offset; + result_val = value_from_ulongest (address_type, result); + break; + case DW_OP_GNU_const_index: op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset); result = (ctx->funcs->get_addr_index) (ctx->baton, uoffset); result_val = value_from_ulongest (address_type, result); diff --git a/gdb/dwarf2expr.h b/gdb/dwarf2expr.h index da3a5bb054a..db49b9c5ceb 100644 --- a/gdb/dwarf2expr.h +++ b/gdb/dwarf2expr.h @@ -158,7 +158,7 @@ struct dwarf_expr_context context and operations depending on DW_FORM_ref_addr are not allowed. */ int ref_addr_size; - /* Offset used to relocate DW_OP_addr argument. */ + /* Offset used to relocate DW_OP_addr and DW_OP_GNU_addr_index arguments. */ CORE_ADDR offset; /* An opaque argument provided by the caller, which will be passed diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c index 54dc5ad435b..6feeab607c8 100644 --- a/gdb/dwarf2loc.c +++ b/gdb/dwarf2loc.c @@ -3293,10 +3293,12 @@ locexpr_regname (struct gdbarch *gdbarch, int dwarf_regnum) static const gdb_byte * locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream, CORE_ADDR addr, struct objfile *objfile, + struct dwarf2_per_cu_data *per_cu, const gdb_byte *data, const gdb_byte *end, unsigned int addr_size) { struct gdbarch *gdbarch = get_objfile_arch (objfile); + size_t leb128_size; if (data[0] >= DW_OP_reg0 && data[0] <= DW_OP_reg31) { @@ -3416,6 +3418,29 @@ locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream, data += 1 + addr_size + 1; } + + /* With -gsplit-dwarf a TLS variable can also look like this: + DW_AT_location : 3 byte block: fc 4 e0 + (DW_OP_GNU_const_index: 4; + DW_OP_GNU_push_tls_address) */ + else if (data + 3 <= end + && data + 1 + (leb128_size = skip_leb128 (data + 1, end)) < end + && data[0] == DW_OP_GNU_const_index + && leb128_size > 0 + && data[1 + leb128_size] == DW_OP_GNU_push_tls_address + && piece_end_p (data + 2 + leb128_size, end)) + { + ULONGEST offset; + + data = safe_read_uleb128 (data + 1, end, &offset); + offset = dwarf2_read_addr_index (per_cu, offset); + fprintf_filtered (stream, + _("a thread-local variable at offset 0x%s " + "in the thread-local storage for `%s'"), + phex_nz (offset, addr_size), objfile->name); + ++data; + } + else if (data[0] >= DW_OP_lit0 && data[0] <= DW_OP_lit31 && data + 1 < end @@ -3771,6 +3796,17 @@ disassemble_dwarf_expression (struct ui_file *stream, all, per_cu); data += ul; continue; + + case DW_OP_GNU_addr_index: + data = safe_read_uleb128 (data, end, &ul); + ul = dwarf2_read_addr_index (per_cu, ul); + fprintf_filtered (stream, " 0x%s", phex_nz (ul, addr_size)); + break; + case DW_OP_GNU_const_index: + data = safe_read_uleb128 (data, end, &ul); + ul = dwarf2_read_addr_index (per_cu, ul); + fprintf_filtered (stream, " %s", pulongest (ul)); + break; } fprintf_filtered (stream, "\n"); @@ -3805,7 +3841,7 @@ locexpr_describe_location_1 (struct symbol *symbol, CORE_ADDR addr, if (!dwarf2_always_disassemble) { data = locexpr_describe_location_piece (symbol, stream, - addr, objfile, + addr, objfile, per_cu, data, end, addr_size); /* If we printed anything, or if we have an empty piece, then don't disassemble. */ diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 7ac125a2081..097ee7fbf88 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -15512,6 +15512,7 @@ decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu) break; case DW_OP_GNU_addr_index: + case DW_OP_GNU_const_index: stack[++stacki] = read_addr_index_from_leb128 (cu, &data[i], &bytes_read); i += bytes_read; -- 2.30.2