btrace: support 32-bit inferior on 64-bit host
authorMarkus Metzger <markus.t.metzger@intel.com>
Thu, 29 Jan 2015 09:43:05 +0000 (10:43 +0100)
committerMarkus Metzger <markus.t.metzger@intel.com>
Tue, 3 Mar 2015 11:47:41 +0000 (12:47 +0100)
The heuristic for filtering out kernel addressess in BTS trace checks the
most significant bit in each address.  This works fine for 32-bit and 64-bit
mode.

For 32-bit compatibility mode, i.e. a 32-bit inferior running on 64-bit
host, we need to check bit 63 (or any bit bigger than 31), not bit 31.

Use the machine field in struct utsname provided by a uname call to
determine whether we are running on a 64-bit host.

Thanks to Jan Kratochvil for reporting the issue.

gdb/
* nat/linux-btrace.c: Include sys/utsname.h.
(linux_determine_kernel_ptr_bits): New.
(linux_enable_bts): Call linux_determine_kernel_ptr_bits.
* x86-linux-nat.c (x86_linux_enable_btrace): Do not overwrite non-zero
ptr_bits.

gdbserver/
* linux-low.c (linux_low_enable_btrace): Do not overwrite non-zero
ptr_bits.

gdb/ChangeLog
gdb/gdbserver/ChangeLog
gdb/gdbserver/linux-low.c
gdb/nat/linux-btrace.c
gdb/x86-linux-nat.c

index 3e9fa55e9573863baae57bc21b1206d752d81be4..1db98ff9f6738dffa20aefe6d958c34b9b94575d 100644 (file)
@@ -1,3 +1,11 @@
+2015-03-03  Markus Metzger  <markus.t.metzger@intel.com>
+
+       * nat/linux-btrace.c: Include sys/utsname.h.
+       (linux_determine_kernel_ptr_bits): New.
+       (linux_enable_bts): Call linux_determine_kernel_ptr_bits.
+       * x86-linux-nat.c (x86_linux_enable_btrace): Do not overwrite non-zero
+       ptr_bits.
+
 2015-03-03  Markus Metzger  <markus.t.metzger@intel.com>
 
        * btrace.c (ftrace_update_function): Treat return as tailcall for
index 456985386c817289efdb3f68c2a6cb19b15a8c40..208601d1d6bb01a92f6751b28dc806926fcac603 100644 (file)
@@ -1,3 +1,8 @@
+2015-03-03  Markus Metzger  <markus.t.metzger@intel.com>
+
+       * linux-low.c (linux_low_enable_btrace): Do not overwrite non-zero
+       ptr_bits.
+
 2015-03-02  Andreas Arnez  <arnez@linux.vnet.ibm.com>
 
        * Makefile.in (s390-vx-linux64.c, s390-tevx-linux64.c)
index a278c9a7a0c022b5d4f803bdb70f290ed9081112..452d0fcecebfadd98ce4e6077a4ecf7c93ed6cc1 100644 (file)
@@ -5956,7 +5956,7 @@ linux_low_enable_btrace (ptid_t ptid, const struct btrace_config *conf)
 
   tinfo = linux_enable_btrace (ptid, conf);
 
-  if (tinfo != NULL)
+  if (tinfo != NULL && tinfo->ptr_bits == 0)
     {
       struct thread_info *thread = find_thread_ptid (ptid);
       struct regcache *regcache = get_thread_regcache (thread, 0);
index 3093a5cf8c7f98df6f9a8ff326cfdd3e4e4e627d..e7aff5e4ad3782f41348bdc8dc2bd2032738d209 100644 (file)
@@ -38,6 +38,7 @@
 #include <sys/ptrace.h>
 #include <sys/types.h>
 #include <signal.h>
+#include <sys/utsname.h>
 
 /* A branch trace record in perf_event.  */
 struct perf_event_bts
@@ -102,6 +103,31 @@ perf_event_new_data (const struct perf_event_buffer *pev)
   return *pev->data_head != pev->last_head;
 }
 
+/* Try to determine the size of a pointer in bits for the OS.
+
+   This is the same as the size of a pointer for the inferior process
+   except when a 32-bit inferior is running on a 64-bit OS.  */
+
+static int
+linux_determine_kernel_ptr_bits (void)
+{
+  struct utsname utsn;
+  int errcode;
+
+  memset (&utsn, 0, sizeof (utsn));
+
+  errcode = uname (&utsn);
+  if (errcode < 0)
+    return 0;
+
+  /* We only need to handle the 64-bit host case, here.  For 32-bit host,
+     the pointer size can be filled in later based on the inferior.  */
+  if (strcmp (utsn.machine, "x86_64") == 0)
+    return 64;
+
+  return 0;
+}
+
 /* Check whether an address is in the kernel.  */
 
 static inline int
@@ -434,7 +460,7 @@ linux_enable_bts (ptid_t ptid, const struct btrace_config_bts *conf)
 
   tinfo = xzalloc (sizeof (*tinfo));
   tinfo->ptid = ptid;
-  tinfo->ptr_bits = 0;
+  tinfo->ptr_bits = linux_determine_kernel_ptr_bits ();
 
   tinfo->conf.format = BTRACE_FORMAT_BTS;
   bts = &tinfo->variant.bts;
index c58c01a2bb74eb20f599bff804c8eecf10ffddb7..7f038f01b563e7e810281fcdccd0c42cb433bbdc 100644 (file)
@@ -450,9 +450,11 @@ x86_linux_enable_btrace (struct target_ops *self, ptid_t ptid,
           target_pid_to_str (ptid), safe_strerror (errno));
 
   /* Fill in the size of a pointer in bits.  */
-  gdbarch = target_thread_architecture (ptid);
-  tinfo->ptr_bits = gdbarch_ptr_bit (gdbarch);
-
+  if (tinfo->ptr_bits == 0)
+    {
+      gdbarch = target_thread_architecture (ptid);
+      tinfo->ptr_bits = gdbarch_ptr_bit (gdbarch);
+    }
   return tinfo;
 }
 
This page took 0.03909 seconds and 4 git commands to generate.