[PATCH] fix info address for thread local vars
Elena Zannoni
ezannoni@redhat.com
Mon Jul 21 19:42:00 GMT 2003
Here is something to fix the output of info address on a TLS
variable. It makes it the same as the old output, with the same amount
of information. I want to commit this on both the branch and the
mainline.
I am also really tempted to commit the tls tests (to the mailine
only), otherwise, the tls feature will bitrot. I'll work through
refining the tests once they are in.
elena
2003-07-21 Elena Zannoni <ezannoni@redhat.com>
* findvar.c (read_var_value): Remove case for thread local storage
variables. It is now entirely handled by the dwarf2 location
expression code.
* printcmd.c (address_info): Ditto.
* symtab.h (address_class): Remove LOC_THREAD_LOCAL_STATIC
enumeration value.
(struct symbol): Remove objfile field, which was used by
LOC_THREAD_LOCAL_STATIC only.
* dwarf2read.c (decode_locdesc): Remove is_thread_local variable.
* dwarf2loc.h (struct dwarf2_loclist_baton): Add comment about
usage of objfile pointer.
* dwarf2loc.c (locexpr_describe_location): Add case to handle
thread local variables.
Add include of objfiles.h.
* dwarf2expr.c (execute_stack_op): Add comments about thread local
storage variables.
* Makefile.in (dwarf2loc.o): Update dependencies.
Index: Makefile.in
===================================================================
RCS file: /cvs/uberbaum/gdb/Makefile.in,v
retrieving revision 1.420
diff -u -p -r1.420 Makefile.in
--- Makefile.in 17 Jul 2003 12:49:52 -0000 1.420
+++ Makefile.in 21 Jul 2003 19:16:24 -0000
@@ -1681,7 +1681,8 @@ dwarf2expr.o: dwarf2expr.c $(defs_h) $(s
$(gdbcore_h) $(dwarf2expr_h)
dwarf2loc.o: dwarf2loc.c $(defs_h) $(ui_out_h) $(value_h) $(frame_h) \
$(gdbcore_h) $(target_h) $(inferior_h) $(dwarf2expr_h) \
- $(dwarf2loc_h) $(ax_h) $(ax_gdb_h) $(regcache_h) $(gdb_string_h)
+ $(dwarf2loc_h) $(ax_h) $(ax_gdb_h) $(regcache_h) $(objfiles_h) \
+ $(gdb_string_h)
dwarf2-frame.o: $(defs_h) $(dwarf2expr_h) $(elf_dwarf2_h) $(frame_h) \
$(frame_base_h) $(frame_unwind_h) $(gdbcore_h) $(gdbtypes_h) \
$(symtab_h) $(objfiles_h) $(regcache_h) $(gdb_assert_h) \
Index: dwarf2expr.c
===================================================================
RCS file: /cvs/uberbaum/gdb/dwarf2expr.c,v
retrieving revision 1.8
diff -u -p -r1.8 dwarf2expr.c
--- dwarf2expr.c 22 May 2003 18:37:05 -0000 1.8
+++ dwarf2expr.c 21 Jul 2003 19:16:25 -0000
@@ -641,6 +641,14 @@ execute_stack_op (struct dwarf_expr_cont
break;
case DW_OP_GNU_push_tls_address:
+ /* Variable is at a constant offset in the thread-local
+ storage block into the objfile for the current thread and
+ the dynamic linker module containing this expression. Here
+ we return returns the offset from that base. The top of the
+ stack has the offset from the beginning of the thread
+ control block at which the variable is located. Nothing
+ should follow this operator, so the top of stack would be
+ returned. */
result = dwarf_expr_fetch (ctx, 0);
dwarf_expr_pop (ctx);
result = (ctx->get_tls_address) (ctx->baton, result);
Index: dwarf2loc.c
===================================================================
RCS file: /cvs/uberbaum/gdb/dwarf2loc.c,v
retrieving revision 1.9
diff -u -p -r1.9 dwarf2loc.c
--- dwarf2loc.c 22 May 2003 18:37:05 -0000 1.9
+++ dwarf2loc.c 21 Jul 2003 19:16:26 -0000
@@ -29,6 +29,7 @@
#include "ax.h"
#include "ax-gdb.h"
#include "regcache.h"
+#include "objfiles.h"
#include "elf/dwarf2.h"
#include "dwarf2expr.h"
@@ -185,6 +186,8 @@ dwarf_expr_tls_address (void *baton, COR
addr = target_get_thread_local_address (inferior_ptid,
debaton->objfile,
offset);
+ /* It wouldn't be wrong here to try a gdbarch method, too; finding
+ TLS is an ABI-specific thing. But we don't do that yet. */
else
error ("Cannot find thread-local variables on this target");
@@ -405,6 +408,34 @@ locexpr_describe_location (struct symbol
"a variable in register %s", REGISTER_NAME (regno));
return 1;
}
+
+ /* The location expression for a TLS variable looks like this (on a
+ 64-bit LE machine):
+
+ 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. */
+
+ if (dlbaton->size > 1
+ && dlbaton->data[dlbaton->size - 1] == DW_OP_GNU_push_tls_address)
+ if (dlbaton->data[0] == DW_OP_addr)
+ {
+ int bytes_read;
+ CORE_ADDR offset = dwarf2_read_address (&dlbaton->data[1],
+ &dlbaton->data[dlbaton->size - 2],
+ &bytes_read);
+ fprintf_filtered (stream,
+ "a thread-local variable at offset %s in the"
+ "thread-local storage for `%s'",
+ paddr_nz (offset), dlbaton->objfile->name);
+ return 1;
+ }
+
fprintf_filtered (stream,
"a variable with complex or multiple locations (DWARF2)");
Index: dwarf2loc.h
===================================================================
RCS file: /cvs/uberbaum/gdb/dwarf2loc.h,v
retrieving revision 1.2
diff -u -p -r1.2 dwarf2loc.h
--- dwarf2loc.h 13 Apr 2003 15:43:35 -0000 1.2
+++ dwarf2loc.h 21 Jul 2003 19:16:26 -0000
@@ -55,6 +55,10 @@ struct dwarf2_loclist_baton
unsigned short size;
/* The objfile containing the symbol whose location we're computing. */
+ /* Used (only???) by thread local variables. The objfile in which
+ this symbol is defined. To find a thread-local variable (e.g., a
+ variable declared with the `__thread' storage class), we may need
+ to know which object file it's in. */
struct objfile *objfile;
};
Index: dwarf2read.c
===================================================================
RCS file: /cvs/uberbaum/gdb/dwarf2read.c,v
retrieving revision 1.97
diff -u -p -r1.97 dwarf2read.c
--- dwarf2read.c 26 Jun 2003 21:20:39 -0000 1.97
+++ dwarf2read.c 21 Jul 2003 19:16:32 -0000
@@ -438,12 +438,6 @@ static int islocal; /* Variable is at t
this function, so we can't say
which register it's relative to;
use LOC_LOCAL. */
-static int is_thread_local; /* Variable is at a constant offset in the
- thread-local storage block for the
- current thread and the dynamic linker
- module containing this expression.
- decode_locdesc returns the offset from
- that base. */
/* DW_AT_frame_base values for the current function.
frame_base_reg is -1 if DW_AT_frame_base is missing, otherwise it
@@ -6788,7 +6782,6 @@ decode_locdesc (struct dwarf_block *blk,
offreg = 0;
isderef = 0;
islocal = 0;
- is_thread_local = 0;
optimized_out = 1;
while (i < size)
@@ -7014,7 +7007,6 @@ decode_locdesc (struct dwarf_block *blk,
break;
case DW_OP_GNU_push_tls_address:
- is_thread_local = 1;
/* The top of the stack has the offset from the beginning
of the thread control block at which the variable is located. */
/* Nothing should follow this operator, so the top of stack would
Index: findvar.c
===================================================================
RCS file: /cvs/uberbaum/gdb/findvar.c,v
retrieving revision 1.61
diff -u -p -r1.61 findvar.c
--- findvar.c 7 Jul 2003 14:36:57 -0000 1.61
+++ findvar.c 21 Jul 2003 19:16:33 -0000
@@ -512,20 +512,6 @@ addresses have not been bound by the dyn
break;
}
- case LOC_THREAD_LOCAL_STATIC:
- {
- if (target_get_thread_local_address_p ())
- addr = target_get_thread_local_address (inferior_ptid,
- SYMBOL_OBJFILE (var),
- SYMBOL_VALUE_ADDRESS (var));
- /* It wouldn't be wrong here to try a gdbarch method, too;
- finding TLS is an ABI-specific thing. But we don't do that
- yet. */
- else
- error ("Cannot find thread-local variables on this target");
- break;
- }
-
case LOC_TYPEDEF:
error ("Cannot look up value of a typedef");
break;
Index: printcmd.c
===================================================================
RCS file: /cvs/uberbaum/gdb/printcmd.c,v
retrieving revision 1.63
diff -u -p -r1.63 printcmd.c
--- printcmd.c 9 Jun 2003 15:20:21 -0000 1.63
+++ printcmd.c 21 Jul 2003 19:16:36 -0000
@@ -1262,12 +1262,6 @@ address_info (char *exp, int from_tty)
val, REGISTER_NAME (basereg));
break;
- case LOC_THREAD_LOCAL_STATIC:
- printf_filtered ("a thread-local variable at offset %ld in the "
- "thread-local storage for `%s'",
- val, SYMBOL_OBJFILE (sym)->name);
- break;
-
case LOC_OPTIMIZED_OUT:
printf_filtered ("optimized out");
break;
Index: symtab.h
===================================================================
RCS file: /cvs/uberbaum/gdb/symtab.h,v
retrieving revision 1.76
diff -u -p -r1.76 symtab.h
--- symtab.h 26 Jun 2003 17:18:42 -0000 1.76
+++ symtab.h 21 Jul 2003 19:16:42 -0000
@@ -482,14 +482,6 @@ enum address_class
LOC_HP_THREAD_LOCAL_STATIC,
- /* Value is at a thread-specific location calculated by a
- target-specific method. SYMBOL_OBJFILE gives the object file
- in which the symbol is defined; the symbol's value is the
- offset into that objfile's thread-local storage for the current
- thread. */
-
- LOC_THREAD_LOCAL_STATIC,
-
/* The variable does not actually exist in the program.
The value is ignored. */
@@ -605,12 +597,6 @@ struct symbol
{
/* Used by LOC_BASEREG and LOC_BASEREG_ARG. */
short basereg;
-
- /* Used by LOC_THREAD_LOCAL_STATIC. The objfile in which this
- symbol is defined. To find a thread-local variable (e.g., a
- variable declared with the `__thread' storage class), we may
- need to know which object file it's in. */
- struct objfile *objfile;
/* For a LOC_COMPUTED or LOC_COMPUTED_ARG symbol, this is the
baton and location_funcs structure to find its location. For a
More information about the Gdb-patches
mailing list