Handle DW_OP_form_tls_address

Currently gdb supports DW_OP_GNU_push_tls_address, but not
DW_OP_form_tls_address.  I think it would be better if the toolchain
as a whole moved to using the standard opcode, and the prerequisite to
this is getting gdb to recognize it.

GCC can sometimes emit DW_OP_form_tls_address for emultls targets.  As
far as I know, nobody has ever tried this with gdb (since it wouldn't
work at all).

I don't think there's a major drawback to using a single opcode for
all targets, because computing the location of a thread-local is
already target specific.

This is PR gdb/11616.

I don't know how to write a test case for this; though it's worth
noting that there aren't explicit tests for DW_OP_GNU_push_tls_address
either -- and if I change GCC, these paths will be tested to the same
extent they are now.

2016-09-02  Tom Tromey  <tom@tromey.com>

	PR gdb/11616:
	* dwarf2read.c (decode_locdesc): Handle DW_OP_form_tls_address.
	* dwarf2loc.c (dwarf2_compile_expr_to_ax): Handle
	DW_OP_form_tls_address.
	(locexpr_describe_location_piece): Likewise.
	* dwarf2expr.h (struct dwarf_expr_context_funcs): Update comment.
	* dwarf2expr.c (execute_stack_op): Handle DW_OP_form_tls_address.
	(ctx_no_get_tls_address): Mention DW_OP_form_tls_address.
	* compile/compile-loc2c.c (struct insn_info): Update comment.
	(compute_stack_depth_worker): Handle DW_OP_form_tls_address.
This commit is contained in:
Tom Tromey 2016-08-22 16:56:52 -06:00
parent 1b2d85b255
commit 4aa4e28bdc
6 changed files with 26 additions and 7 deletions

View file

@ -1,3 +1,16 @@
2016-09-02 Tom Tromey <tom@tromey.com>
PR gdb/11616:
* dwarf2read.c (decode_locdesc): Handle DW_OP_form_tls_address.
* dwarf2loc.c (dwarf2_compile_expr_to_ax): Handle
DW_OP_form_tls_address.
(locexpr_describe_location_piece): Likewise.
* dwarf2expr.h (struct dwarf_expr_context_funcs): Update comment.
* dwarf2expr.c (execute_stack_op): Handle DW_OP_form_tls_address.
(ctx_no_get_tls_address): Mention DW_OP_form_tls_address.
* compile/compile-loc2c.c (struct insn_info): Update comment.
(compute_stack_depth_worker): Handle DW_OP_form_tls_address.
2016-09-01 Sergio Durigan Junior <sergiodj@redhat.com> 2016-09-01 Sergio Durigan Junior <sergiodj@redhat.com>
* target.c (target_wait): Mention that the function's prototype * target.c (target_wait): Mention that the function's prototype

View file

@ -48,9 +48,9 @@ struct insn_info
unsigned int label : 1; unsigned int label : 1;
/* Whether this instruction is DW_OP_GNU_push_tls_address. This is /* Whether this instruction is DW_OP_GNU_push_tls_address or
a hack until we can add a feature to glibc to let us properly DW_OP_form_tls_address. This is a hack until we can add a
generate code for TLS. */ feature to glibc to let us properly generate code for TLS. */
unsigned int is_tls : 1; unsigned int is_tls : 1;
}; };
@ -323,6 +323,7 @@ compute_stack_depth_worker (int start, int *need_tempvar,
break; break;
case DW_OP_GNU_push_tls_address: case DW_OP_GNU_push_tls_address:
case DW_OP_form_tls_address:
info[ndx].is_tls = 1; info[ndx].is_tls = 1;
break; break;

View file

@ -1257,6 +1257,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
break; break;
case DW_OP_GNU_push_tls_address: case DW_OP_GNU_push_tls_address:
case DW_OP_form_tls_address:
/* Variable is at a constant offset in the thread-local /* Variable is at a constant offset in the thread-local
storage block into the objfile for the current thread and storage block into the objfile for the current thread and
the dynamic linker module containing this expression. Here the dynamic linker module containing this expression. Here
@ -1533,7 +1534,7 @@ ctx_no_get_frame_pc (void *baton)
CORE_ADDR CORE_ADDR
ctx_no_get_tls_address (void *baton, CORE_ADDR offset) ctx_no_get_tls_address (void *baton, CORE_ADDR offset)
{ {
error (_("%s is invalid in this context"), "DW_OP_GNU_push_tls_address"); error (_("%s is invalid in this context"), "DW_OP_form_tls_address");
} }
/* Stub dwarf_expr_context_funcs.dwarf_call implementation. */ /* Stub dwarf_expr_context_funcs.dwarf_call implementation. */

View file

@ -56,7 +56,7 @@ struct dwarf_expr_context_funcs
CORE_ADDR (*get_frame_pc) (void *baton); CORE_ADDR (*get_frame_pc) (void *baton);
/* Return the thread-local storage address for /* Return the thread-local storage address for
DW_OP_GNU_push_tls_address. */ DW_OP_GNU_push_tls_address or DW_OP_form_tls_address. */
CORE_ADDR (*get_tls_address) (void *baton, CORE_ADDR offset); CORE_ADDR (*get_tls_address) (void *baton, CORE_ADDR offset);
/* Execute DW_AT_location expression for the DWARF expression subroutine in /* Execute DW_AT_location expression for the DWARF expression subroutine in

View file

@ -3571,6 +3571,7 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
break; break;
case DW_OP_GNU_push_tls_address: case DW_OP_GNU_push_tls_address:
case DW_OP_form_tls_address:
unimplemented (op); unimplemented (op);
break; break;
@ -3907,7 +3908,8 @@ locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream,
&& (data[0] == DW_OP_addr && (data[0] == DW_OP_addr
|| (addr_size == 4 && data[0] == DW_OP_const4u) || (addr_size == 4 && data[0] == DW_OP_const4u)
|| (addr_size == 8 && data[0] == DW_OP_const8u)) || (addr_size == 8 && data[0] == DW_OP_const8u))
&& data[1 + addr_size] == DW_OP_GNU_push_tls_address && (data[1 + addr_size] == DW_OP_GNU_push_tls_address
|| data[1 + addr_size] == DW_OP_form_tls_address)
&& piece_end_p (data + 2 + addr_size, end)) && piece_end_p (data + 2 + addr_size, end))
{ {
ULONGEST offset; ULONGEST offset;
@ -3930,7 +3932,8 @@ locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream,
&& data + 1 + (leb128_size = skip_leb128 (data + 1, end)) < end && data + 1 + (leb128_size = skip_leb128 (data + 1, end)) < end
&& data[0] == DW_OP_GNU_const_index && data[0] == DW_OP_GNU_const_index
&& leb128_size > 0 && leb128_size > 0
&& data[1 + leb128_size] == DW_OP_GNU_push_tls_address && (data[1 + leb128_size] == DW_OP_GNU_push_tls_address
|| data[1 + leb128_size] == DW_OP_form_tls_address)
&& piece_end_p (data + 2 + leb128_size, end)) && piece_end_p (data + 2 + leb128_size, end))
{ {
uint64_t offset; uint64_t offset;

View file

@ -20817,6 +20817,7 @@ decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
break; break;
case DW_OP_GNU_push_tls_address: case DW_OP_GNU_push_tls_address:
case DW_OP_form_tls_address:
/* The top of the stack has the offset from the beginning /* The top of the stack has the offset from the beginning
of the thread control block at which the variable is located. */ of the thread control block at which the variable is located. */
/* Nothing should follow this operator, so the top of stack would /* Nothing should follow this operator, so the top of stack would