From patchwork Thu Sep 17 07:38:37 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yao Qi X-Patchwork-Id: 8737 Received: (qmail 127219 invoked by alias); 17 Sep 2015 07:38:49 -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 127207 invoked by uid 89); 17 Sep 2015 07:38:48 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-wi0-f171.google.com Received: from mail-wi0-f171.google.com (HELO mail-wi0-f171.google.com) (209.85.212.171) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Thu, 17 Sep 2015 07:38:45 +0000 Received: by wiclk2 with SMTP id lk2so11516870wic.0 for ; Thu, 17 Sep 2015 00:38:42 -0700 (PDT) X-Received: by 10.180.186.195 with SMTP id fm3mr27438942wic.1.1442475520173; Thu, 17 Sep 2015 00:38:40 -0700 (PDT) Received: from E107787-LIN.cambridge.arm.com ([195.154.84.196]) by smtp.gmail.com with ESMTPSA id s16sm8499677wik.13.2015.09.17.00.38.38 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 17 Sep 2015 00:38:39 -0700 (PDT) From: Yao Qi X-Google-Original-From: Yao Qi To: gdb-patches@sourceware.org Subject: [PATCH] aarch64 multi-arch (part 3): get thread area Date: Thu, 17 Sep 2015 08:38:37 +0100 Message-Id: <1442475517-32501-1-git-send-email-yao.qi@linaro.org> X-IsSubscribed: yes With the kernle fix , aarch64 GDB is able to read the base of thread area of 32-bit arm program through NT_ARM_TLS. This patch is to teach both GDB and GDBserver to read the base of thread area correctly in the multi-arch case. A new function aarch64_ps_get_thread_area is added, and is shared between GDB and GDBserver. With this patch applied, the following fails in multi-arch testing (GDB is aarch64 but the test cases are arm) are fixed, -FAIL: gdb.threads/tls-nodebug.exp: thread local storage -FAIL: gdb.threads/tls-shared.exp: print thread local storage variable -FAIL: gdb.threads/tls-so_extern.exp: print thread local storage variable -FAIL: gdb.threads/tls-var.exp: print tls_var -FAIL: gdb.threads/tls.exp: first thread local storage -FAIL: gdb.threads/tls.exp: first another thread local storage -FAIL: gdb.threads/tls.exp: p a_thread_local -FAIL: gdb.threads/tls.exp: p file2_thread_local -FAIL: gdb.threads/tls.exp: p a_thread_local second time gdb: 2015-09-17 Yao Qi * nat/aarch64-linux.c: Include elf/common.h, nat/gdb_ptrace.h, asm/ptrace.h and sys/uio.h. (aarch64_ps_get_thread_area): New function. * nat/aarch64-linux.h: Include gdb_proc_service.h. (aarch64_ps_get_thread_area): Declare. * aarch64-linux-nat.c (ps_get_thread_area): Call aarch64_ps_get_thread_area. gdb/gdbserver: 2015-09-17 Yao Qi * linux-aarch64-low.c: Don't include sys/uio.h. (ps_get_thread_area): Call aarch64_ps_get_thread_area. --- gdb/aarch64-linux-nat.c | 17 +++------------- gdb/gdbserver/linux-aarch64-low.c | 18 ++--------------- gdb/nat/aarch64-linux.c | 42 +++++++++++++++++++++++++++++++++++++++ gdb/nat/aarch64-linux.h | 7 +++++++ 4 files changed, 54 insertions(+), 30 deletions(-) diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c index d7ac19e..c9f439f 100644 --- a/gdb/aarch64-linux-nat.c +++ b/gdb/aarch64-linux-nat.c @@ -460,21 +460,10 @@ ps_err_e ps_get_thread_area (const struct ps_prochandle *ph, lwpid_t lwpid, int idx, void **base) { - struct iovec iovec; - uint64_t reg; - - iovec.iov_base = ® - iovec.iov_len = sizeof (reg); - - if (ptrace (PTRACE_GETREGSET, lwpid, NT_ARM_TLS, &iovec) != 0) - return PS_ERR; - - /* IDX is the bias from the thread pointer to the beginning of the - thread descriptor. It has to be subtracted due to implementation - quirks in libthread_db. */ - *base = (void *) (reg - idx); + int is_64bit_p + = (gdbarch_bfd_arch_info (target_gdbarch ())->bits_per_word == 64); - return PS_OK; + return aarch64_ps_get_thread_area (ph, lwpid, idx, base, is_64bit_p); } diff --git a/gdb/gdbserver/linux-aarch64-low.c b/gdb/gdbserver/linux-aarch64-low.c index 73b248c..0ba58dd 100644 --- a/gdb/gdbserver/linux-aarch64-low.c +++ b/gdb/gdbserver/linux-aarch64-low.c @@ -30,7 +30,6 @@ #include #include "nat/gdb_ptrace.h" #include -#include #include "gdb_proc_service.h" @@ -413,21 +412,8 @@ ps_err_e ps_get_thread_area (const struct ps_prochandle *ph, lwpid_t lwpid, int idx, void **base) { - struct iovec iovec; - uint64_t reg; - - iovec.iov_base = ® - iovec.iov_len = sizeof (reg); - - if (ptrace (PTRACE_GETREGSET, lwpid, NT_ARM_TLS, &iovec) != 0) - return PS_ERR; - - /* IDX is the bias from the thread pointer to the beginning of the - thread descriptor. It has to be subtracted due to implementation - quirks in libthread_db. */ - *base = (void *) (reg - idx); - - return PS_OK; + return aarch64_ps_get_thread_area (ph, lwpid, idx, base, + is_64bit_tdesc ()); } /* Implementation of linux_target_ops method "siginfo_fixup". */ diff --git a/gdb/nat/aarch64-linux.c b/gdb/nat/aarch64-linux.c index 0634094..dbd7dff 100644 --- a/gdb/nat/aarch64-linux.c +++ b/gdb/nat/aarch64-linux.c @@ -22,6 +22,11 @@ #include "nat/aarch64-linux-hw-point.h" #include "nat/aarch64-linux.h" +#include "elf/common.h" +#include "nat/gdb_ptrace.h" +#include +#include + /* Called when resuming a thread LWP. The hardware debug registers are updated when there is any change. */ @@ -195,3 +200,40 @@ aarch64_siginfo_from_compat_siginfo (siginfo_t *to, compat_siginfo_t *from) } } } + +/* Called by libthread_db. Returns a pointer to the thread local + storage (or its descriptor). */ + +ps_err_e +aarch64_ps_get_thread_area (const struct ps_prochandle *ph, + lwpid_t lwpid, int idx, void **base, + int is_64bit_p) +{ + struct iovec iovec; + uint64_t reg64; + uint32_t reg32; + + if (is_64bit_p) + { + iovec.iov_base = ®64; + iovec.iov_len = sizeof (reg64); + } + else + { + iovec.iov_base = ®32; + iovec.iov_len = sizeof (reg32); + } + + if (ptrace (PTRACE_GETREGSET, lwpid, NT_ARM_TLS, &iovec) != 0) + return PS_ERR; + + /* IDX is the bias from the thread pointer to the beginning of the + thread descriptor. It has to be subtracted due to implementation + quirks in libthread_db. */ + if (is_64bit_p) + *base = (void *) (reg64 - idx); + else + *base = (void *) (uintptr_t) (reg32 - idx); + + return PS_OK; +} diff --git a/gdb/nat/aarch64-linux.h b/gdb/nat/aarch64-linux.h index 89eb4e3..07f85b9 100644 --- a/gdb/nat/aarch64-linux.h +++ b/gdb/nat/aarch64-linux.h @@ -21,6 +21,9 @@ #include +/* Defines ps_err_e, struct ps_prochandle. */ +#include "gdb_proc_service.h" + typedef int compat_int_t; typedef unsigned int compat_uptr_t; @@ -119,4 +122,8 @@ void aarch64_linux_prepare_to_resume (struct lwp_info *lwp); void aarch64_linux_new_thread (struct lwp_info *lwp); +ps_err_e aarch64_ps_get_thread_area (const struct ps_prochandle *ph, + lwpid_t lwpid, int idx, void **base, + int is_64bit_p); + #endif /* AARCH64_LINUX_H */