From patchwork Sat Jun 27 16:21:42 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Wei-cheng, Wang" X-Patchwork-Id: 7413 Received: (qmail 46088 invoked by alias); 27 Jun 2015 16:22:09 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 46006 invoked by uid 89); 27 Jun 2015 16:22:08 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=1.5 required=5.0 tests=AWL, BAYES_00, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS, URIBL_BLACK autolearn=no version=3.3.2 X-HELO: mail-pd0-f171.google.com Received: from mail-pd0-f171.google.com (HELO mail-pd0-f171.google.com) (209.85.192.171) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Sat, 27 Jun 2015 16:22:02 +0000 Received: by pdcu2 with SMTP id u2so91988910pdc.3 for ; Sat, 27 Jun 2015 09:22:00 -0700 (PDT) X-Received: by 10.68.129.134 with SMTP id nw6mr14616300pbb.109.1435422120104; Sat, 27 Jun 2015 09:22:00 -0700 (PDT) Received: from localhost.localdomain (114-32-204-230.HINET-IP.hinet.net. [114.32.204.230]) by mx.google.com with ESMTPSA id ju3sm27788766pbc.33.2015.06.27.09.21.58 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 27 Jun 2015 09:21:59 -0700 (PDT) From: Wei-cheng Wang To: uweigand@de.ibm.com, gdb-patches@sourceware.org Cc: Wei-cheng Wang Subject: [PATCH 5/5 v4] Allow target to decide where to map jump-pad. Date: Sun, 28 Jun 2015 00:21:42 +0800 Message-Id: <1435422102-39438-5-git-send-email-cole945@gmail.com> In-Reply-To: <1435422102-39438-1-git-send-email-cole945@gmail.com> References: <1435422102-39438-1-git-send-email-cole945@gmail.com> Ulrich Weigand wrote: > Looks OK to me. Note that getauxval was only introduced with > a relatively recent glibc release, so might warrant a configure > check to avoid breaking the build on older releases ... Current configure.ac had alreadly check getauxval, AC_CHECK_FUNCS(getauxval pread pwrite pread64 setns) so I simply add the old-fashioned-way getauxval fallback if it's not there. Thanks, Wei-cheng --- This patch adds an IPA function, jump_pad_area_hint, for giving a hint where to map jump pad buffer. For some targets, addr = page-size is too far to reach from executable. gdb/gdbserver/ChangeLog 2015-06-27 Wei-cheng Wang * tracepoint.c (initialize_tracepoint): Call jump_pad_area_hint to get where to map gdb_jump_pad_buffer. Remove MAP_FIXED. * tracepoint.h (jump_pad_area_hint): Add declaration. * linux-amd64-ipa.c (jump_pad_area_hint): New function. * linux-i386-ipa.c (jump_pad_area_hint): New function. * linux-ppc-ipa.c (jump_pad_area_hint): New function. (getauxvl): New function. --- gdb/gdbserver/linux-amd64-ipa.c | 10 ++++++++ gdb/gdbserver/linux-i386-ipa.c | 10 ++++++++ gdb/gdbserver/linux-ppc-ipa.c | 51 +++++++++++++++++++++++++++++++++++++++++ gdb/gdbserver/tracepoint.c | 7 +++--- gdb/gdbserver/tracepoint.h | 3 +++ 5 files changed, 77 insertions(+), 4 deletions(-) diff --git a/gdb/gdbserver/linux-amd64-ipa.c b/gdb/gdbserver/linux-amd64-ipa.c index a6dfb03..65cd748 100644 --- a/gdb/gdbserver/linux-amd64-ipa.c +++ b/gdb/gdbserver/linux-amd64-ipa.c @@ -77,6 +77,16 @@ gdb_agent_get_raw_reg (const unsigned char *raw_regs, int regnum) return *(ULONGEST *) (raw_regs + x86_64_ft_collect_regmap[regnum]); } +/* See tracepoint.h. */ + +uintptr_t +jump_pad_area_hint (void) +{ + /* Allocate scratch buffer aligned on a page boundary, at a low + address (close to the main executable's code). */ + return sysconf (_SC_PAGE_SIZE); +} + #ifdef HAVE_UST #include diff --git a/gdb/gdbserver/linux-i386-ipa.c b/gdb/gdbserver/linux-i386-ipa.c index eb30dcd..dc0dfaf 100644 --- a/gdb/gdbserver/linux-i386-ipa.c +++ b/gdb/gdbserver/linux-i386-ipa.c @@ -114,6 +114,16 @@ gdb_agent_get_raw_reg (const unsigned char *raw_regs, int regnum) return *(int *) (raw_regs + i386_ft_collect_regmap[regnum]); } +/* See tracepoint.h. */ + +uintptr_t +jump_pad_area_hint (void) +{ + /* Allocate scratch buffer aligned on a page boundary, at a low + address (close to the main executable's code). */ + return sysconf (_SC_PAGE_SIZE); +} + #ifdef HAVE_UST #include diff --git a/gdb/gdbserver/linux-ppc-ipa.c b/gdb/gdbserver/linux-ppc-ipa.c index 73d8899..ddb2174 100644 --- a/gdb/gdbserver/linux-ppc-ipa.c +++ b/gdb/gdbserver/linux-ppc-ipa.c @@ -21,6 +21,8 @@ #include "server.h" #include "tracepoint.h" +#include + #if defined __PPC64__ void init_registers_powerpc_64l (void); extern const struct target_desc *tdesc_powerpc_64l; @@ -105,6 +107,55 @@ gdb_agent_get_raw_reg (const unsigned char *raw_regs, int regnum) + ppc_ft_collect_regmap[regnum] * REGSZ); } +#ifndef HAVE_GETAUXVAL +/* Retrieve the value of TYPE from the auxiliary vector. If TYPE is not + found, 0 is returned. This function is provided if glibc is too old. */ + +static unsigned long +getauxval (unsigned long type) +{ + unsigned long data[2]; + FILE *f = fopen ("/proc/self/auxv", "r"); + unsigned long value = 0; + + if (f == NULL) + return 0; + + while (fread (data, sizeof (data), 1, f) > 0) + { + if (data[0] == AT_HWCAP) + { + value = data[1]; + break; + } + } + + fclose (f); + return value; +} +#endif + +/* See tracepoint.h. */ + +uintptr_t +jump_pad_area_hint (void) +{ + /* Use AT_PHDR address to guess where the main executable is mapped, + and try to map the jump pad before it. The jump pad should be + closed enough to the executable for unconditional branch (+/- 32MB). */ + + const int SCRATCH_BUFFER_NPAGES = 20; + uintptr_t base = getauxval (AT_PHDR); + uintptr_t pagesz = sysconf (_SC_PAGE_SIZE); + uintptr_t hint = (base & ~(pagesz - 1)) - SCRATCH_BUFFER_NPAGES * pagesz; + + /* Return the lowest possible value if wrap-around. */ + if (hint > base) + hint = pagesz; + + return hint; +} + /* Initialize ipa_tdesc and others. */ void diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c index fdec7db..d1c03cf 100644 --- a/gdb/gdbserver/tracepoint.c +++ b/gdb/gdbserver/tracepoint.c @@ -7355,13 +7355,12 @@ initialize_tracepoint (void) #define SCRATCH_BUFFER_NPAGES 20 - /* Allocate scratch buffer aligned on a page boundary, at a low - address (close to the main executable's code). */ - for (addr = pagesize; addr != 0; addr += pagesize) + addr = jump_pad_area_hint (); + for (; addr != 0; addr += pagesize) { gdb_jump_pad_buffer = mmap ((void *) addr, pagesize * SCRATCH_BUFFER_NPAGES, PROT_READ | PROT_WRITE | PROT_EXEC, - MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (gdb_jump_pad_buffer != MAP_FAILED) break; diff --git a/gdb/gdbserver/tracepoint.h b/gdb/gdbserver/tracepoint.h index 30d0b58..139894f 100644 --- a/gdb/gdbserver/tracepoint.h +++ b/gdb/gdbserver/tracepoint.h @@ -131,6 +131,9 @@ void supply_static_tracepoint_registers (struct regcache *regcache, CORE_ADDR pc); void set_trampoline_buffer_space (CORE_ADDR begin, CORE_ADDR end, char *errmsg); +/* Return the address for where to allocate buffer for jump pad. + The buffer should be close enough for tracepoints. */ +uintptr_t jump_pad_area_hint (void); extern const struct target_desc *ipa_tdesc;