aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog20
-rw-r--r--gdb/Makefile.in3
-rw-r--r--gdb/dwarf2expr.c8
-rw-r--r--gdb/dwarf2loc.c31
-rw-r--r--gdb/dwarf2loc.h4
-rw-r--r--gdb/dwarf2read.c8
-rw-r--r--gdb/findvar.c14
-rw-r--r--gdb/printcmd.c6
-rw-r--r--gdb/symtab.h14
9 files changed, 65 insertions, 43 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 5438b69..9c024d0 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,23 @@
+2003-07-22 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.
+
2003-07-22 Andrew Cagney <cagney@redhat.com>
* config/pa/tm-hppa64.h (FRAME_SAVED_PC_IN_SIGTRAMP): Use
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 95e4439..8a244b3 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -1681,7 +1681,8 @@ dwarf2expr.o: dwarf2expr.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(value_h) \
$(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) \
diff --git a/gdb/dwarf2expr.c b/gdb/dwarf2expr.c
index aa391eb..3d1523b 100644
--- a/gdb/dwarf2expr.c
+++ b/gdb/dwarf2expr.c
@@ -641,6 +641,14 @@ execute_stack_op (struct dwarf_expr_context *ctx, unsigned char *op_ptr,
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);
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index 9ed6b7e..01a2dda 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -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, CORE_ADDR offset)
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");
@@ -406,6 +409,34 @@ locexpr_describe_location (struct symbol *symbol, struct ui_file *stream)
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)");
return 1;
diff --git a/gdb/dwarf2loc.h b/gdb/dwarf2loc.h
index b6b4d33..321cb03 100644
--- a/gdb/dwarf2loc.h
+++ b/gdb/dwarf2loc.h
@@ -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;
};
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 1d68eff..115d8db 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -438,12 +438,6 @@ static int islocal; /* Variable is at the returned offset
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, struct objfile *objfile,
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, struct objfile *objfile,
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
diff --git a/gdb/findvar.c b/gdb/findvar.c
index 2e6a858..7b6191c 100644
--- a/gdb/findvar.c
+++ b/gdb/findvar.c
@@ -512,20 +512,6 @@ addresses have not been bound by the dynamic loader. Try again when executable i
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;
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index 410b950..3f0bc3c 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -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;
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 642b960..29df929 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -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. */
@@ -606,12 +598,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
LOC_BLOCK symbol for a function in a compilation unit compiled