From c08834975df1b218495e7bc366a30e53a711f905 Mon Sep 17 00:00:00 2001 From: Elena Zannoni Date: Mon, 21 Oct 2002 19:11:50 +0000 Subject: [PATCH] 2002-10-21 Jim Blandy Elena Zannoni * 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. --- gdb/ChangeLog | 17 +++++++++++++++++ gdb/dwarf2read.c | 32 +++++++++++++++++++++++++++++++- gdb/findvar.c | 17 +++++++++++++++++ gdb/printcmd.c | 6 ++++++ gdb/symtab.h | 15 +++++++++++++++ 5 files changed, 86 insertions(+), 1 deletion(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 738246d66f..09ecdbe8e9 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,20 @@ +2002-10-21 Jim Blandy + Elena Zannoni + + * 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 * solib-svr4.c (svr4_fetch_objfile_link_map): New function. diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 16a1c4225d..d6de7ef4cc 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 e48ccc6f4a..9eff168ddc 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 2f7f865c6f..2bf5fdf4d0 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 520e81efef..b84cac69ce 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 -- 2.11.0