This is the mail archive of the gdb-cvs@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] aarch64 multi-arch (part 3): get thread area


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=a0cc84cd15396df7752fe16659c01628ba729324

commit a0cc84cd15396df7752fe16659c01628ba729324
Author: Yao Qi <yao.qi@linaro.org>
Date:   Fri Sep 18 13:59:42 2015 +0100

    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.

Diff:
---
 gdb/ChangeLog                     | 10 ++++++++++
 gdb/aarch64-linux-nat.c           | 17 +++-------------
 gdb/gdbserver/ChangeLog           |  5 +++++
 gdb/gdbserver/linux-aarch64-low.c | 18 ++---------------
 gdb/nat/aarch64-linux.c           | 42 +++++++++++++++++++++++++++++++++++++++
 gdb/nat/aarch64-linux.h           |  7 +++++++
 6 files changed, 69 insertions(+), 30 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 61e435e..074417d 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,13 @@
+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.
+
 2015-09-18  Markus Metzger  <markus.t.metzger@intel.com>
 
 	* record-btrace.c (record_btrace_resume): Honour scheduler-locking.
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/ChangeLog b/gdb/gdbserver/ChangeLog
index c018f28..bef1d57 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,3 +1,8 @@
+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.
+
 2015-09-16  Wei-cheng Wang  <cole945@gmail.com>
 
 	* tracepoint.c (eval_result_type): Change prototype.
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 */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]