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.
This commit is contained in:
parent
b41b1f95b7
commit
c3228f1238
9 changed files with 65 additions and 43 deletions
|
@ -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
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
14
gdb/symtab.h
14
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
|
||||
|
|
Loading…
Add table
Reference in a new issue