diff options
author | Yao Qi <yao.qi@linaro.org> | 2015-09-18 13:59:42 +0100 |
---|---|---|
committer | Yao Qi <yao.qi@linaro.org> | 2015-09-18 13:59:42 +0100 |
commit | a0cc84cd15396df7752fe16659c01628ba729324 (patch) | |
tree | 32792ead6e959a72eeffd4257571fb3e56797e06 /gdb/nat | |
parent | d2939ba2b40daa89b501d4b81484ea888ef17139 (diff) | |
download | gdb-a0cc84cd15396df7752fe16659c01628ba729324.zip gdb-a0cc84cd15396df7752fe16659c01628ba729324.tar.gz gdb-a0cc84cd15396df7752fe16659c01628ba729324.tar.bz2 |
aarch64 multi-arch (part 3): get thread area
With the kernle fix <http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/356511.html>,
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-18 Yao Qi <yao.qi@linaro.org>
* 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-18 Yao Qi <yao.qi@linaro.org>
* linux-aarch64-low.c: Don't include sys/uio.h.
(ps_get_thread_area): Call aarch64_ps_get_thread_area.
Diffstat (limited to 'gdb/nat')
-rw-r--r-- | gdb/nat/aarch64-linux.c | 42 | ||||
-rw-r--r-- | gdb/nat/aarch64-linux.h | 7 |
2 files changed, 49 insertions, 0 deletions
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 <asm/ptrace.h> +#include <sys/uio.h> + /* 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 <signal.h> +/* 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 */ |