aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog17
-rw-r--r--gdb/dwarf2read.c32
-rw-r--r--gdb/findvar.c17
-rw-r--r--gdb/printcmd.c6
-rw-r--r--gdb/symtab.h15
5 files changed, 86 insertions, 1 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 738246d..09ecdbe 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,20 @@
+2002-10-21 Jim Blandy <jimb@redhat.com>
+ Elena Zannoni <ezannoni@redhat.com>
+
+ * symtab.h (address_class): Re-add LOC_THREAD_LOCAL_STATIC
+ for thread local storage locations.
+ (struct symbol): Add objfile field.
+ (SYMBOL_OBJFILE): Define.
+ * dwarf2read.c (is_thread_local): New static variable.
+ (new_symbol): If variable is in thread local fill in address class
+ and objfile appropriately.
+ (decode_locdesc): Recognize and handle DW_OP_GNU_push_tls_address
+ stack operation.
+ * printcmd.c (address_info): Print the information for thread
+ local storage variable.
+ * findvar.c (read_var_value): In case of thread local variable,
+ defer to the target vector code to compute address.
+
2002-10-21 Elena Zannoni <ezannoni@redhat.com>
* solib-svr4.c (svr4_fetch_objfile_link_map): New function.
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 16a1c42..d6de7ef 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -410,6 +410,12 @@ 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
@@ -4788,6 +4794,14 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
"external variable");
}
add_symbol_to_list (sym, &global_symbols);
+ if (is_thread_local)
+ {
+ /* SYMBOL_VALUE_ADDRESS contains at this point the
+ offset of the variable within the thread local
+ storage. */
+ SYMBOL_CLASS (sym) = LOC_THREAD_LOCAL_STATIC;
+ SYMBOL_OBJFILE (sym) = objfile;
+ }
/* In shared libraries the address of the variable
in the location descriptor might still be relocatable,
@@ -4796,7 +4810,7 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
value is zero, the address of the variable will then
be determined from the minimal symbol table whenever
the variable is referenced. */
- if (SYMBOL_VALUE_ADDRESS (sym))
+ else if (SYMBOL_VALUE_ADDRESS (sym))
{
fixup_symbol_section (sym, objfile);
SYMBOL_VALUE_ADDRESS (sym) +=
@@ -4846,6 +4860,11 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
{
SYMBOL_CLASS (sym) = LOC_LOCAL;
}
+ else if (is_thread_local)
+ {
+ SYMBOL_CLASS (sym) = LOC_THREAD_LOCAL_STATIC;
+ SYMBOL_OBJFILE (sym) = objfile;
+ }
else
{
fixup_symbol_section (sym, objfile);
@@ -6358,6 +6377,7 @@ 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)
@@ -6581,6 +6601,16 @@ decode_locdesc (struct dwarf_block *blk, struct objfile *objfile,
complain (&dwarf2_complex_location_expr);
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
+ be returned. */
+ if (i < size)
+ complain (&dwarf2_complex_location_expr);
+ break;
+
default:
complain (&dwarf2_unsupported_stack_op, dwarf_stack_op_name (op));
return (stack[stacki]);
diff --git a/gdb/findvar.c b/gdb/findvar.c
index e48ccc6..9eff168 100644
--- a/gdb/findvar.c
+++ b/gdb/findvar.c
@@ -542,6 +542,23 @@ addresses have not been bound by the dynamic loader. Try again when executable i
break;
}
+ case LOC_THREAD_LOCAL_STATIC:
+ {
+ /* We want to let the target / ABI-specific code construct
+ this value for us, so we need to dispose of the value
+ allocated for us above. */
+ 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 2f7f865..2bf5fdf 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -1285,6 +1285,12 @@ 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 520e81e..b84cac6 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -629,6 +629,14 @@ 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. */
@@ -698,6 +706,12 @@ 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;
}
aux_value;
@@ -719,6 +733,7 @@ struct symbol
#define SYMBOL_TYPE(symbol) (symbol)->type
#define SYMBOL_LINE(symbol) (symbol)->line
#define SYMBOL_BASEREG(symbol) (symbol)->aux_value.basereg
+#define SYMBOL_OBJFILE(symbol) (symbol)->aux_value.objfile
#define SYMBOL_ALIASES(symbol) (symbol)->aliases
#define SYMBOL_RANGES(symbol) (symbol)->ranges