btrace: support 32-bit inferior on 64-bit host
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.
This commit is contained in:
parent
986b66010c
commit
d68e53f479
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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. */
|
||||
if (tinfo->ptr_bits == 0)
|
||||
{
|
||||
gdbarch = target_thread_architecture (ptid);
|
||||
tinfo->ptr_bits = gdbarch_ptr_bit (gdbarch);
|
||||
|
||||
}
|
||||
return tinfo;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user