From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27299 invoked by alias); 2 Oct 2002 03:06:48 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 27251 invoked from network); 2 Oct 2002 03:06:47 -0000 Received: from unknown (HELO mx1.redhat.com) (66.187.233.31) by sources.redhat.com with SMTP; 2 Oct 2002 03:06:47 -0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.11.6/8.11.6) with ESMTP id g922m0i05336 for ; Tue, 1 Oct 2002 22:48:00 -0400 Received: from pobox.corp.redhat.com (pobox.corp.redhat.com [172.16.52.156]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id g9236kf28335 for ; Tue, 1 Oct 2002 23:06:46 -0400 Received: from localhost.redhat.com (IDENT:root@tooth.toronto.redhat.com [172.16.14.29]) by pobox.corp.redhat.com (8.11.6/8.11.6) with ESMTP id g9236jj11338 for ; Tue, 1 Oct 2002 23:06:45 -0400 Received: by localhost.redhat.com (Postfix, from userid 469) id 61752FF79; Tue, 1 Oct 2002 23:04:19 -0400 (EDT) From: Elena Zannoni MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Message-ID: <15770.25139.262675.365054@localhost.redhat.com> Date: Tue, 01 Oct 2002 20:06:00 -0000 To: gdb-patches@sources.redhat.com Subject: [PATCH/RFC] TLS support part 1 X-SW-Source: 2002-10/txt/msg00039.txt.bz2 This part of the tls changes deal with the symbol handling. I.e. recognizes the debug information, and sets up variables with the appropriate address information. Then it requests the address to be computed by the target/thread code. BTW: the debug info looks like this (in a simple case): <1><1e2c>: Abbrev Number: 32 (DW_TAG_variable) DW_AT_name : (indirect string, offset: 0xc0d): a_tls DW_AT_decl_file : 1 DW_AT_decl_line : 4 DW_AT_type : DW_AT_external : 1 DW_AT_location : 6 byte block: 3 0 0 0 0 e0 (DW_OP_addr: 0; DW_OP_GNU_push_tls_address; ) <1><1e3f>: Abbrev Number: 32 (DW_TAG_variable) DW_AT_name : (indirect string, offset: 0xb42): b_tls DW_AT_decl_file : 1 DW_AT_decl_line : 5 DW_AT_type : DW_AT_external : 1 DW_AT_location : 6 byte block: 3 4 0 0 0 e0 (DW_OP_addr: 4; DW_OP_GNU_push_tls_address; ) <1><1e52>: Abbrev Number: 32 (DW_TAG_variable) DW_AT_name : (indirect string, offset: 0xaa8): c_tls DW_AT_decl_file : 1 DW_AT_decl_line : 6 DW_AT_type : DW_AT_external : 1 DW_AT_location : 6 byte block: 3 8 0 0 0 e0 (DW_OP_addr: 8; DW_OP_GNU_push_tls_address; ) I.e. a_tls, b_tls, c_tls are thread local storage variables at offset 0, 4, 8 respectively within the thread local storage. The next patch will deal with the actual computation of the address. Elena 2002-10-01 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. Index: symtab.h =================================================================== RCS file: /cvs/src/src/gdb/symtab.h,v retrieving revision 1.42 diff -u -p -r1.42 symtab.h --- symtab.h 20 Sep 2002 14:58:58 -0000 1.42 +++ symtab.h 2 Oct 2002 02:52:57 -0000 @@ -611,8 +611,16 @@ enum address_class target-specific method. This is used only by hppa. */ 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 + o + /* 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. @@ -684,6 +692,12 @@ struct symbol { /* Used by LOC_BASEREG and LOC_BASEREG_ARG. */ short basereg; + + /* 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; @@ -705,6 +719,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 Index: dwarf2read.c =================================================================== RCS file: /cvs/src/src/gdb/dwarf2read.c,v retrieving revision 1.67 diff -u -p -r1.67 dwarf2read.c --- dwarf2read.c 1 Oct 2002 23:51:43 -0000 1.67 +++ dwarf2read.c 2 Oct 2002 02:58:26 -0000 @@ -389,6 +389,12 @@ static int islocal; /* Variable is at t 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 @@ -4724,6 +4730,14 @@ new_symbol (struct die_info *die, struct "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, @@ -4732,7 +4746,7 @@ new_symbol (struct die_info *die, struct 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) += @@ -4782,6 +4796,11 @@ new_symbol (struct die_info *die, struct { 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); @@ -6294,6 +6313,7 @@ decode_locdesc (struct dwarf_block *blk, offreg = 0; isderef = 0; islocal = 0; + is_thread_local = 0; optimized_out = 1; while (i < size) @@ -6516,6 +6536,16 @@ decode_locdesc (struct dwarf_block *blk, if (i < size) 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)); Index: findvar.c =================================================================== RCS file: /cvs/src/src/gdb/findvar.c,v retrieving revision 1.35 diff -u -p -r1.35 findvar.c --- findvar.c 24 Jul 2002 22:46:48 -0000 1.35 +++ findvar.c 2 Oct 2002 02:59:09 -0000 @@ -540,6 +540,23 @@ addresses have not been bound by the dyn addr = value_as_address (regval); addr += SYMBOL_VALUE (var); 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: Index: printcmd.c =================================================================== RCS file: /cvs/src/src/gdb/printcmd.c,v retrieving revision 1.43 diff -u -p -r1.43 printcmd.c --- printcmd.c 19 Sep 2002 03:58:41 -0000 1.43 +++ printcmd.c 2 Oct 2002 03:00:20 -0000 @@ -1275,10 +1275,16 @@ address_info (char *exp, int from_tty) "a thread-local variable at offset %ld from the thread base register %s", 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: