From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7823 invoked by alias); 29 Dec 2013 05:43:22 -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 7807 invoked by uid 89); 29 Dec 2013 05:43:20 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.7 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; Sun, 29 Dec 2013 05:43:18 +0000 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id rBT5hG8Z005809 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Sun, 29 Dec 2013 00:43:16 -0500 Received: from psique ([10.3.113.9]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id rBT5hAoL016923 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Sun, 29 Dec 2013 00:43:12 -0500 From: Sergio Durigan Junior To: GDB Patches Cc: Joel Brobecker Subject: [PATCH] Split i386_stap_parse_special_token into smaller functions X-URL: http://www.redhat.com Date: Sun, 29 Dec 2013 05:43:00 -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/msg00984.txt.bz2 Hi, As requested by Joel on: 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. -=-=- 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 * 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. */