diff mbox

aarch64 multi-arch (part 3): get thread area

Message ID 1442475517-32501-1-git-send-email-yao.qi@linaro.org
State New
Headers show

Commit Message

Yao Qi Sept. 17, 2015, 7:38 a.m. UTC
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-17  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-17  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.
---
 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(-)

Comments

Yao Qi Sept. 18, 2015, 1 p.m. UTC | #1
Yao Qi <qiyaoltc@gmail.com> writes:

> gdb:
>
> 2015-09-17  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-17  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.

Patch is pushed in.
diff mbox

Patch

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 = &reg;
-  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 <sys/user.h>
 #include "nat/gdb_ptrace.h"
 #include <asm/ptrace.h>
-#include <sys/uio.h>
 
 #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 = &reg;
-  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 <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 = &reg64;
+      iovec.iov_len = sizeof (reg64);
+    }
+  else
+    {
+      iovec.iov_base = &reg32;
+      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 */