This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [PATCH] Split i386_stap_parse_special_token into smaller functions
- From: Joel Brobecker <brobecker at adacore dot com>
- To: Sergio Durigan Junior <sergiodj at redhat dot com>
- Cc: GDB Patches <gdb-patches at sourceware dot org>, Mark Kettenis <kettenis at gnu dot org>
- Date: Mon, 30 Dec 2013 07:11:12 +0400
- Subject: Re: [PATCH] Split i386_stap_parse_special_token into smaller functions
- Authentication-results: sourceware.org; auth=none
- References: <m37gaodxg2 dot fsf at redhat dot com>
> As requested by Joel on:
>
> <https://sourceware.org/ml/gdb-patches/2013-12/msg00977.html>
>
> I am reposting this separate patch whose only purpose is to split
> i386_stap_parse_special_token into smaller functions. I haven't
> modified anything logical in the functions, i.e., there's still one
> latent bug on i386_stap_parse_special_token_triplet now. I will soon
> post a patch to fix this, and to also improve the readability of the two
> new functions.
>
> I am also posting the output of "git diff -b" here.
Thank you, Sergio. This patch is missing a ChangeLog :).
FWIW, this patch looks good to me, and it is IMO a nice improvement
over the current state. But i386-tdep.c is usually under Mark's
responsibility, so let's give him a little bit of time to reply
as well.
>
> -=-=- git diff -b -=-=-
>
> diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
> index 4f86f0c..1a435c1 100644
> --- a/gdb/i386-tdep.c
> +++ b/gdb/i386-tdep.c
> @@ -3605,40 +3605,20 @@ i386_stap_is_single_operand (struct gdbarch *gdbarch, const char *s)
> || (*s == '%' && isalpha (s[1]))); /* Register access. */
> }
>
> -/* Implementation of `gdbarch_stap_parse_special_token', as defined in
> - gdbarch.h. */
> -
> -int
> -i386_stap_parse_special_token (struct gdbarch *gdbarch,
> - struct stap_parse_info *p)
> -{
> - /* In order to parse special tokens, we use a state-machine that go
> - through every known token and try to get a match. */
> - enum
> - {
> - TRIPLET,
> - THREE_ARG_DISPLACEMENT,
> - DONE
> - } current_state;
> -
> - current_state = TRIPLET;
> +/* Helper function for i386_stap_parse_special_token.
>
> - /* The special tokens to be parsed here are:
> -
> - - `register base + (register index * size) + offset', as represented
> - in `(%rcx,%rax,8)', or `[OFFSET](BASE_REG,INDEX_REG[,SIZE])'.
> + This function parses operands of the form `-8+3+1(%rbp)', which
> + must be interpreted as `*(-8 + 3 - 1 + (void *) $eax)'.
>
> - - Operands of the form `-8+3+1(%rbp)', which must be interpreted as
> - `*(-8 + 3 - 1 + (void *) $eax)'. */
> + Return 1 if the operand was parsed successfully, zero
> + otherwise. */
>
> - while (current_state != DONE)
> - {
> +static int
> +i386_stap_parse_special_token_triplet (struct gdbarch *gdbarch,
> + struct stap_parse_info *p)
> +{
> const char *s = p->arg;
>
> - switch (current_state)
> - {
> - case TRIPLET:
> - {
> if (isdigit (*s) || *s == '-' || *s == '+')
> {
> int got_minus[3];
> @@ -3665,7 +3645,7 @@ i386_stap_parse_special_token (struct gdbarch *gdbarch,
> if (*s != '+' && *s != '-')
> {
> /* We are not dealing with a triplet. */
> - break;
> + return 0;
> }
>
> got_minus[1] = 0;
> @@ -3683,7 +3663,7 @@ i386_stap_parse_special_token (struct gdbarch *gdbarch,
> if (*s != '+' && *s != '-')
> {
> /* We are not dealing with a triplet. */
> - break;
> + return 0;
> }
>
> got_minus[2] = 0;
> @@ -3699,7 +3679,7 @@ i386_stap_parse_special_token (struct gdbarch *gdbarch,
> s = endp;
>
> if (*s != '(' || s[1] != '%')
> - break;
> + return 0;
>
> s += 2;
> start = s;
> @@ -3708,7 +3688,7 @@ i386_stap_parse_special_token (struct gdbarch *gdbarch,
> ++s;
>
> if (*s++ != ')')
> - break;
> + return 0;
>
> len = s - start;
> regname = alloca (len + 1);
> @@ -3716,17 +3696,14 @@ i386_stap_parse_special_token (struct gdbarch *gdbarch,
> strncpy (regname, start, len);
> regname[len] = '\0';
>
> - if (user_reg_map_name_to_regnum (gdbarch,
> - regname, len) == -1)
> - error (_("Invalid register name `%s' "
> - "on expression `%s'."),
> + if (user_reg_map_name_to_regnum (gdbarch, regname, len) == -1)
> + error (_("Invalid register name `%s' on expression `%s'."),
> regname, p->saved_arg);
>
> for (i = 0; i < 3; i++)
> {
> write_exp_elt_opcode (OP_LONG);
> - write_exp_elt_type
> - (builtin_type (gdbarch)->builtin_long);
> + write_exp_elt_type (builtin_type (gdbarch)->builtin_long);
> write_exp_elt_longcst (displacements[i]);
> write_exp_elt_opcode (OP_LONG);
> if (got_minus[i])
> @@ -3757,10 +3734,25 @@ i386_stap_parse_special_token (struct gdbarch *gdbarch,
>
> return 1;
> }
> - break;
> - }
> - case THREE_ARG_DISPLACEMENT:
> - {
> +
> + return 0;
> +}
> +
> +/* Helper function for i386_stap_parse_special_token.
> +
> + This function parses operands of the form `register base +
> + (register index * size) + offset', as represented in
> + `(%rcx,%rax,8)', or `[OFFSET](BASE_REG,INDEX_REG[,SIZE])'.
> +
> + Return 1 if the operand was parsed successfully, zero
> + otherwise. */
> +
> +static int
> +i386_stap_parse_special_token_three_arg_disp (struct gdbarch *gdbarch,
> + struct stap_parse_info *p)
> +{
> + const char *s = p->arg;
> +
> if (isdigit (*s) || *s == '(' || *s == '-' || *s == '+')
> {
> int offset_minus = 0;
> @@ -3783,7 +3775,7 @@ i386_stap_parse_special_token (struct gdbarch *gdbarch,
> }
>
> if (offset_minus && !isdigit (*s))
> - break;
> + return 0;
>
> if (isdigit (*s))
> {
> @@ -3794,7 +3786,7 @@ i386_stap_parse_special_token (struct gdbarch *gdbarch,
> }
>
> if (*s != '(' || s[1] != '%')
> - break;
> + return 0;
>
> s += 2;
> start = s;
> @@ -3803,17 +3795,15 @@ i386_stap_parse_special_token (struct gdbarch *gdbarch,
> ++s;
>
> if (*s != ',' || s[1] != '%')
> - break;
> + return 0;
>
> len_base = s - start;
> base = alloca (len_base + 1);
> strncpy (base, start, len_base);
> base[len_base] = '\0';
>
> - if (user_reg_map_name_to_regnum (gdbarch,
> - base, len_base) == -1)
> - error (_("Invalid register name `%s' "
> - "on expression `%s'."),
> + if (user_reg_map_name_to_regnum (gdbarch, base, len_base) == -1)
> + error (_("Invalid register name `%s' on expression `%s'."),
> base, p->saved_arg);
>
> s += 2;
> @@ -3827,14 +3817,12 @@ i386_stap_parse_special_token (struct gdbarch *gdbarch,
> strncpy (index, start, len_index);
> index[len_index] = '\0';
>
> - if (user_reg_map_name_to_regnum (gdbarch,
> - index, len_index) == -1)
> - error (_("Invalid register name `%s' "
> - "on expression `%s'."),
> + if (user_reg_map_name_to_regnum (gdbarch, index, len_index) == -1)
> + error (_("Invalid register name `%s' on expression `%s'."),
> index, p->saved_arg);
>
> if (*s != ',' && *s != ')')
> - break;
> + return 0;
>
> if (*s == ',')
> {
> @@ -3853,7 +3841,7 @@ i386_stap_parse_special_token (struct gdbarch *gdbarch,
> s = endp;
>
> if (*s != ')')
> - break;
> + return 0;
> }
>
> ++s;
> @@ -3861,8 +3849,7 @@ i386_stap_parse_special_token (struct gdbarch *gdbarch,
> if (offset)
> {
> write_exp_elt_opcode (OP_LONG);
> - write_exp_elt_type
> - (builtin_type (gdbarch)->builtin_long);
> + write_exp_elt_type (builtin_type (gdbarch)->builtin_long);
> write_exp_elt_longcst (offset);
> write_exp_elt_opcode (OP_LONG);
> if (offset_minus)
> @@ -3887,8 +3874,7 @@ i386_stap_parse_special_token (struct gdbarch *gdbarch,
> if (size)
> {
> write_exp_elt_opcode (OP_LONG);
> - write_exp_elt_type
> - (builtin_type (gdbarch)->builtin_long);
> + write_exp_elt_type (builtin_type (gdbarch)->builtin_long);
> write_exp_elt_longcst (size);
> write_exp_elt_opcode (OP_LONG);
> if (size_minus)
> @@ -3908,8 +3894,49 @@ i386_stap_parse_special_token (struct gdbarch *gdbarch,
>
> return 1;
> }
> +
> + return 0;
> +}
> +
> +/* Implementation of `gdbarch_stap_parse_special_token', as defined in
> + gdbarch.h. */
> +
> +int
> +i386_stap_parse_special_token (struct gdbarch *gdbarch,
> + struct stap_parse_info *p)
> +{
> + /* In order to parse special tokens, we use a state-machine that go
> + through every known token and try to get a match. */
> + enum
> + {
> + TRIPLET,
> + THREE_ARG_DISPLACEMENT,
> + DONE
> + } current_state;
> +
> + current_state = TRIPLET;
> +
> + /* The special tokens to be parsed here are:
> +
> + - `register base + (register index * size) + offset', as represented
> + in `(%rcx,%rax,8)', or `[OFFSET](BASE_REG,INDEX_REG[,SIZE])'.
> +
> + - Operands of the form `-8+3+1(%rbp)', which must be interpreted as
> + `*(-8 + 3 - 1 + (void *) $eax)'. */
> +
> + while (current_state != DONE)
> + {
> + switch (current_state)
> + {
> + case TRIPLET:
> + if (i386_stap_parse_special_token_triplet (gdbarch, p))
> + return 1;
> + break;
> +
> + case THREE_ARG_DISPLACEMENT:
> + if (i386_stap_parse_special_token_three_arg_disp (gdbarch, p))
> + return 1;
> break;
> - }
> }
>
> /* Advancing to the next state. */
>
> -=-=- git diff -b -=-=-
>
> I tested this on Fedora 18 x86_64, everything is OK.
>
> OK to apply?
>
> --
> Sergio
>
> 2013-12-29 Sergio Durigan Junior <sergiodj@redhat.com>
>
> * i386-tdep.c (i386_stap_parse_special_token_triplet): New
> function, with code from i386_stap_parse_special_token.
> (i386_stap_parse_special_token_three_arg_disp): Likewise.
> (i386_stap_parse_special_token): Move code to the two functions
> above; simplify it.
>
> diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
> index 4f86f0c..1a435c1 100644
> --- a/gdb/i386-tdep.c
> +++ b/gdb/i386-tdep.c
> @@ -3605,311 +3605,338 @@ i386_stap_is_single_operand (struct gdbarch *gdbarch, const char *s)
> || (*s == '%' && isalpha (s[1]))); /* Register access. */
> }
>
> -/* Implementation of `gdbarch_stap_parse_special_token', as defined in
> - gdbarch.h. */
> +/* Helper function for i386_stap_parse_special_token.
>
> -int
> -i386_stap_parse_special_token (struct gdbarch *gdbarch,
> - struct stap_parse_info *p)
> + This function parses operands of the form `-8+3+1(%rbp)', which
> + must be interpreted as `*(-8 + 3 - 1 + (void *) $eax)'.
> +
> + Return 1 if the operand was parsed successfully, zero
> + otherwise. */
> +
> +static int
> +i386_stap_parse_special_token_triplet (struct gdbarch *gdbarch,
> + struct stap_parse_info *p)
> {
> - /* In order to parse special tokens, we use a state-machine that go
> - through every known token and try to get a match. */
> - enum
> + const char *s = p->arg;
> +
> + if (isdigit (*s) || *s == '-' || *s == '+')
> {
> - TRIPLET,
> - THREE_ARG_DISPLACEMENT,
> - DONE
> - } current_state;
> + int got_minus[3];
> + int i;
> + long displacements[3];
> + const char *start;
> + char *regname;
> + int len;
> + struct stoken str;
> + char *endp;
> +
> + got_minus[0] = 0;
> + if (*s == '+')
> + ++s;
> + else if (*s == '-')
> + {
> + ++s;
> + got_minus[0] = 1;
> + }
>
> - current_state = TRIPLET;
> + displacements[0] = strtol (s, &endp, 10);
> + s = endp;
>
> - /* The special tokens to be parsed here are:
> + if (*s != '+' && *s != '-')
> + {
> + /* We are not dealing with a triplet. */
> + return 0;
> + }
>
> - - `register base + (register index * size) + offset', as represented
> - in `(%rcx,%rax,8)', or `[OFFSET](BASE_REG,INDEX_REG[,SIZE])'.
> + got_minus[1] = 0;
> + if (*s == '+')
> + ++s;
> + else
> + {
> + ++s;
> + got_minus[1] = 1;
> + }
>
> - - Operands of the form `-8+3+1(%rbp)', which must be interpreted as
> - `*(-8 + 3 - 1 + (void *) $eax)'. */
> + displacements[1] = strtol (s, &endp, 10);
> + s = endp;
>
> - while (current_state != DONE)
> - {
> - const char *s = p->arg;
> + if (*s != '+' && *s != '-')
> + {
> + /* We are not dealing with a triplet. */
> + return 0;
> + }
>
> - switch (current_state)
> + got_minus[2] = 0;
> + if (*s == '+')
> + ++s;
> + else
> {
> - case TRIPLET:
> - {
> - if (isdigit (*s) || *s == '-' || *s == '+')
> - {
> - int got_minus[3];
> - int i;
> - long displacements[3];
> - const char *start;
> - char *regname;
> - int len;
> - struct stoken str;
> - char *endp;
> -
> - got_minus[0] = 0;
> - if (*s == '+')
> - ++s;
> - else if (*s == '-')
> - {
> - ++s;
> - got_minus[0] = 1;
> - }
> + ++s;
> + got_minus[2] = 1;
> + }
>
> - displacements[0] = strtol (s, &endp, 10);
> - s = endp;
> + displacements[2] = strtol (s, &endp, 10);
> + s = endp;
>
> - if (*s != '+' && *s != '-')
> - {
> - /* We are not dealing with a triplet. */
> - break;
> - }
> + if (*s != '(' || s[1] != '%')
> + return 0;
>
> - got_minus[1] = 0;
> - if (*s == '+')
> - ++s;
> - else
> - {
> - ++s;
> - got_minus[1] = 1;
> - }
> + s += 2;
> + start = s;
>
> - displacements[1] = strtol (s, &endp, 10);
> - s = endp;
> + while (isalnum (*s))
> + ++s;
>
> - if (*s != '+' && *s != '-')
> - {
> - /* We are not dealing with a triplet. */
> - break;
> - }
> + if (*s++ != ')')
> + return 0;
>
> - got_minus[2] = 0;
> - if (*s == '+')
> - ++s;
> - else
> - {
> - ++s;
> - got_minus[2] = 1;
> - }
> + len = s - start;
> + regname = alloca (len + 1);
>
> - displacements[2] = strtol (s, &endp, 10);
> - s = endp;
> + strncpy (regname, start, len);
> + regname[len] = '\0';
>
> - if (*s != '(' || s[1] != '%')
> - break;
> + if (user_reg_map_name_to_regnum (gdbarch, regname, len) == -1)
> + error (_("Invalid register name `%s' on expression `%s'."),
> + regname, p->saved_arg);
>
> - s += 2;
> - start = s;
> + for (i = 0; i < 3; i++)
> + {
> + write_exp_elt_opcode (OP_LONG);
> + write_exp_elt_type (builtin_type (gdbarch)->builtin_long);
> + write_exp_elt_longcst (displacements[i]);
> + write_exp_elt_opcode (OP_LONG);
> + if (got_minus[i])
> + write_exp_elt_opcode (UNOP_NEG);
> + }
>
> - while (isalnum (*s))
> - ++s;
> + write_exp_elt_opcode (OP_REGISTER);
> + str.ptr = regname;
> + str.length = len;
> + write_exp_string (str);
> + write_exp_elt_opcode (OP_REGISTER);
>
> - if (*s++ != ')')
> - break;
> + write_exp_elt_opcode (UNOP_CAST);
> + write_exp_elt_type (builtin_type (gdbarch)->builtin_data_ptr);
> + write_exp_elt_opcode (UNOP_CAST);
>
> - len = s - start;
> - regname = alloca (len + 1);
> + write_exp_elt_opcode (BINOP_ADD);
> + write_exp_elt_opcode (BINOP_ADD);
> + write_exp_elt_opcode (BINOP_ADD);
>
> - strncpy (regname, start, len);
> - regname[len] = '\0';
> + write_exp_elt_opcode (UNOP_CAST);
> + write_exp_elt_type (lookup_pointer_type (p->arg_type));
> + write_exp_elt_opcode (UNOP_CAST);
>
> - if (user_reg_map_name_to_regnum (gdbarch,
> - regname, len) == -1)
> - error (_("Invalid register name `%s' "
> - "on expression `%s'."),
> - regname, p->saved_arg);
> + write_exp_elt_opcode (UNOP_IND);
>
> - for (i = 0; i < 3; i++)
> - {
> - write_exp_elt_opcode (OP_LONG);
> - write_exp_elt_type
> - (builtin_type (gdbarch)->builtin_long);
> - write_exp_elt_longcst (displacements[i]);
> - write_exp_elt_opcode (OP_LONG);
> - if (got_minus[i])
> - write_exp_elt_opcode (UNOP_NEG);
> - }
> + p->arg = s;
>
> - write_exp_elt_opcode (OP_REGISTER);
> - str.ptr = regname;
> - str.length = len;
> - write_exp_string (str);
> - write_exp_elt_opcode (OP_REGISTER);
> + return 1;
> + }
>
> - write_exp_elt_opcode (UNOP_CAST);
> - write_exp_elt_type (builtin_type (gdbarch)->builtin_data_ptr);
> - write_exp_elt_opcode (UNOP_CAST);
> + return 0;
> +}
>
> - write_exp_elt_opcode (BINOP_ADD);
> - write_exp_elt_opcode (BINOP_ADD);
> - write_exp_elt_opcode (BINOP_ADD);
> +/* Helper function for i386_stap_parse_special_token.
>
> - write_exp_elt_opcode (UNOP_CAST);
> - write_exp_elt_type (lookup_pointer_type (p->arg_type));
> - write_exp_elt_opcode (UNOP_CAST);
> + This function parses operands of the form `register base +
> + (register index * size) + offset', as represented in
> + `(%rcx,%rax,8)', or `[OFFSET](BASE_REG,INDEX_REG[,SIZE])'.
>
> - write_exp_elt_opcode (UNOP_IND);
> + Return 1 if the operand was parsed successfully, zero
> + otherwise. */
>
> - p->arg = s;
> +static int
> +i386_stap_parse_special_token_three_arg_disp (struct gdbarch *gdbarch,
> + struct stap_parse_info *p)
> +{
> + const char *s = p->arg;
>
> - return 1;
> - }
> - break;
> - }
> - case THREE_ARG_DISPLACEMENT:
> - {
> - if (isdigit (*s) || *s == '(' || *s == '-' || *s == '+')
> - {
> - int offset_minus = 0;
> - long offset = 0;
> - int size_minus = 0;
> - long size = 0;
> - const char *start;
> - char *base;
> - int len_base;
> - char *index;
> - int len_index;
> - struct stoken base_token, index_token;
> -
> - if (*s == '+')
> - ++s;
> - else if (*s == '-')
> - {
> - ++s;
> - offset_minus = 1;
> - }
> + if (isdigit (*s) || *s == '(' || *s == '-' || *s == '+')
> + {
> + int offset_minus = 0;
> + long offset = 0;
> + int size_minus = 0;
> + long size = 0;
> + const char *start;
> + char *base;
> + int len_base;
> + char *index;
> + int len_index;
> + struct stoken base_token, index_token;
> +
> + if (*s == '+')
> + ++s;
> + else if (*s == '-')
> + {
> + ++s;
> + offset_minus = 1;
> + }
>
> - if (offset_minus && !isdigit (*s))
> - break;
> + if (offset_minus && !isdigit (*s))
> + return 0;
>
> - if (isdigit (*s))
> - {
> - char *endp;
> + if (isdigit (*s))
> + {
> + char *endp;
>
> - offset = strtol (s, &endp, 10);
> - s = endp;
> - }
> + offset = strtol (s, &endp, 10);
> + s = endp;
> + }
>
> - if (*s != '(' || s[1] != '%')
> - break;
> + if (*s != '(' || s[1] != '%')
> + return 0;
>
> - s += 2;
> - start = s;
> + s += 2;
> + start = s;
>
> - while (isalnum (*s))
> - ++s;
> + while (isalnum (*s))
> + ++s;
>
> - if (*s != ',' || s[1] != '%')
> - break;
> + if (*s != ',' || s[1] != '%')
> + return 0;
>
> - len_base = s - start;
> - base = alloca (len_base + 1);
> - strncpy (base, start, len_base);
> - base[len_base] = '\0';
> + len_base = s - start;
> + base = alloca (len_base + 1);
> + strncpy (base, start, len_base);
> + base[len_base] = '\0';
>
> - if (user_reg_map_name_to_regnum (gdbarch,
> - base, len_base) == -1)
> - error (_("Invalid register name `%s' "
> - "on expression `%s'."),
> - base, p->saved_arg);
> + if (user_reg_map_name_to_regnum (gdbarch, base, len_base) == -1)
> + error (_("Invalid register name `%s' on expression `%s'."),
> + base, p->saved_arg);
>
> - s += 2;
> - start = s;
> + s += 2;
> + start = s;
>
> - while (isalnum (*s))
> - ++s;
> + while (isalnum (*s))
> + ++s;
>
> - len_index = s - start;
> - index = alloca (len_index + 1);
> - strncpy (index, start, len_index);
> - index[len_index] = '\0';
> + len_index = s - start;
> + index = alloca (len_index + 1);
> + strncpy (index, start, len_index);
> + index[len_index] = '\0';
>
> - if (user_reg_map_name_to_regnum (gdbarch,
> - index, len_index) == -1)
> - error (_("Invalid register name `%s' "
> - "on expression `%s'."),
> - index, p->saved_arg);
> + if (user_reg_map_name_to_regnum (gdbarch, index, len_index) == -1)
> + error (_("Invalid register name `%s' on expression `%s'."),
> + index, p->saved_arg);
>
> - if (*s != ',' && *s != ')')
> - break;
> + if (*s != ',' && *s != ')')
> + return 0;
>
> - if (*s == ',')
> - {
> - char *endp;
> + if (*s == ',')
> + {
> + char *endp;
>
> - ++s;
> - if (*s == '+')
> - ++s;
> - else if (*s == '-')
> - {
> - ++s;
> - size_minus = 1;
> - }
> + ++s;
> + if (*s == '+')
> + ++s;
> + else if (*s == '-')
> + {
> + ++s;
> + size_minus = 1;
> + }
>
> - size = strtol (s, &endp, 10);
> - s = endp;
> + size = strtol (s, &endp, 10);
> + s = endp;
>
> - if (*s != ')')
> - break;
> - }
> + if (*s != ')')
> + return 0;
> + }
>
> - ++s;
> + ++s;
>
> - if (offset)
> - {
> - write_exp_elt_opcode (OP_LONG);
> - write_exp_elt_type
> - (builtin_type (gdbarch)->builtin_long);
> - write_exp_elt_longcst (offset);
> - write_exp_elt_opcode (OP_LONG);
> - if (offset_minus)
> - write_exp_elt_opcode (UNOP_NEG);
> - }
> + if (offset)
> + {
> + write_exp_elt_opcode (OP_LONG);
> + write_exp_elt_type (builtin_type (gdbarch)->builtin_long);
> + write_exp_elt_longcst (offset);
> + write_exp_elt_opcode (OP_LONG);
> + if (offset_minus)
> + write_exp_elt_opcode (UNOP_NEG);
> + }
>
> - write_exp_elt_opcode (OP_REGISTER);
> - base_token.ptr = base;
> - base_token.length = len_base;
> - write_exp_string (base_token);
> - write_exp_elt_opcode (OP_REGISTER);
> + write_exp_elt_opcode (OP_REGISTER);
> + base_token.ptr = base;
> + base_token.length = len_base;
> + write_exp_string (base_token);
> + write_exp_elt_opcode (OP_REGISTER);
>
> - if (offset)
> - write_exp_elt_opcode (BINOP_ADD);
> + if (offset)
> + write_exp_elt_opcode (BINOP_ADD);
>
> - write_exp_elt_opcode (OP_REGISTER);
> - index_token.ptr = index;
> - index_token.length = len_index;
> - write_exp_string (index_token);
> - write_exp_elt_opcode (OP_REGISTER);
> + write_exp_elt_opcode (OP_REGISTER);
> + index_token.ptr = index;
> + index_token.length = len_index;
> + write_exp_string (index_token);
> + write_exp_elt_opcode (OP_REGISTER);
>
> - if (size)
> - {
> - write_exp_elt_opcode (OP_LONG);
> - write_exp_elt_type
> - (builtin_type (gdbarch)->builtin_long);
> - write_exp_elt_longcst (size);
> - write_exp_elt_opcode (OP_LONG);
> - if (size_minus)
> - write_exp_elt_opcode (UNOP_NEG);
> - write_exp_elt_opcode (BINOP_MUL);
> - }
> + if (size)
> + {
> + write_exp_elt_opcode (OP_LONG);
> + write_exp_elt_type (builtin_type (gdbarch)->builtin_long);
> + write_exp_elt_longcst (size);
> + write_exp_elt_opcode (OP_LONG);
> + if (size_minus)
> + write_exp_elt_opcode (UNOP_NEG);
> + write_exp_elt_opcode (BINOP_MUL);
> + }
>
> - write_exp_elt_opcode (BINOP_ADD);
> + write_exp_elt_opcode (BINOP_ADD);
>
> - write_exp_elt_opcode (UNOP_CAST);
> - write_exp_elt_type (lookup_pointer_type (p->arg_type));
> - write_exp_elt_opcode (UNOP_CAST);
> + write_exp_elt_opcode (UNOP_CAST);
> + write_exp_elt_type (lookup_pointer_type (p->arg_type));
> + write_exp_elt_opcode (UNOP_CAST);
>
> - write_exp_elt_opcode (UNOP_IND);
> + write_exp_elt_opcode (UNOP_IND);
>
> - p->arg = s;
> + p->arg = s;
>
> - return 1;
> - }
> - break;
> - }
> + return 1;
> + }
> +
> + return 0;
> +}
> +
> +/* Implementation of `gdbarch_stap_parse_special_token', as defined in
> + gdbarch.h. */
> +
> +int
> +i386_stap_parse_special_token (struct gdbarch *gdbarch,
> + struct stap_parse_info *p)
> +{
> + /* In order to parse special tokens, we use a state-machine that go
> + through every known token and try to get a match. */
> + enum
> + {
> + TRIPLET,
> + THREE_ARG_DISPLACEMENT,
> + DONE
> + } current_state;
> +
> + current_state = TRIPLET;
> +
> + /* The special tokens to be parsed here are:
> +
> + - `register base + (register index * size) + offset', as represented
> + in `(%rcx,%rax,8)', or `[OFFSET](BASE_REG,INDEX_REG[,SIZE])'.
> +
> + - Operands of the form `-8+3+1(%rbp)', which must be interpreted as
> + `*(-8 + 3 - 1 + (void *) $eax)'. */
> +
> + while (current_state != DONE)
> + {
> + switch (current_state)
> + {
> + case TRIPLET:
> + if (i386_stap_parse_special_token_triplet (gdbarch, p))
> + return 1;
> + break;
> +
> + case THREE_ARG_DISPLACEMENT:
> + if (i386_stap_parse_special_token_three_arg_disp (gdbarch, p))
> + return 1;
> + break;
> }
>
> /* Advancing to the next state. */
--
Joel