From c3228f12381fe247c089a315455beced163f88e0 Mon Sep 17 00:00:00 2001 From: Elena Zannoni Date: Tue, 22 Jul 2003 15:41:59 +0000 Subject: [PATCH] 2003-07-22 Elena Zannoni * 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. --- gdb/ChangeLog | 20 ++++++++++++++++++++ gdb/Makefile.in | 3 ++- gdb/dwarf2expr.c | 8 ++++++++ gdb/dwarf2loc.c | 31 +++++++++++++++++++++++++++++++ gdb/dwarf2loc.h | 4 ++++ gdb/dwarf2read.c | 8 -------- gdb/findvar.c | 14 -------------- gdb/printcmd.c | 6 ------ gdb/symtab.h | 14 -------------- 9 files changed, 65 insertions(+), 43 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 5438b69b102..9c024d0a07b 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,23 @@ +2003-07-22 Elena Zannoni + + * 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 * config/pa/tm-hppa64.h (FRAME_SAVED_PC_IN_SIGTRAMP): Use diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 95e4439d2b4..8a244b3fa52 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 aa391ebd6a5..3d1523b6010 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 9ed6b7e9665..01a2ddac940 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 b6b4d3325e1..321cb037528 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 1d68efffbd3..115d8db9645 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 2e6a858ab69..7b6191c7d68 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 410b950fe33..3f0bc3c21a8 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 642b96014e2..29df929e536 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 -- 2.30.2