diff options
author | Markus Metzger <markus.t.metzger@intel.com> | 2015-01-29 10:43:05 +0100 |
---|---|---|
committer | Markus Metzger <markus.t.metzger@intel.com> | 2015-03-03 12:47:41 +0100 |
commit | d68e53f47932eb7c374df9b90faed7aca2eed9d7 (patch) | |
tree | 47015cbfe454f85ccfb6c95577800d86767712ad | |
parent | 986b66010c684a871f5606cb4f074d4e3d829e2f (diff) | |
download | gdb-d68e53f47932eb7c374df9b90faed7aca2eed9d7.zip gdb-d68e53f47932eb7c374df9b90faed7aca2eed9d7.tar.gz gdb-d68e53f47932eb7c374df9b90faed7aca2eed9d7.tar.bz2 |
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.
-rw-r--r-- | gdb/ChangeLog | 8 | ||||
-rw-r--r-- | gdb/gdbserver/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/gdbserver/linux-low.c | 2 | ||||
-rw-r--r-- | gdb/nat/linux-btrace.c | 28 | ||||
-rw-r--r-- | gdb/x86-linux-nat.c | 8 |
5 files changed, 46 insertions, 5 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 3e9fa55..1db98ff 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,13 @@ 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 "_dl_runtime_resolve". diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index 4569853..208601d 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -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) diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index a278c9a..452d0fc 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.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); diff --git a/gdb/nat/linux-btrace.c b/gdb/nat/linux-btrace.c index 3093a5c..e7aff5e 100644 --- a/gdb/nat/linux-btrace.c +++ b/gdb/nat/linux-btrace.c @@ -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; diff --git a/gdb/x86-linux-nat.c b/gdb/x86-linux-nat.c index c58c01a..7f038f0 100644 --- a/gdb/x86-linux-nat.c +++ b/gdb/x86-linux-nat.c @@ -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; } |