From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 32205 invoked by alias); 24 Nov 2013 23:35:18 -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 32196 invoked by uid 89); 24 Nov 2013 23:35:17 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=AWL,BAYES_50,RDNS_NONE,SPF_HELO_PASS,SPF_PASS autolearn=no version=3.3.2 X-HELO: mx1.redhat.com Received: from Unknown (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 24 Nov 2013 23:35:16 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id rAONZ1Eq013027 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Sun, 24 Nov 2013 18:35:01 -0500 Received: from psique.redhat.com (ovpn-113-74.phx2.redhat.com [10.3.113.74]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id rAONYwNR024427; Sun, 24 Nov 2013 18:34:59 -0500 From: Sergio Durigan Junior To: GDB Patches Cc: Sergio Durigan Junior , Marcus Shawcroft Subject: [PATCH] Fix for PR tdep/15653: Implement SystemTap SDT probe support for AArch64 Date: Sun, 24 Nov 2013 23:48:00 -0000 Message-Id: <1385336092-19621-1-git-send-email-sergiodj@redhat.com> X-IsSubscribed: yes X-SW-Source: 2013-11/txt/msg00746.txt.bz2 This commit implements the needed bits for SystemTap SDT probe support on AArch64 architectures. The core of the patch is in the aarch64-linux-tdep.c file; all the rest are support/cleanup modifications. First, I started by looking at AArch64 assembly specification and filling the necessary options on gdbarch's stap machinery in order to make the generic asm parser (implemented in stap-probe.c) recognize AArch64's asm. AArch64 has the same idiosincrasy as 32-bit ARM: the syntax for register indirection is very specific, and demands its own function to parse this special expression. However, both AArch64 and 32-bit ARM share the same syntax (with only one little difference between them), which made me think of a way to share the specific parser between both architectures. That's why I came up with the modification on configure.tgt: the idea is to mimic i386/x86_64 behavior, by sharing the 32-bit linux-tdep.c file with the 64-bit relative. Therefore, I decided to make arm-linux-tdep.c and arm-tdep.c be built when we're compiling for aarch64-linux-gnu. I guess another option would be to create a "generic" ARM tdep file to be shared among 32- and 64-bit, but I didn't go that way because i386/x86_64 don't do that... The other issue I had to fix was a bad decision on the code that handles single operands on the generic asm parser. If there is no register prefix or a register indirection prefix, then we should assume that the operand being parsed is a register, and not an error. This case is covered now. Now, about the tests... I have been using ARM Foundation's simulator on x86_64 (Fedora 18). This is an incredibly slow simulator, to the point that I gave up compiling GDB directly on it. Instead, I am cross-compiling it on my machine and testing only the binary there. Therefore, I also gave up running the testsuite, and only ran stap-related tests. As far as I'm concerned, everything succeeded and I didn't break anything. The code is pretty much self contained that it doesn't affect other areas of GDB, but of course this patch could use more testing, and I won't complain if you have the means and the will to do this! Otherwise, I consider this patch OK, and of course I will keep an eye for when AArch64 hardware becomes available, so that I can test this on real machines. Any comments? OK to apply? Thanks. 2013-11-24 Sergio Durigan Junior PR tdep/15653: * aarch64-linux-tdep.c: Include "arm-linux-tdep.h" and . (aarch64_stap_is_single_operand): New function. (aarch64_stap_parse_special_token): Likewise. (aarch64_linux_init_abi): Intialize SystemTap SDT probes specific parameters. * arm-linux-tdep.c (arm_generic_stap_parse_special_token): New function, with the contents of... (arm_stap_parse_special_token): ...this one. Rewrite this function to call the function above. * arm-linux-tdep.h: Forward declare "struct gdbarch" and "struct stap_parse_info". (arm_generic_stap_parse_special_token): New prototype. * configure.tgt (aarch64*-*-linux*): Add "arm-linux-tdep.o" and "arm-tdep.o" to be built. * stap-probe.c (stap_parse_single_operand): Handle the case when there is no register prefix or register indirection prefix. --- gdb/aarch64-linux-tdep.c | 31 +++++++++++++++++++++++++++++++ gdb/arm-linux-tdep.c | 27 +++++++++++++++------------ gdb/arm-linux-tdep.h | 20 ++++++++++++++++++++ gdb/configure.tgt | 3 ++- gdb/stap-probe.c | 13 +++++++++++-- 5 files changed, 79 insertions(+), 15 deletions(-) diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c index bcfcce2..f23468c 100644 --- a/gdb/aarch64-linux-tdep.c +++ b/gdb/aarch64-linux-tdep.c @@ -25,6 +25,7 @@ #include "linux-tdep.h" #include "aarch64-tdep.h" #include "aarch64-linux-tdep.h" +#include "arm-linux-tdep.h" #include "osabi.h" #include "solib-svr4.h" #include "symtab.h" @@ -35,6 +36,8 @@ #include "regcache.h" #include "regset.h" +#include + /* The general-purpose regset consists of 31 X registers, plus SP, PC, and PSTATE registers, as defined in the AArch64 port of the Linux kernel. */ @@ -263,6 +266,25 @@ aarch64_linux_regset_from_core_section (struct gdbarch *gdbarch, return NULL; } +/* Implementation of gdbarch_stap_is_single_operand. */ + +static int +aarch64_stap_is_single_operand (struct gdbarch *gdbarch, const char *s) +{ + return (*s == '#' /* Literal number. */ + || *s == '[' /* Register indirection or displacement. */ + || isalpha (*s)); /* Register value. */ +} + +/* Implementation of gdbarch_stap_parse_special_token. */ + +static int +aarch64_stap_parse_special_token (struct gdbarch *gdbarch, + struct stap_parse_info *p) +{ + return arm_generic_stap_parse_special_token (gdbarch, p, 0); +} + static void aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { @@ -285,6 +307,15 @@ aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_gdbarch_get_siginfo_type (gdbarch, linux_get_siginfo_type); tramp_frame_prepend_unwinder (gdbarch, &aarch64_linux_rt_sigframe); + /* SystemTap SDT probe related. */ + set_gdbarch_stap_integer_prefix (gdbarch, "#"); + set_gdbarch_stap_register_indirection_prefix (gdbarch, "["); + set_gdbarch_stap_register_indirection_suffix (gdbarch, "]"); + set_gdbarch_stap_is_single_operand (gdbarch, + aarch64_stap_is_single_operand); + set_gdbarch_stap_parse_special_token (gdbarch, + aarch64_stap_parse_special_token); + /* Enable longjmp. */ tdep->jb_pc = 11; diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c index 9deed10..f316cde 100644 --- a/gdb/arm-linux-tdep.c +++ b/gdb/arm-linux-tdep.c @@ -1122,18 +1122,12 @@ arm_stap_is_single_operand (struct gdbarch *gdbarch, const char *s) || isalpha (*s)); /* Register value. */ } -/* This routine is used to parse a special token in ARM's assembly. +/* See comment on arm-linux-tdep.h. */ - The special tokens parsed by it are: - - - Register displacement (e.g, [fp, #-8]) - - It returns one if the special token has been parsed successfully, - or zero if the current token is not considered special. */ - -static int -arm_stap_parse_special_token (struct gdbarch *gdbarch, - struct stap_parse_info *p) +int +arm_generic_stap_parse_special_token (struct gdbarch *gdbarch, + struct stap_parse_info *p, + int skip_hash_sign) { if (*p->arg == '[') { @@ -1183,7 +1177,7 @@ arm_stap_parse_special_token (struct gdbarch *gdbarch, ++tmp; tmp = skip_spaces_const (tmp); - if (*tmp++ != '#') + if (skip_hash_sign && *tmp++ != '#') return 0; if (*tmp == '-') @@ -1231,6 +1225,15 @@ arm_stap_parse_special_token (struct gdbarch *gdbarch, return 1; } +/* Implementation of gdbarch_stap_parse_special_token. */ + +static int +arm_stap_parse_special_token (struct gdbarch *gdbarch, + struct stap_parse_info *p) +{ + return arm_generic_stap_parse_special_token (gdbarch, p, 1); +} + static void arm_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) diff --git a/gdb/arm-linux-tdep.h b/gdb/arm-linux-tdep.h index 59518fd..1b3c349 100644 --- a/gdb/arm-linux-tdep.h +++ b/gdb/arm-linux-tdep.h @@ -19,6 +19,8 @@ struct regset; struct regcache; +struct gdbarch; +struct stap_parse_info; #define ARM_LINUX_SIZEOF_NWFPE (8 * FP_REGISTER_SIZE \ + 2 * INT_REGISTER_SIZE \ @@ -59,6 +61,24 @@ void arm_linux_collect_nwfpe (const struct regset *regset, const struct regcache *regcache, int regnum, void *regs_buf, size_t len); +/* This routine is used to parse a special token in ARM's assembly. + It works for both 32-bit and 64-bit ARM architectures. + + The special tokens parsed by it are: + + - Register displacement (e.g, [fp, #-8] on ARM, and [fp, -8] on AArch64) + + SKIP_HASH_SIGN is 1 is the parser should skip the hash sign + before integers (e.g., #-8 for ARM), or 0 if the parser should + not bother with it (e.g., -8 for AArch64). + + It returns one if the special token has been parsed successfully, + or zero if the current token is not considered special. */ + +extern int arm_generic_stap_parse_special_token (struct gdbarch *gdbarch, + struct stap_parse_info *p, + int skip_hash_sign); + /* ARM GNU/Linux HWCAP values. These are in defined in in current kernels. */ #define HWCAP_VFP 64 diff --git a/gdb/configure.tgt b/gdb/configure.tgt index 47e98d9..49dbc60 100644 --- a/gdb/configure.tgt +++ b/gdb/configure.tgt @@ -41,7 +41,8 @@ aarch64*-*-linux*) # Target: AArch64 linux gdb_target_obs="aarch64-tdep.o aarch64-linux-tdep.o \ glibc-tdep.o linux-tdep.o solib-svr4.o \ - symfile-mem.o" + symfile-mem.o + arm-linux-tdep.o arm-tdep.o" build_gdbserver=yes ;; diff --git a/gdb/stap-probe.c b/gdb/stap-probe.c index a734793..b3ab397 100644 --- a/gdb/stap-probe.c +++ b/gdb/stap-probe.c @@ -699,8 +699,17 @@ stap_parse_single_operand (struct stap_parse_info *p) else if ((reg_prefix && strncmp (p->arg, reg_prefix, reg_prefix_len) == 0) || (reg_ind_prefix - && strncmp (p->arg, reg_ind_prefix, reg_ind_prefix_len) == 0)) - stap_parse_register_operand (p); + && strncmp (p->arg, reg_ind_prefix, reg_ind_prefix_len) == 0) + || reg_prefix == NULL || reg_ind_prefix == NULL) + { + /* We are dealing with a register here, or trying to... If + `reg_prefix' or `reg_ind_prefix' are NULL, it means we can + expect anything to be a register (or a register indirection), + and therefore there is no way to guarantee that we really + have a register in hands now. So we call our parser for + register operand, and let it deal with the situation. */ + stap_parse_register_operand (p); + } else error (_("Operator `%c' not recognized on expression `%s'."), *p->arg, p->saved_arg); -- 1.7.11.7