From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5059 invoked by alias); 17 Dec 2013 17:28:11 -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 5045 invoked by uid 89); 17 Dec 2013 17:28:10 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.8 required=5.0 tests=AWL,BAYES_00,RP_MATCHES_RCVD,SPF_HELO_PASS,SPF_PASS autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 17 Dec 2013 17:28:07 +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 rBHHS50E020355 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 17 Dec 2013 12:28:06 -0500 Received: from psique ([10.3.113.5]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id rBHHRwZM020808 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Tue, 17 Dec 2013 12:27:59 -0500 From: Sergio Durigan Junior To: Pedro Alves Cc: GDB Patches Subject: Re: [PATCH] Extend SystemTap SDT probe argument parser References: <1386734160-29837-1-git-send-email-sergiodj@redhat.com> <52B02F82.3020907@redhat.com> X-URL: http://www.redhat.com Date: Tue, 17 Dec 2013 17:28:00 -0000 In-Reply-To: <52B02F82.3020907@redhat.com> (Pedro Alves's message of "Tue, 17 Dec 2013 11:03:30 +0000") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.1 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-IsSubscribed: yes X-SW-Source: 2013-12/txt/msg00656.txt.bz2 On Tuesday, December 17 2013, Pedro Alves wrote: > On 12/11/2013 03:55 AM, Sergio Durigan Junior wrote: >> I have chosen to implement this as a list of const strings, which needs >> to be declared as "static const char *const *", and is provided to >> gdbarch on initialization. I think it is cleaner to implement it this >> way, but for a moment I wondered whether demanding the variables to be >> declared as "static" is a good idea... After some thought and >> discussion, I decided to leave it as is. > > AFAICS, nothing in the interface "demands" static. What is required > is that the array outlives the gdbarch method call. So usually, > you'll make the array either static global, or static to a function. > That is, this would work just as well with the same gdbarch interface: > > --- a/gdb/amd64-tdep.c > +++ b/gdb/amd64-tdep.c > +const char *const stap_integer_prefix[] = { "$", NULL }; > +const char *const stap_register_prefix[] = { "%", NULL }; > +const char *const stap_register_indirection_prefix[] = { "(", NULL }; > +const char *const stap_register_indirection_suffix[] = { ")", NULL }; > + > void > amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > { > struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); > const struct target_desc *tdesc = info.target_desc; > > > Or even, allocating "stap_integer_prefix" etc. on the > heap (xmalloc, etc.). > > "static" or not is a detail of the arch's gdbarch hook implementation. Yes, I knew it, but I should have written it in a clear way. Thanks for expliciting this. Anyway, I have chosen to keep the "static" there because I think it is better. But as you said, someone who implements the support for a new target may choose whatever she wants. BTW, I will fix the commit message to remove this confusing statement. >> + * gdbarch.sh (stap_integer_prefix, stap_integer_suffix) >> + (stap_register_prefix, stap_register_suffix) >> + (stap_register_indirection_prefix) >> + (stap_register_indirection_suffix): Declare as "const char *const >> + *" instead of "const char *". Adjust printing function. > > As we're touching all the hooks anyway, can we rename them to > the plural "prefixes" and "suffixes" ? I'd find that clearer. Done. >> >> +static char * >> +pstring_list (const char *const *list) > > Please add an intro comment. Done. >> +{ >> + static char ret[100]; >> + const char *const *p; >> + int offset = 0; > > size_t. Done. >> + >> + if (list == NULL) >> + return "(null)"; >> + >> + ret[0] = '\0'; >> + for (p = list; *p != NULL && offset < sizeof (ret); ++p) >> + { >> + xsnprintf (ret + offset, sizeof (ret) - offset, "%s, ", *p); >> + offset += 2 + strlen (*p); > > You can use the return of xsnprintf instead of strlen. Done. >> + } >> + > > Also, currently unlikely, but if this function ends up used > in the future with a bigger list, we'll get silent truncation. > I think we should assert instead that doesn't happen. Done. >> + if (offset > 0) >> + ret[offset - 2] = '\0'; >> + >> + return ret; >> +} >> + > >> # in this case, this prefix would be the character \`\$\'. >> -v:const char *:stap_integer_prefix:::0:0::0:pstring (gdbarch->stap_integer_prefix) >> +# >> +# This variable must be declared as \`static const char *const var\[\]\', >> +# and must also be NUL-terminated, like the following example: >> +# > > It's a NULL pointer, not NUL, the null character. So, "NULL-terminated". > > I'd remove the "must be" part, and just say: > > - Prefix used to mark an integer constant on the architecture's assembly > + A NULL-terminated array of prefixes used to mark an integer constant on the architecture's assembly. > For example, on x86 integer constants are written as: > > ( reindented, of course ) Done. >> +/* Helper function to check for a generic list of prefixes. Return 1 >> + if any prefix has been found, zero otherwise. */ > > Please describe the parameters and the contract. Some of these > arguments can be NULL. We do a case insensitive match. Etc. > Likewise stap_generic_check_suffix and possibly others. If > there's some central function that describes all this, then > you can point at it: "arguments are like foo", or some such. Done. >> + >> +static int >> +stap_is_generic_prefix (struct gdbarch *gdbarch, const char *s, >> + const char **r, const char *const *prefixes) >> +{ > >> + /* A NULL value here means that integers do not have prefix. We >> + just check for a digit then. */ > > "have a prefix" ? Fixed. > Otherwise looks good to me. Thanks. I guess I will wait a little more until Mark K. replies to my question, and then I will push the following version. -- Sergio 2013-12-17 Sergio Durigan Junior * amd64-tdep.c (amd64_init_abi): Declare SystemTap SDT probe argument prefixes and suffixes. Initialize gdbarch with them. * arm-linux-tdep.c (arm_linux_init_abi): Likewise. * gdbarch.c: Regenerate. * gdbarch.h: Regenerate. * gdbarch.sh (stap_integer_prefix, stap_integer_suffix) (stap_register_prefix, stap_register_suffix) (stap_register_indirection_prefix) (stap_register_indirection_suffix): Declare as "const char *const *" instead of "const char *". Adjust printing function. Rename to plural. (pstring_list): New function. * i386-tdep.c (i386_elf_init_abi): Declare SystemTap SDT probe argument prefixes and suffixes. Initialize gdbarch with them. * ia64-linux-tdep.c (ia64_linux_init_abi): Likewise. * ppc-linux-tdep.c (ppc_linux_init_abi): Likewise. * s390-linux-tdep.c (s390_gdbarch_init): Likewise. * stap-probe.c (stap_is_generic_prefix): New function. (stap_is_register_prefix): Likewise. (stap_is_register_indirection_prefix): Likewise. (stap_is_integer_prefix): Likewise. (stap_generic_check_suffix): Likewise. (stap_check_integer_suffix): Likewise. (stap_check_register_suffix): Likewise. (stap_check_register_indirection_suffix): Likewise. (stap_parse_register_operand): Remove unecessary declarations for variables holding prefix and suffix information. Use the new functions listed above for checking for prefixes and suffixes. (stap_parse_single_operand): Likewise. diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c index 19968fc..9efefd2 100644 --- a/gdb/amd64-tdep.c +++ b/gdb/amd64-tdep.c @@ -2832,6 +2832,12 @@ amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); const struct target_desc *tdesc = info.target_desc; + static const char *const stap_integer_prefixes[] = { "$", NULL }; + static const char *const stap_register_prefixes[] = { "%", NULL }; + static const char *const stap_register_indirection_prefixes[] = { "(", + NULL }; + static const char *const stap_register_indirection_suffixes[] = { ")", + NULL }; /* AMD64 generally uses `fxsave' instead of `fsave' for saving its floating-point registers. */ @@ -2944,10 +2950,12 @@ amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_gdbarch_gen_return_address (gdbarch, amd64_gen_return_address); /* SystemTap variables and functions. */ - set_gdbarch_stap_integer_prefix (gdbarch, "$"); - set_gdbarch_stap_register_prefix (gdbarch, "%"); - set_gdbarch_stap_register_indirection_prefix (gdbarch, "("); - set_gdbarch_stap_register_indirection_suffix (gdbarch, ")"); + set_gdbarch_stap_integer_prefixes (gdbarch, stap_integer_prefixes); + set_gdbarch_stap_register_prefixes (gdbarch, stap_register_prefixes); + set_gdbarch_stap_register_indirection_prefixes (gdbarch, + stap_register_indirection_prefixes); + set_gdbarch_stap_register_indirection_suffixes (gdbarch, + stap_register_indirection_suffixes); set_gdbarch_stap_is_single_operand (gdbarch, i386_stap_is_single_operand); set_gdbarch_stap_parse_special_token (gdbarch, diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c index 9deed10..0284f69 100644 --- a/gdb/arm-linux-tdep.c +++ b/gdb/arm-linux-tdep.c @@ -1235,6 +1235,12 @@ static void arm_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { + static const char *const stap_integer_prefixes[] = { "#", NULL }; + static const char *const stap_register_prefixes[] = { "r", NULL }; + static const char *const stap_register_indirection_prefixes[] = { "[", + NULL }; + static const char *const stap_register_indirection_suffixes[] = { "]", + NULL }; struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); linux_init_abi (info, gdbarch); @@ -1334,10 +1340,12 @@ arm_linux_init_abi (struct gdbarch_info info, set_gdbarch_process_record (gdbarch, arm_process_record); /* SystemTap functions. */ - set_gdbarch_stap_integer_prefix (gdbarch, "#"); - set_gdbarch_stap_register_prefix (gdbarch, "r"); - set_gdbarch_stap_register_indirection_prefix (gdbarch, "["); - set_gdbarch_stap_register_indirection_suffix (gdbarch, "]"); + set_gdbarch_stap_integer_prefixes (gdbarch, stap_integer_prefixes); + set_gdbarch_stap_register_prefixes (gdbarch, stap_register_prefixes); + set_gdbarch_stap_register_indirection_prefixes (gdbarch, + stap_register_indirection_prefixes); + set_gdbarch_stap_register_indirection_suffixes (gdbarch, + stap_register_indirection_suffixes); set_gdbarch_stap_gdb_register_prefix (gdbarch, "r"); set_gdbarch_stap_is_single_operand (gdbarch, arm_stap_is_single_operand); set_gdbarch_stap_parse_special_token (gdbarch, diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index fb3595f..f07b8c6 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -86,6 +86,33 @@ pstring (const char *string) return string; } +/* Helper function to print a list of strings, represented as "const + char *const *". The list is printed comma-separated. */ + +static char * +pstring_list (const char *const *list) +{ + static char ret[100]; + const char *const *p; + size_t offset = 0; + + if (list == NULL) + return "(null)"; + + ret[0] = '\0'; + for (p = list; *p != NULL && offset < sizeof (ret); ++p) + { + size_t s = xsnprintf (ret + offset, sizeof (ret) - offset, "%s, ", *p); + offset += 2 + s; + } + + gdb_assert (offset - 2 < sizeof (ret)); + if (offset > 0) + ret[offset - 2] = '\0'; + + return ret; +} + /* Maintain the struct gdbarch object. */ @@ -265,12 +292,12 @@ struct gdbarch gdbarch_get_siginfo_type_ftype *get_siginfo_type; gdbarch_record_special_symbol_ftype *record_special_symbol; gdbarch_get_syscall_number_ftype *get_syscall_number; - const char * stap_integer_prefix; - const char * stap_integer_suffix; - const char * stap_register_prefix; - const char * stap_register_suffix; - const char * stap_register_indirection_prefix; - const char * stap_register_indirection_suffix; + const char *const * stap_integer_prefixes; + const char *const * stap_integer_suffixes; + const char *const * stap_register_prefixes; + const char *const * stap_register_suffixes; + const char *const * stap_register_indirection_prefixes; + const char *const * stap_register_indirection_suffixes; const char * stap_gdb_register_prefix; const char * stap_gdb_register_suffix; gdbarch_stap_is_single_operand_ftype *stap_is_single_operand; @@ -438,12 +465,12 @@ struct gdbarch startup_gdbarch = 0, /* get_siginfo_type */ 0, /* record_special_symbol */ 0, /* get_syscall_number */ - 0, /* stap_integer_prefix */ - 0, /* stap_integer_suffix */ - 0, /* stap_register_prefix */ - 0, /* stap_register_suffix */ - 0, /* stap_register_indirection_prefix */ - 0, /* stap_register_indirection_suffix */ + 0, /* stap_integer_prefixes */ + 0, /* stap_integer_suffixes */ + 0, /* stap_register_prefixes */ + 0, /* stap_register_suffixes */ + 0, /* stap_register_indirection_prefixes */ + 0, /* stap_register_indirection_suffixes */ 0, /* stap_gdb_register_prefix */ 0, /* stap_gdb_register_suffix */ 0, /* stap_is_single_operand */ @@ -744,12 +771,12 @@ verify_gdbarch (struct gdbarch *gdbarch) /* Skip verify of get_siginfo_type, has predicate. */ /* Skip verify of record_special_symbol, has predicate. */ /* Skip verify of get_syscall_number, has predicate. */ - /* Skip verify of stap_integer_prefix, invalid_p == 0 */ - /* Skip verify of stap_integer_suffix, invalid_p == 0 */ - /* Skip verify of stap_register_prefix, invalid_p == 0 */ - /* Skip verify of stap_register_suffix, invalid_p == 0 */ - /* Skip verify of stap_register_indirection_prefix, invalid_p == 0 */ - /* Skip verify of stap_register_indirection_suffix, invalid_p == 0 */ + /* Skip verify of stap_integer_prefixes, invalid_p == 0 */ + /* Skip verify of stap_integer_suffixes, invalid_p == 0 */ + /* Skip verify of stap_register_prefixes, invalid_p == 0 */ + /* Skip verify of stap_register_suffixes, invalid_p == 0 */ + /* Skip verify of stap_register_indirection_prefixes, invalid_p == 0 */ + /* Skip verify of stap_register_indirection_suffixes, invalid_p == 0 */ /* Skip verify of stap_gdb_register_prefix, invalid_p == 0 */ /* Skip verify of stap_gdb_register_suffix, invalid_p == 0 */ /* Skip verify of stap_is_single_operand, has predicate. */ @@ -1351,11 +1378,11 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) "gdbarch_dump: stap_gdb_register_suffix = %s\n", pstring (gdbarch->stap_gdb_register_suffix)); fprintf_unfiltered (file, - "gdbarch_dump: stap_integer_prefix = %s\n", - pstring (gdbarch->stap_integer_prefix)); + "gdbarch_dump: stap_integer_prefixes = %s\n", + pstring_list (gdbarch->stap_integer_prefixes)); fprintf_unfiltered (file, - "gdbarch_dump: stap_integer_suffix = %s\n", - pstring (gdbarch->stap_integer_suffix)); + "gdbarch_dump: stap_integer_suffixes = %s\n", + pstring_list (gdbarch->stap_integer_suffixes)); fprintf_unfiltered (file, "gdbarch_dump: gdbarch_stap_is_single_operand_p() = %d\n", gdbarch_stap_is_single_operand_p (gdbarch)); @@ -1369,17 +1396,17 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) "gdbarch_dump: stap_parse_special_token = <%s>\n", host_address_to_string (gdbarch->stap_parse_special_token)); fprintf_unfiltered (file, - "gdbarch_dump: stap_register_indirection_prefix = %s\n", - pstring (gdbarch->stap_register_indirection_prefix)); + "gdbarch_dump: stap_register_indirection_prefixes = %s\n", + pstring_list (gdbarch->stap_register_indirection_prefixes)); fprintf_unfiltered (file, - "gdbarch_dump: stap_register_indirection_suffix = %s\n", - pstring (gdbarch->stap_register_indirection_suffix)); + "gdbarch_dump: stap_register_indirection_suffixes = %s\n", + pstring_list (gdbarch->stap_register_indirection_suffixes)); fprintf_unfiltered (file, - "gdbarch_dump: stap_register_prefix = %s\n", - pstring (gdbarch->stap_register_prefix)); + "gdbarch_dump: stap_register_prefixes = %s\n", + pstring_list (gdbarch->stap_register_prefixes)); fprintf_unfiltered (file, - "gdbarch_dump: stap_register_suffix = %s\n", - pstring (gdbarch->stap_register_suffix)); + "gdbarch_dump: stap_register_suffixes = %s\n", + pstring_list (gdbarch->stap_register_suffixes)); fprintf_unfiltered (file, "gdbarch_dump: gdbarch_static_transform_name_p() = %d\n", gdbarch_static_transform_name_p (gdbarch)); @@ -4004,106 +4031,106 @@ set_gdbarch_get_syscall_number (struct gdbarch *gdbarch, gdbarch->get_syscall_number = get_syscall_number; } -const char * -gdbarch_stap_integer_prefix (struct gdbarch *gdbarch) +const char *const * +gdbarch_stap_integer_prefixes (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of stap_integer_prefix, invalid_p == 0 */ + /* Skip verify of stap_integer_prefixes, invalid_p == 0 */ if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_integer_prefix called\n"); - return gdbarch->stap_integer_prefix; + fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_integer_prefixes called\n"); + return gdbarch->stap_integer_prefixes; } void -set_gdbarch_stap_integer_prefix (struct gdbarch *gdbarch, - const char * stap_integer_prefix) +set_gdbarch_stap_integer_prefixes (struct gdbarch *gdbarch, + const char *const * stap_integer_prefixes) { - gdbarch->stap_integer_prefix = stap_integer_prefix; + gdbarch->stap_integer_prefixes = stap_integer_prefixes; } -const char * -gdbarch_stap_integer_suffix (struct gdbarch *gdbarch) +const char *const * +gdbarch_stap_integer_suffixes (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of stap_integer_suffix, invalid_p == 0 */ + /* Skip verify of stap_integer_suffixes, invalid_p == 0 */ if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_integer_suffix called\n"); - return gdbarch->stap_integer_suffix; + fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_integer_suffixes called\n"); + return gdbarch->stap_integer_suffixes; } void -set_gdbarch_stap_integer_suffix (struct gdbarch *gdbarch, - const char * stap_integer_suffix) +set_gdbarch_stap_integer_suffixes (struct gdbarch *gdbarch, + const char *const * stap_integer_suffixes) { - gdbarch->stap_integer_suffix = stap_integer_suffix; + gdbarch->stap_integer_suffixes = stap_integer_suffixes; } -const char * -gdbarch_stap_register_prefix (struct gdbarch *gdbarch) +const char *const * +gdbarch_stap_register_prefixes (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of stap_register_prefix, invalid_p == 0 */ + /* Skip verify of stap_register_prefixes, invalid_p == 0 */ if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_register_prefix called\n"); - return gdbarch->stap_register_prefix; + fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_register_prefixes called\n"); + return gdbarch->stap_register_prefixes; } void -set_gdbarch_stap_register_prefix (struct gdbarch *gdbarch, - const char * stap_register_prefix) +set_gdbarch_stap_register_prefixes (struct gdbarch *gdbarch, + const char *const * stap_register_prefixes) { - gdbarch->stap_register_prefix = stap_register_prefix; + gdbarch->stap_register_prefixes = stap_register_prefixes; } -const char * -gdbarch_stap_register_suffix (struct gdbarch *gdbarch) +const char *const * +gdbarch_stap_register_suffixes (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of stap_register_suffix, invalid_p == 0 */ + /* Skip verify of stap_register_suffixes, invalid_p == 0 */ if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_register_suffix called\n"); - return gdbarch->stap_register_suffix; + fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_register_suffixes called\n"); + return gdbarch->stap_register_suffixes; } void -set_gdbarch_stap_register_suffix (struct gdbarch *gdbarch, - const char * stap_register_suffix) +set_gdbarch_stap_register_suffixes (struct gdbarch *gdbarch, + const char *const * stap_register_suffixes) { - gdbarch->stap_register_suffix = stap_register_suffix; + gdbarch->stap_register_suffixes = stap_register_suffixes; } -const char * -gdbarch_stap_register_indirection_prefix (struct gdbarch *gdbarch) +const char *const * +gdbarch_stap_register_indirection_prefixes (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of stap_register_indirection_prefix, invalid_p == 0 */ + /* Skip verify of stap_register_indirection_prefixes, invalid_p == 0 */ if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_register_indirection_prefix called\n"); - return gdbarch->stap_register_indirection_prefix; + fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_register_indirection_prefixes called\n"); + return gdbarch->stap_register_indirection_prefixes; } void -set_gdbarch_stap_register_indirection_prefix (struct gdbarch *gdbarch, - const char * stap_register_indirection_prefix) +set_gdbarch_stap_register_indirection_prefixes (struct gdbarch *gdbarch, + const char *const * stap_register_indirection_prefixes) { - gdbarch->stap_register_indirection_prefix = stap_register_indirection_prefix; + gdbarch->stap_register_indirection_prefixes = stap_register_indirection_prefixes; } -const char * -gdbarch_stap_register_indirection_suffix (struct gdbarch *gdbarch) +const char *const * +gdbarch_stap_register_indirection_suffixes (struct gdbarch *gdbarch) { gdb_assert (gdbarch != NULL); - /* Skip verify of stap_register_indirection_suffix, invalid_p == 0 */ + /* Skip verify of stap_register_indirection_suffixes, invalid_p == 0 */ if (gdbarch_debug >= 2) - fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_register_indirection_suffix called\n"); - return gdbarch->stap_register_indirection_suffix; + fprintf_unfiltered (gdb_stdlog, "gdbarch_stap_register_indirection_suffixes called\n"); + return gdbarch->stap_register_indirection_suffixes; } void -set_gdbarch_stap_register_indirection_suffix (struct gdbarch *gdbarch, - const char * stap_register_indirection_suffix) +set_gdbarch_stap_register_indirection_suffixes (struct gdbarch *gdbarch, + const char *const * stap_register_indirection_suffixes) { - gdbarch->stap_register_indirection_suffix = stap_register_indirection_suffix; + gdbarch->stap_register_indirection_suffixes = stap_register_indirection_suffixes; } const char * diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index b58efc8..f37f44f 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -1034,37 +1034,42 @@ extern LONGEST gdbarch_get_syscall_number (struct gdbarch *gdbarch, ptid_t ptid) extern void set_gdbarch_get_syscall_number (struct gdbarch *gdbarch, gdbarch_get_syscall_number_ftype *get_syscall_number); /* SystemTap related fields and functions. - Prefix used to mark an integer constant on the architecture's assembly + A NULL-terminated array of prefixes used to mark an integer constant + on the architecture's assembly. For example, on x86 integer constants are written as: $10 ;; integer constant 10 in this case, this prefix would be the character `$'. */ -extern const char * gdbarch_stap_integer_prefix (struct gdbarch *gdbarch); -extern void set_gdbarch_stap_integer_prefix (struct gdbarch *gdbarch, const char * stap_integer_prefix); +extern const char *const * gdbarch_stap_integer_prefixes (struct gdbarch *gdbarch); +extern void set_gdbarch_stap_integer_prefixes (struct gdbarch *gdbarch, const char *const * stap_integer_prefixes); -/* Suffix used to mark an integer constant on the architecture's assembly. */ +/* A NULL-terminated array of suffixes used to mark an integer constant + on the architecture's assembly. */ -extern const char * gdbarch_stap_integer_suffix (struct gdbarch *gdbarch); -extern void set_gdbarch_stap_integer_suffix (struct gdbarch *gdbarch, const char * stap_integer_suffix); +extern const char *const * gdbarch_stap_integer_suffixes (struct gdbarch *gdbarch); +extern void set_gdbarch_stap_integer_suffixes (struct gdbarch *gdbarch, const char *const * stap_integer_suffixes); -/* Prefix used to mark a register name on the architecture's assembly. +/* A NULL-terminated array of prefixes used to mark a register name on + the architecture's assembly. For example, on x86 the register name is written as: %eax ;; register eax in this case, this prefix would be the character `%'. */ -extern const char * gdbarch_stap_register_prefix (struct gdbarch *gdbarch); -extern void set_gdbarch_stap_register_prefix (struct gdbarch *gdbarch, const char * stap_register_prefix); +extern const char *const * gdbarch_stap_register_prefixes (struct gdbarch *gdbarch); +extern void set_gdbarch_stap_register_prefixes (struct gdbarch *gdbarch, const char *const * stap_register_prefixes); -/* Suffix used to mark a register name on the architecture's assembly */ +/* A NULL-terminated array of suffixes used to mark a register name on + the architecture's assembly. */ -extern const char * gdbarch_stap_register_suffix (struct gdbarch *gdbarch); -extern void set_gdbarch_stap_register_suffix (struct gdbarch *gdbarch, const char * stap_register_suffix); +extern const char *const * gdbarch_stap_register_suffixes (struct gdbarch *gdbarch); +extern void set_gdbarch_stap_register_suffixes (struct gdbarch *gdbarch, const char *const * stap_register_suffixes); -/* Prefix used to mark a register indirection on the architecture's assembly. +/* A NULL-terminated array of prefixes used to mark a register + indirection on the architecture's assembly. For example, on x86 the register indirection is written as: (%eax) ;; indirecting eax @@ -1074,10 +1079,11 @@ extern void set_gdbarch_stap_register_suffix (struct gdbarch *gdbarch, const cha Please note that we use the indirection prefix also for register displacement, e.g., `4(%eax)' on x86. */ -extern const char * gdbarch_stap_register_indirection_prefix (struct gdbarch *gdbarch); -extern void set_gdbarch_stap_register_indirection_prefix (struct gdbarch *gdbarch, const char * stap_register_indirection_prefix); +extern const char *const * gdbarch_stap_register_indirection_prefixes (struct gdbarch *gdbarch); +extern void set_gdbarch_stap_register_indirection_prefixes (struct gdbarch *gdbarch, const char *const * stap_register_indirection_prefixes); -/* Suffix used to mark a register indirection on the architecture's assembly. +/* A NULL-terminated array of suffixes used to mark a register + indirection on the architecture's assembly. For example, on x86 the register indirection is written as: (%eax) ;; indirecting eax @@ -1087,10 +1093,10 @@ extern void set_gdbarch_stap_register_indirection_prefix (struct gdbarch *gdbarc Please note that we use the indirection suffix also for register displacement, e.g., `4(%eax)' on x86. */ -extern const char * gdbarch_stap_register_indirection_suffix (struct gdbarch *gdbarch); -extern void set_gdbarch_stap_register_indirection_suffix (struct gdbarch *gdbarch, const char * stap_register_indirection_suffix); +extern const char *const * gdbarch_stap_register_indirection_suffixes (struct gdbarch *gdbarch); +extern void set_gdbarch_stap_register_indirection_suffixes (struct gdbarch *gdbarch, const char *const * stap_register_indirection_suffixes); -/* Prefix used to name a register using GDB's nomenclature. +/* Prefix(es) used to name a register using GDB's nomenclature. For example, on PPC a register is represented by a number in the assembly language (e.g., `10' is the 10th general-purpose register). However, diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh index a678a78..ca56d1a 100755 --- a/gdb/gdbarch.sh +++ b/gdb/gdbarch.sh @@ -826,29 +826,34 @@ M:LONGEST:get_syscall_number:ptid_t ptid:ptid # SystemTap related fields and functions. -# Prefix used to mark an integer constant on the architecture's assembly +# A NULL-terminated array of prefixes used to mark an integer constant +# on the architecture's assembly. # For example, on x86 integer constants are written as: # # \$10 ;; integer constant 10 # # in this case, this prefix would be the character \`\$\'. -v:const char *:stap_integer_prefix:::0:0::0:pstring (gdbarch->stap_integer_prefix) +v:const char *const *:stap_integer_prefixes:::0:0::0:pstring_list (gdbarch->stap_integer_prefixes) -# Suffix used to mark an integer constant on the architecture's assembly. -v:const char *:stap_integer_suffix:::0:0::0:pstring (gdbarch->stap_integer_suffix) +# A NULL-terminated array of suffixes used to mark an integer constant +# on the architecture's assembly. +v:const char *const *:stap_integer_suffixes:::0:0::0:pstring_list (gdbarch->stap_integer_suffixes) -# Prefix used to mark a register name on the architecture's assembly. +# A NULL-terminated array of prefixes used to mark a register name on +# the architecture's assembly. # For example, on x86 the register name is written as: # # \%eax ;; register eax # # in this case, this prefix would be the character \`\%\'. -v:const char *:stap_register_prefix:::0:0::0:pstring (gdbarch->stap_register_prefix) +v:const char *const *:stap_register_prefixes:::0:0::0:pstring_list (gdbarch->stap_register_prefixes) -# Suffix used to mark a register name on the architecture's assembly -v:const char *:stap_register_suffix:::0:0::0:pstring (gdbarch->stap_register_suffix) +# A NULL-terminated array of suffixes used to mark a register name on +# the architecture's assembly. +v:const char *const *:stap_register_suffixes:::0:0::0:pstring_list (gdbarch->stap_register_suffixes) -# Prefix used to mark a register indirection on the architecture's assembly. +# A NULL-terminated array of prefixes used to mark a register +# indirection on the architecture's assembly. # For example, on x86 the register indirection is written as: # # \(\%eax\) ;; indirecting eax @@ -857,9 +862,10 @@ v:const char *:stap_register_suffix:::0:0::0:pstring (gdbarch->stap_register_suf # # Please note that we use the indirection prefix also for register # displacement, e.g., \`4\(\%eax\)\' on x86. -v:const char *:stap_register_indirection_prefix:::0:0::0:pstring (gdbarch->stap_register_indirection_prefix) +v:const char *const *:stap_register_indirection_prefixes:::0:0::0:pstring_list (gdbarch->stap_register_indirection_prefixes) -# Suffix used to mark a register indirection on the architecture's assembly. +# A NULL-terminated array of suffixes used to mark a register +# indirection on the architecture's assembly. # For example, on x86 the register indirection is written as: # # \(\%eax\) ;; indirecting eax @@ -868,9 +874,9 @@ v:const char *:stap_register_indirection_prefix:::0:0::0:pstring (gdbarch->stap_ # # Please note that we use the indirection suffix also for register # displacement, e.g., \`4\(\%eax\)\' on x86. -v:const char *:stap_register_indirection_suffix:::0:0::0:pstring (gdbarch->stap_register_indirection_suffix) +v:const char *const *:stap_register_indirection_suffixes:::0:0::0:pstring_list (gdbarch->stap_register_indirection_suffixes) -# Prefix used to name a register using GDB's nomenclature. +# Prefix(es) used to name a register using GDB's nomenclature. # # For example, on PPC a register is represented by a number in the assembly # language (e.g., \`10\' is the 10th general-purpose register). However, @@ -1481,6 +1487,33 @@ pstring (const char *string) return string; } +/* Helper function to print a list of strings, represented as "const + char *const *". The list is printed comma-separated. */ + +static char * +pstring_list (const char *const *list) +{ + static char ret[100]; + const char *const *p; + size_t offset = 0; + + if (list == NULL) + return "(null)"; + + ret[0] = '\0'; + for (p = list; *p != NULL && offset < sizeof (ret); ++p) + { + size_t s = xsnprintf (ret + offset, sizeof (ret) - offset, "%s, ", *p); + offset += 2 + s; + } + + gdb_assert (offset - 2 < sizeof (ret)); + if (offset > 0) + ret[offset - 2] = '\0'; + + return ret; +} + EOF # gdbarch open the gdbarch object diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index a1a4453..d0e1d8b 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -3919,14 +3919,23 @@ i386_stap_parse_special_token (struct gdbarch *gdbarch, void i386_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { + static const char *const stap_integer_prefixes[] = { "$", NULL }; + static const char *const stap_register_prefixes[] = { "%", NULL }; + static const char *const stap_register_indirection_prefixes[] = { "(", + NULL }; + static const char *const stap_register_indirection_suffixes[] = { ")", + NULL }; + /* We typically use stabs-in-ELF with the SVR4 register numbering. */ set_gdbarch_stab_reg_to_regnum (gdbarch, i386_svr4_reg_to_regnum); /* Registering SystemTap handlers. */ - set_gdbarch_stap_integer_prefix (gdbarch, "$"); - set_gdbarch_stap_register_prefix (gdbarch, "%"); - set_gdbarch_stap_register_indirection_prefix (gdbarch, "("); - set_gdbarch_stap_register_indirection_suffix (gdbarch, ")"); + set_gdbarch_stap_integer_prefixes (gdbarch, stap_integer_prefixes); + set_gdbarch_stap_register_prefixes (gdbarch, stap_register_prefixes); + set_gdbarch_stap_register_indirection_prefixes (gdbarch, + stap_register_indirection_prefixes); + set_gdbarch_stap_register_indirection_suffixes (gdbarch, + stap_register_indirection_suffixes); set_gdbarch_stap_is_single_operand (gdbarch, i386_stap_is_single_operand); set_gdbarch_stap_parse_special_token (gdbarch, diff --git a/gdb/ia64-linux-tdep.c b/gdb/ia64-linux-tdep.c index d1eb529..9756a67 100644 --- a/gdb/ia64-linux-tdep.c +++ b/gdb/ia64-linux-tdep.c @@ -135,6 +135,11 @@ static void ia64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + static const char *const stap_register_prefixes[] = { "r", NULL }; + static const char *const stap_register_indirection_prefixes[] = { "[", + NULL }; + static const char *const stap_register_indirection_suffixes[] = { "]", + NULL }; linux_init_abi (info, gdbarch); @@ -157,9 +162,11 @@ ia64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) svr4_fetch_objfile_link_map); /* SystemTap related. */ - set_gdbarch_stap_register_prefix (gdbarch, "r"); - set_gdbarch_stap_register_indirection_prefix (gdbarch, "["); - set_gdbarch_stap_register_indirection_suffix (gdbarch, "]"); + set_gdbarch_stap_register_prefixes (gdbarch, stap_register_prefixes); + set_gdbarch_stap_register_indirection_prefixes (gdbarch, + stap_register_indirection_prefixes); + set_gdbarch_stap_register_indirection_suffixes (gdbarch, + stap_register_indirection_suffixes); set_gdbarch_stap_gdb_register_prefix (gdbarch, "r"); set_gdbarch_stap_is_single_operand (gdbarch, ia64_linux_stap_is_single_operand); diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c index fc09560..62a1386 100644 --- a/gdb/ppc-linux-tdep.c +++ b/gdb/ppc-linux-tdep.c @@ -1245,6 +1245,11 @@ ppc_linux_init_abi (struct gdbarch_info info, { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); struct tdesc_arch_data *tdesc_data = (void *) info.tdep_info; + static const char *const stap_integer_prefixes[] = { "i", NULL }; + static const char *const stap_register_indirection_prefixes[] = { "(", + NULL }; + static const char *const stap_register_indirection_suffixes[] = { ")", + NULL }; linux_init_abi (info, gdbarch); @@ -1263,9 +1268,11 @@ ppc_linux_init_abi (struct gdbarch_info info, set_gdbarch_get_syscall_number (gdbarch, ppc_linux_get_syscall_number); /* SystemTap functions. */ - set_gdbarch_stap_integer_prefix (gdbarch, "i"); - set_gdbarch_stap_register_indirection_prefix (gdbarch, "("); - set_gdbarch_stap_register_indirection_suffix (gdbarch, ")"); + set_gdbarch_stap_integer_prefixes (gdbarch, stap_integer_prefixes); + set_gdbarch_stap_register_indirection_prefixes (gdbarch, + stap_register_indirection_prefixes); + set_gdbarch_stap_register_indirection_suffixes (gdbarch, + stap_register_indirection_suffixes); set_gdbarch_stap_gdb_register_prefix (gdbarch, "r"); set_gdbarch_stap_is_single_operand (gdbarch, ppc_stap_is_single_operand); set_gdbarch_stap_parse_special_token (gdbarch, diff --git a/gdb/s390-linux-tdep.c b/gdb/s390-linux-tdep.c index cd41de5..07237ad 100644 --- a/gdb/s390-linux-tdep.c +++ b/gdb/s390-linux-tdep.c @@ -3026,6 +3026,11 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) int have_linux_v1 = 0; int have_linux_v2 = 0; int first_pseudo_reg, last_pseudo_reg; + static const char *const stap_register_prefixes[] = { "%", NULL }; + static const char *const stap_register_indirection_prefixes[] = { "(", + NULL }; + static const char *const stap_register_indirection_suffixes[] = { ")", + NULL }; /* Default ABI and register size. */ switch (info.bfd_arch_info->mach) @@ -3358,9 +3363,11 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_get_siginfo_type (gdbarch, linux_get_siginfo_type); /* SystemTap functions. */ - set_gdbarch_stap_register_prefix (gdbarch, "%"); - set_gdbarch_stap_register_indirection_prefix (gdbarch, "("); - set_gdbarch_stap_register_indirection_suffix (gdbarch, ")"); + set_gdbarch_stap_register_prefixes (gdbarch, stap_register_prefixes); + set_gdbarch_stap_register_indirection_prefixes (gdbarch, + stap_register_indirection_prefixes); + set_gdbarch_stap_register_indirection_suffixes (gdbarch, + stap_register_indirection_suffixes); set_gdbarch_stap_is_single_operand (gdbarch, s390_stap_is_single_operand); return gdbarch; diff --git a/gdb/stap-probe.c b/gdb/stap-probe.c index 33d4569..1d94255 100644 --- a/gdb/stap-probe.c +++ b/gdb/stap-probe.c @@ -346,6 +346,191 @@ stap_get_expected_argument_type (struct gdbarch *gdbarch, } } +/* Helper function to check for a generic list of prefixes. GDBARCH + is the current gdbarch being used. S is the expression being + analyzed. If R is not NULL, it will be used to return the found + prefix. PREFIXES is the list of expected prefixes. + + This function does a case-insensitive match. + + Return 1 if any prefix has been found, zero otherwise. */ + +static int +stap_is_generic_prefix (struct gdbarch *gdbarch, const char *s, + const char **r, const char *const *prefixes) +{ + const char *const *p; + + if (prefixes == NULL) + { + if (r != NULL) + *r = ""; + + return 1; + } + + for (p = prefixes; *p != NULL; ++p) + { + if (strncasecmp (s, *p, strlen (*p)) == 0) + { + if (r != NULL) + *r = *p; + + return 1; + } + } + + return 0; +} + +/* Return 1 if S points to a register prefix, zero otherwise. For a + description of the arguments, look at stap_is_generic_prefix. */ + +static int +stap_is_register_prefix (struct gdbarch *gdbarch, const char *s, + const char **r) +{ + const char *const *t = gdbarch_stap_register_prefixes (gdbarch); + + return stap_is_generic_prefix (gdbarch, s, r, t); +} + +/* Return 1 if S points to a register indirection prefix, zero + otherwise. For a description of the arguments, look at + stap_is_generic_prefix. */ + +static int +stap_is_register_indirection_prefix (struct gdbarch *gdbarch, const char *s, + const char **r) +{ + const char *const *t = gdbarch_stap_register_indirection_prefixes (gdbarch); + + return stap_is_generic_prefix (gdbarch, s, r, t); +} + +/* Return 1 if S points to an integer prefix, zero otherwise. For a + description of the arguments, look at stap_is_generic_prefix. + + This function takes care of analyzing whether we are dealing with + an expected integer prefix, or, if there is no integer prefix to be + expected, whether we are dealing with a digit. It does a + case-insensitive match. */ + +static int +stap_is_integer_prefix (struct gdbarch *gdbarch, const char *s, + const char **r) +{ + const char *const *t = gdbarch_stap_integer_prefixes (gdbarch); + const char *const *p; + + if (t == NULL) + { + /* A NULL value here means that integers do not have a prefix. + We just check for a digit then. */ + if (r != NULL) + *r = ""; + + return isdigit (*s); + } + + for (p = t; *p != NULL; ++p) + { + size_t len = strlen (*p); + + if ((len == 0 && isdigit (*s)) + || (len > 0 && strncasecmp (s, *p, len) == 0)) + { + /* Integers may or may not have a prefix. The "len == 0" + check covers the case when integers do not have a prefix + (therefore, we just check if we have a digit). The call + to "strncasecmp" covers the case when they have a + prefix. */ + if (r != NULL) + *r = *p; + + return 1; + } + } + + return 0; +} + +/* Helper function to check for a generic list of suffixes. If we are + not expecting any suffixes, then it just returns 1. If we are + expecting at least one suffix, then it returns 1 if a suffix has + been found, zero otherwise. GDBARCH is the current gdbarch being + used. S is the expression being analyzed. If R is not NULL, it + will be used to return the found suffix. SUFFIXES is the list of + expected suffixes. This function does a case-insensitive + match. */ + +static int +stap_generic_check_suffix (struct gdbarch *gdbarch, const char *s, + const char **r, const char *const *suffixes) +{ + const char *const *p; + int found = 0; + + if (suffixes == NULL) + { + if (r != NULL) + *r = ""; + + return 1; + } + + for (p = suffixes; *p != NULL; ++p) + if (strncasecmp (s, *p, strlen (*p)) == 0) + { + if (r != NULL) + *r = *p; + + found = 1; + break; + } + + return found; +} + +/* Return 1 if S points to an integer suffix, zero otherwise. For a + description of the arguments, look at + stap_generic_check_suffix. */ + +static int +stap_check_integer_suffix (struct gdbarch *gdbarch, const char *s, + const char **r) +{ + const char *const *p = gdbarch_stap_integer_suffixes (gdbarch); + + return stap_generic_check_suffix (gdbarch, s, r, p); +} + +/* Return 1 if S points to a register suffix, zero otherwise. For a + description of the arguments, look at + stap_generic_check_suffix. */ + +static int +stap_check_register_suffix (struct gdbarch *gdbarch, const char *s, + const char **r) +{ + const char *const *p = gdbarch_stap_register_suffixes (gdbarch); + + return stap_generic_check_suffix (gdbarch, s, r, p); +} + +/* Return 1 if S points to a register indirection suffix, zero + otherwise. For a description of the arguments, look at + stap_generic_check_suffix. */ + +static int +stap_check_register_indirection_suffix (struct gdbarch *gdbarch, const char *s, + const char **r) +{ + const char *const *p = gdbarch_stap_register_indirection_suffixes (gdbarch); + + return stap_generic_check_suffix (gdbarch, s, r, p); +} + /* Function responsible for parsing a register operand according to SystemTap parlance. Assuming: @@ -385,24 +570,14 @@ stap_parse_register_operand (struct stap_parse_info *p) const char *start; char *regname; int len; - - /* Prefixes for the parser. */ - const char *reg_prefix = gdbarch_stap_register_prefix (gdbarch); - const char *reg_ind_prefix - = gdbarch_stap_register_indirection_prefix (gdbarch); const char *gdb_reg_prefix = gdbarch_stap_gdb_register_prefix (gdbarch); - int reg_prefix_len = reg_prefix ? strlen (reg_prefix) : 0; - int reg_ind_prefix_len = reg_ind_prefix ? strlen (reg_ind_prefix) : 0; int gdb_reg_prefix_len = gdb_reg_prefix ? strlen (gdb_reg_prefix) : 0; - - /* Suffixes for the parser. */ - const char *reg_suffix = gdbarch_stap_register_suffix (gdbarch); - const char *reg_ind_suffix - = gdbarch_stap_register_indirection_suffix (gdbarch); const char *gdb_reg_suffix = gdbarch_stap_gdb_register_suffix (gdbarch); - int reg_suffix_len = reg_suffix ? strlen (reg_suffix) : 0; - int reg_ind_suffix_len = reg_ind_suffix ? strlen (reg_ind_suffix) : 0; int gdb_reg_suffix_len = gdb_reg_suffix ? strlen (gdb_reg_suffix) : 0; + const char *reg_prefix; + const char *reg_ind_prefix; + const char *reg_suffix; + const char *reg_ind_suffix; /* Checking for a displacement argument. */ if (*p->arg == '+') @@ -438,11 +613,10 @@ stap_parse_register_operand (struct stap_parse_info *p) } /* Getting rid of register indirection prefix. */ - if (reg_ind_prefix - && strncmp (p->arg, reg_ind_prefix, reg_ind_prefix_len) == 0) + if (stap_is_register_indirection_prefix (gdbarch, p->arg, ®_ind_prefix)) { indirect_p = 1; - p->arg += reg_ind_prefix_len; + p->arg += strlen (reg_ind_prefix); } if (disp_p && !indirect_p) @@ -450,8 +624,8 @@ stap_parse_register_operand (struct stap_parse_info *p) p->saved_arg); /* Getting rid of register prefix. */ - if (reg_prefix && strncmp (p->arg, reg_prefix, reg_prefix_len) == 0) - p->arg += reg_prefix_len; + if (stap_is_register_prefix (gdbarch, p->arg, ®_prefix)) + p->arg += strlen (reg_prefix); /* Now we should have only the register name. Let's extract it and get the associated number. */ @@ -509,23 +683,21 @@ stap_parse_register_operand (struct stap_parse_info *p) } /* Getting rid of the register name suffix. */ - if (reg_suffix) - { - if (strncmp (p->arg, reg_suffix, reg_suffix_len) != 0) - error (_("Missing register name suffix `%s' on expression `%s'."), - reg_suffix, p->saved_arg); - - p->arg += reg_suffix_len; - } + if (stap_check_register_suffix (gdbarch, p->arg, ®_suffix)) + p->arg += strlen (reg_suffix); + else + error (_("Missing register name suffix on expression `%s'."), + p->saved_arg); /* Getting rid of the register indirection suffix. */ - if (indirect_p && reg_ind_suffix) + if (indirect_p) { - if (strncmp (p->arg, reg_ind_suffix, reg_ind_suffix_len) != 0) - error (_("Missing indirection suffix `%s' on expression `%s'."), - reg_ind_suffix, p->saved_arg); - - p->arg += reg_ind_suffix_len; + if (stap_check_register_indirection_suffix (gdbarch, p->arg, + ®_ind_suffix)) + p->arg += strlen (reg_ind_suffix); + else + error (_("Missing indirection suffix on expression `%s'."), + p->saved_arg); } } @@ -548,19 +720,7 @@ static void stap_parse_single_operand (struct stap_parse_info *p) { struct gdbarch *gdbarch = p->gdbarch; - - /* Prefixes for the parser. */ - const char *const_prefix = gdbarch_stap_integer_prefix (gdbarch); - const char *reg_prefix = gdbarch_stap_register_prefix (gdbarch); - const char *reg_ind_prefix - = gdbarch_stap_register_indirection_prefix (gdbarch); - int const_prefix_len = const_prefix ? strlen (const_prefix) : 0; - int reg_prefix_len = reg_prefix ? strlen (reg_prefix) : 0; - int reg_ind_prefix_len = reg_ind_prefix ? strlen (reg_ind_prefix) : 0; - - /* Suffixes for the parser. */ - const char *const_suffix = gdbarch_stap_integer_suffix (gdbarch); - int const_suffix_len = const_suffix ? strlen (const_suffix) : 0; + const char *int_prefix = NULL; /* We first try to parse this token as a "special token". */ if (gdbarch_stap_parse_special_token_p (gdbarch)) @@ -607,8 +767,7 @@ stap_parse_single_operand (struct stap_parse_info *p) tmp = endp; } - if (!reg_ind_prefix - || strncmp (tmp, reg_ind_prefix, reg_ind_prefix_len) != 0) + if (!stap_is_register_indirection_prefix (gdbarch, tmp, NULL)) { /* This is not a displacement. We skip the operator, and deal with it later. */ @@ -637,16 +796,23 @@ stap_parse_single_operand (struct stap_parse_info *p) char *endp; long number; - /* We can be dealing with a numeric constant (if `const_prefix' is - NULL), or with a register displacement. */ + /* We can be dealing with a numeric constant, or with a register + displacement. */ number = strtol (tmp, &endp, 10); tmp = endp; if (p->inside_paren_p) tmp = skip_spaces_const (tmp); - if (!const_prefix && reg_ind_prefix - && strncmp (tmp, reg_ind_prefix, reg_ind_prefix_len) != 0) + + /* If "stap_is_integer_prefix" returns true, it means we can + accept integers without a prefix here. But we also need to + check whether the next token (i.e., "tmp") is not a register + indirection prefix. */ + if (stap_is_integer_prefix (gdbarch, p->arg, NULL) + && !stap_is_register_indirection_prefix (gdbarch, tmp, NULL)) { + const char *int_suffix; + /* We are dealing with a numeric constant. */ write_exp_elt_opcode (OP_LONG); write_exp_elt_type (builtin_type (gdbarch)->builtin_long); @@ -655,30 +821,26 @@ stap_parse_single_operand (struct stap_parse_info *p) p->arg = tmp; - if (const_suffix) - { - if (strncmp (p->arg, const_suffix, const_suffix_len) == 0) - p->arg += const_suffix_len; - else - error (_("Invalid constant suffix on expression `%s'."), - p->saved_arg); - } + if (stap_check_integer_suffix (gdbarch, p->arg, &int_suffix)) + p->arg += strlen (int_suffix); + else + error (_("Invalid constant suffix on expression `%s'."), + p->saved_arg); } - else if (reg_ind_prefix - && strncmp (tmp, reg_ind_prefix, reg_ind_prefix_len) == 0) + else if (stap_is_register_indirection_prefix (gdbarch, tmp, NULL)) stap_parse_register_operand (p); else error (_("Unknown numeric token on expression `%s'."), p->saved_arg); } - else if (const_prefix - && strncmp (p->arg, const_prefix, const_prefix_len) == 0) + else if (stap_is_integer_prefix (gdbarch, p->arg, &int_prefix)) { /* We are dealing with a numeric constant. */ long number; char *endp; + const char *int_suffix; - p->arg += const_prefix_len; + p->arg += strlen (int_prefix); number = strtol (p->arg, &endp, 10); p->arg = endp; @@ -687,19 +849,14 @@ stap_parse_single_operand (struct stap_parse_info *p) write_exp_elt_longcst (number); write_exp_elt_opcode (OP_LONG); - if (const_suffix) - { - if (strncmp (p->arg, const_suffix, const_suffix_len) == 0) - p->arg += const_suffix_len; - else - error (_("Invalid constant suffix on expression `%s'."), - p->saved_arg); - } + if (stap_check_integer_suffix (gdbarch, p->arg, &int_suffix)) + p->arg += strlen (int_suffix); + else + error (_("Invalid constant suffix on expression `%s'."), + p->saved_arg); } - 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)) + else if (stap_is_register_prefix (gdbarch, p->arg, NULL) + || stap_is_register_indirection_prefix (gdbarch, p->arg, NULL)) stap_parse_register_operand (p); else error (_("Operator `%c' not recognized on expression `%s'."),