From patchwork Sat Feb 9 00:40:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Baldwin X-Patchwork-Id: 31385 Received: (qmail 78262 invoked by alias); 9 Feb 2019 00:50:50 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 78217 invoked by uid 89); 9 Feb 2019 00:50:49 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.2 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_HELO_PASS, SPF_SOFTFAIL autolearn=ham version=3.3.2 spammy= X-HELO: mail.baldwin.cx Received: from bigwig.baldwin.cx (HELO mail.baldwin.cx) (96.47.65.170) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sat, 09 Feb 2019 00:50:42 +0000 Received: from ralph.com (ralph.baldwin.cx [66.234.199.215]) by mail.baldwin.cx (Postfix) with ESMTPSA id BA55D10B670 for ; Fri, 8 Feb 2019 19:42:36 -0500 (EST) From: John Baldwin To: gdb-patches@sourceware.org Subject: [PATCH v2 04/11] Add a new gdbarch method to resolve the address of TLS variables. Date: Fri, 8 Feb 2019 16:40:07 -0800 Message-Id: <4db33aead3f31532b7d4e165d9786df792a4d925.1549672588.git.jhb@FreeBSD.org> In-Reply-To: References: MIME-Version: 1.0 X-IsSubscribed: yes Permit TLS variable addresses to be resolved purely by an ABI rather than requiring a target method. This doesn't try the target method if the ABI function is present (even if the ABI function fails) to simplify error handling. gdb/ChangeLog: * gdbarch.sh (get_thread_local_address): New method. * gdbarch.h, gdbarch.c: Regenerate. * target.c (target_translate_tls_address): Use gdbarch_get_thread_local_address if present instead of target::get_thread_local_address. --- gdb/ChangeLog | 8 ++++++++ gdb/gdbarch.c | 32 ++++++++++++++++++++++++++++++++ gdb/gdbarch.h | 6 ++++++ gdb/gdbarch.sh | 1 + gdb/target.c | 13 ++++++++----- 5 files changed, 55 insertions(+), 5 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 7f4e912ad3..621b9af800 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,11 @@ +2019-02-08 John Baldwin + + * gdbarch.sh (get_thread_local_address): New method. + * gdbarch.h, gdbarch.c: Regenerate. + * target.c (target_translate_tls_address): Use + gdbarch_get_thread_local_address if present instead of + target::get_thread_local_address. + 2019-02-08 John Baldwin * solib-svr4.c (svr4_fetch_objfile_link_map): Look for diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index 434ee3bfcf..2b3fcef004 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -251,6 +251,7 @@ struct gdbarch CORE_ADDR deprecated_function_start_offset; gdbarch_remote_register_number_ftype *remote_register_number; gdbarch_fetch_tls_load_module_address_ftype *fetch_tls_load_module_address; + gdbarch_get_thread_local_address_ftype *get_thread_local_address; CORE_ADDR frame_args_skip; gdbarch_unwind_pc_ftype *unwind_pc; gdbarch_unwind_sp_ftype *unwind_sp; @@ -613,6 +614,7 @@ verify_gdbarch (struct gdbarch *gdbarch) /* Skip verify of deprecated_function_start_offset, invalid_p == 0 */ /* Skip verify of remote_register_number, invalid_p == 0 */ /* Skip verify of fetch_tls_load_module_address, has predicate. */ + /* Skip verify of get_thread_local_address, has predicate. */ /* Skip verify of frame_args_skip, invalid_p == 0 */ /* Skip verify of unwind_pc, invalid_p == 0 */ /* Skip verify of unwind_sp, invalid_p == 0 */ @@ -1073,6 +1075,12 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) fprintf_unfiltered (file, "gdbarch_dump: get_syscall_number = <%s>\n", host_address_to_string (gdbarch->get_syscall_number)); + fprintf_unfiltered (file, + "gdbarch_dump: gdbarch_get_thread_local_address_p() = %d\n", + gdbarch_get_thread_local_address_p (gdbarch)); + fprintf_unfiltered (file, + "gdbarch_dump: get_thread_local_address = <%s>\n", + host_address_to_string (gdbarch->get_thread_local_address)); fprintf_unfiltered (file, "gdbarch_dump: gnu_triplet_regexp = <%s>\n", host_address_to_string (gdbarch->gnu_triplet_regexp)); @@ -3018,6 +3026,30 @@ set_gdbarch_fetch_tls_load_module_address (struct gdbarch *gdbarch, gdbarch->fetch_tls_load_module_address = fetch_tls_load_module_address; } +int +gdbarch_get_thread_local_address_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->get_thread_local_address != NULL; +} + +CORE_ADDR +gdbarch_get_thread_local_address (struct gdbarch *gdbarch, ptid_t ptid, CORE_ADDR lm_addr, CORE_ADDR offset) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->get_thread_local_address != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_get_thread_local_address called\n"); + return gdbarch->get_thread_local_address (gdbarch, ptid, lm_addr, offset); +} + +void +set_gdbarch_get_thread_local_address (struct gdbarch *gdbarch, + gdbarch_get_thread_local_address_ftype get_thread_local_address) +{ + gdbarch->get_thread_local_address = get_thread_local_address; +} + CORE_ADDR gdbarch_frame_args_skip (struct gdbarch *gdbarch) { diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index 5b265a462a..e11144941f 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -649,6 +649,12 @@ typedef CORE_ADDR (gdbarch_fetch_tls_load_module_address_ftype) (struct objfile extern CORE_ADDR gdbarch_fetch_tls_load_module_address (struct gdbarch *gdbarch, struct objfile *objfile); extern void set_gdbarch_fetch_tls_load_module_address (struct gdbarch *gdbarch, gdbarch_fetch_tls_load_module_address_ftype *fetch_tls_load_module_address); +extern int gdbarch_get_thread_local_address_p (struct gdbarch *gdbarch); + +typedef CORE_ADDR (gdbarch_get_thread_local_address_ftype) (struct gdbarch *gdbarch, ptid_t ptid, CORE_ADDR lm_addr, CORE_ADDR offset); +extern CORE_ADDR gdbarch_get_thread_local_address (struct gdbarch *gdbarch, ptid_t ptid, CORE_ADDR lm_addr, CORE_ADDR offset); +extern void set_gdbarch_get_thread_local_address (struct gdbarch *gdbarch, gdbarch_get_thread_local_address_ftype *get_thread_local_address); + extern CORE_ADDR gdbarch_frame_args_skip (struct gdbarch *gdbarch); extern void set_gdbarch_frame_args_skip (struct gdbarch *gdbarch, CORE_ADDR frame_args_skip); diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh index afc4da7cdd..09097bcbaf 100755 --- a/gdb/gdbarch.sh +++ b/gdb/gdbarch.sh @@ -602,6 +602,7 @@ m;int;remote_register_number;int regno;regno;;default_remote_register_number;;0 # Fetch the target specific address used to represent a load module. F;CORE_ADDR;fetch_tls_load_module_address;struct objfile *objfile;objfile +M;CORE_ADDR;get_thread_local_address;ptid_t ptid, CORE_ADDR lm_addr, CORE_ADDR offset;ptid, lm_addr, offset # v;CORE_ADDR;frame_args_skip;;;0;;;0 m;CORE_ADDR;unwind_pc;struct frame_info *next_frame;next_frame;;default_unwind_pc;;0 diff --git a/gdb/target.c b/gdb/target.c index c1ab07f760..9864103826 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -691,8 +691,9 @@ target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset) { volatile CORE_ADDR addr = 0; struct target_ops *target = current_top_target (); + struct gdbarch *gdbarch = target_gdbarch (); - if (gdbarch_fetch_tls_load_module_address_p (target_gdbarch ())) + if (gdbarch_fetch_tls_load_module_address_p (gdbarch)) { ptid_t ptid = inferior_ptid; @@ -701,10 +702,14 @@ target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset) CORE_ADDR lm_addr; /* Fetch the load module address for this objfile. */ - lm_addr = gdbarch_fetch_tls_load_module_address (target_gdbarch (), + lm_addr = gdbarch_fetch_tls_load_module_address (gdbarch, objfile); - addr = target->get_thread_local_address (ptid, lm_addr, offset); + if (gdbarch_get_thread_local_address_p (gdbarch)) + addr = gdbarch_get_thread_local_address (gdbarch, ptid, lm_addr, + offset); + else + addr = target->get_thread_local_address (ptid, lm_addr, offset); } /* If an error occurred, print TLS related messages here. Otherwise, throw the error to some higher catcher. */ @@ -759,8 +764,6 @@ target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset) } END_CATCH } - /* 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"));