This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Extend SystemTap SDT probe argument parser


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  <sergiodj@redhat.com>

	* 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, &reg_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, &reg_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, &reg_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,
+						  &reg_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'."),


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]