From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1435 invoked by alias); 29 Jan 2015 16:28:58 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 1322 invoked by uid 89); 29 Jan 2015 16:28:56 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.7 required=5.0 tests=AWL,BAYES_00,T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mga14.intel.com Received: from mga14.intel.com (HELO mga14.intel.com) (192.55.52.115) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 29 Jan 2015 16:28:41 +0000 Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga103.fm.intel.com with ESMTP; 29 Jan 2015 08:22:12 -0800 X-ExtLoop1: 1 Received: from irvmail001.ir.intel.com ([163.33.26.43]) by orsmga002.jf.intel.com with ESMTP; 29 Jan 2015 08:28:25 -0800 Received: from ulvlx001.iul.intel.com (ulvlx001.iul.intel.com [172.28.207.17]) by irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id t0TGSOYY020063; Thu, 29 Jan 2015 16:28:24 GMT Received: from ulvlx001.iul.intel.com (localhost [127.0.0.1]) by ulvlx001.iul.intel.com with ESMTP id t0TGSOBe010153; Thu, 29 Jan 2015 17:28:24 +0100 Received: (from mmetzger@localhost) by ulvlx001.iul.intel.com with œ id t0TGSNmD010149; Thu, 29 Jan 2015 17:28:24 +0100 From: Markus Metzger To: palves@redhat.com Cc: gdb-patches@sourceware.org, Jan Kratochvil Subject: [PATCH v3 12/15] btrace: support 32-bit inferior on 64-bit host Date: Thu, 29 Jan 2015 16:29:00 -0000 Message-Id: <1422548899-9789-13-git-send-email-markus.t.metzger@intel.com> In-Reply-To: <1422548899-9789-1-git-send-email-markus.t.metzger@intel.com> References: <1422548899-9789-1-git-send-email-markus.t.metzger@intel.com> X-IsSubscribed: yes X-SW-Source: 2015-01/txt/msg00767.txt.bz2 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. CC: Jan Kratochvil 2015-01-29 Markus Metzger gdb/ * nat/linux-btrace.c: Include sys/utsname.h. (linux_determine_ptr_bits): New. (linux_enable_bts): Call linux_determine_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/gdbserver/linux-low.c | 2 +- gdb/nat/linux-btrace.c | 29 ++++++++++++++++++++++++++++- gdb/x86-linux-nat.c | 8 +++++--- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index 62be7aa..6dca61e 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -5931,7 +5931,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 3376a0f..c5c05a2 100644 --- a/gdb/nat/linux-btrace.c +++ b/gdb/nat/linux-btrace.c @@ -38,6 +38,7 @@ #include #include #include +#include /* A branch trace record in perf_event. */ struct perf_event_bts @@ -102,6 +103,32 @@ 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_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 +461,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_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 9d82be2..0bf564a 100644 --- a/gdb/x86-linux-nat.c +++ b/gdb/x86-linux-nat.c @@ -441,9 +441,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; } -- 1.8.3.1