Split i386_stap_parse_special_token into smaller functions
This patch reorganizes code on gdb/i386-tdep.c's SystemTap SDT probe support functions. Before it, the code to parse special operands on x86 lived in a single, big function. This patch creates 2 new functions that makes the code more organized and removes a few indentation levels (which is always good IMO). 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. 2014-01-12 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.
This commit is contained in:
parent
024f468406
commit
5acfdbae5d
2 changed files with 307 additions and 272 deletions
|
@ -1,3 +1,11 @@
|
|||
2014-01-12 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.
|
||||
|
||||
2014-01-09 Pedro Alves <palves@redhat.com>
|
||||
Hui Zhu <hui@codesourcery.com>
|
||||
|
||||
|
|
149
gdb/i386-tdep.c
149
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. */
|
||||
/* Helper function for i386_stap_parse_special_token.
|
||||
|
||||
int
|
||||
i386_stap_parse_special_token (struct gdbarch *gdbarch,
|
||||
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
|
||||
{
|
||||
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)
|
||||
{
|
||||
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. */
|
||||
|
|
Loading…
Reference in a new issue