mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-10-18 05:12:33 +08:00
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:
@ -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>
|
2003-07-22 Andrew Cagney <cagney@redhat.com>
|
||||||
|
|
||||||
* config/pa/tm-hppa64.h (FRAME_SAVED_PC_IN_SIGTRAMP): Use
|
* 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)
|
$(gdbcore_h) $(dwarf2expr_h)
|
||||||
dwarf2loc.o: dwarf2loc.c $(defs_h) $(ui_out_h) $(value_h) $(frame_h) \
|
dwarf2loc.o: dwarf2loc.c $(defs_h) $(ui_out_h) $(value_h) $(frame_h) \
|
||||||
$(gdbcore_h) $(target_h) $(inferior_h) $(dwarf2expr_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) \
|
dwarf2-frame.o: $(defs_h) $(dwarf2expr_h) $(elf_dwarf2_h) $(frame_h) \
|
||||||
$(frame_base_h) $(frame_unwind_h) $(gdbcore_h) $(gdbtypes_h) \
|
$(frame_base_h) $(frame_unwind_h) $(gdbcore_h) $(gdbtypes_h) \
|
||||||
$(symtab_h) $(objfiles_h) $(regcache_h) $(gdb_assert_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;
|
break;
|
||||||
|
|
||||||
case DW_OP_GNU_push_tls_address:
|
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);
|
result = dwarf_expr_fetch (ctx, 0);
|
||||||
dwarf_expr_pop (ctx);
|
dwarf_expr_pop (ctx);
|
||||||
result = (ctx->get_tls_address) (ctx->baton, result);
|
result = (ctx->get_tls_address) (ctx->baton, result);
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include "ax.h"
|
#include "ax.h"
|
||||||
#include "ax-gdb.h"
|
#include "ax-gdb.h"
|
||||||
#include "regcache.h"
|
#include "regcache.h"
|
||||||
|
#include "objfiles.h"
|
||||||
|
|
||||||
#include "elf/dwarf2.h"
|
#include "elf/dwarf2.h"
|
||||||
#include "dwarf2expr.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,
|
addr = target_get_thread_local_address (inferior_ptid,
|
||||||
debaton->objfile,
|
debaton->objfile,
|
||||||
offset);
|
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
|
else
|
||||||
error ("Cannot find thread-local variables on this target");
|
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;
|
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,
|
fprintf_filtered (stream,
|
||||||
"a variable with complex or multiple locations (DWARF2)");
|
"a variable with complex or multiple locations (DWARF2)");
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -55,6 +55,10 @@ struct dwarf2_loclist_baton
|
|||||||
unsigned short size;
|
unsigned short size;
|
||||||
|
|
||||||
/* The objfile containing the symbol whose location we're computing. */
|
/* 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;
|
struct objfile *objfile;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -438,12 +438,6 @@ static int islocal; /* Variable is at the returned offset
|
|||||||
this function, so we can't say
|
this function, so we can't say
|
||||||
which register it's relative to;
|
which register it's relative to;
|
||||||
use LOC_LOCAL. */
|
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.
|
/* DW_AT_frame_base values for the current function.
|
||||||
frame_base_reg is -1 if DW_AT_frame_base is missing, otherwise it
|
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;
|
offreg = 0;
|
||||||
isderef = 0;
|
isderef = 0;
|
||||||
islocal = 0;
|
islocal = 0;
|
||||||
is_thread_local = 0;
|
|
||||||
optimized_out = 1;
|
optimized_out = 1;
|
||||||
|
|
||||||
while (i < size)
|
while (i < size)
|
||||||
@ -7014,7 +7007,6 @@ decode_locdesc (struct dwarf_block *blk, struct objfile *objfile,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_OP_GNU_push_tls_address:
|
case DW_OP_GNU_push_tls_address:
|
||||||
is_thread_local = 1;
|
|
||||||
/* 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
|
||||||
|
@ -512,20 +512,6 @@ addresses have not been bound by the dynamic loader. Try again when executable i
|
|||||||
break;
|
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:
|
case LOC_TYPEDEF:
|
||||||
error ("Cannot look up value of a typedef");
|
error ("Cannot look up value of a typedef");
|
||||||
break;
|
break;
|
||||||
|
@ -1262,12 +1262,6 @@ address_info (char *exp, int from_tty)
|
|||||||
val, REGISTER_NAME (basereg));
|
val, REGISTER_NAME (basereg));
|
||||||
break;
|
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:
|
case LOC_OPTIMIZED_OUT:
|
||||||
printf_filtered ("optimized out");
|
printf_filtered ("optimized out");
|
||||||
break;
|
break;
|
||||||
|
14
gdb/symtab.h
14
gdb/symtab.h
@ -482,14 +482,6 @@ enum address_class
|
|||||||
|
|
||||||
LOC_HP_THREAD_LOCAL_STATIC,
|
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 variable does not actually exist in the program.
|
||||||
The value is ignored. */
|
The value is ignored. */
|
||||||
|
|
||||||
@ -606,12 +598,6 @@ struct symbol
|
|||||||
/* Used by LOC_BASEREG and LOC_BASEREG_ARG. */
|
/* Used by LOC_BASEREG and LOC_BASEREG_ARG. */
|
||||||
short basereg;
|
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
|
/* For a LOC_COMPUTED or LOC_COMPUTED_ARG symbol, this is the
|
||||||
baton and location_funcs structure to find its location. For a
|
baton and location_funcs structure to find its location. For a
|
||||||
LOC_BLOCK symbol for a function in a compilation unit compiled
|
LOC_BLOCK symbol for a function in a compilation unit compiled
|
||||||
|
Reference in New Issue
Block a user