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:
Sergio Durigan Junior 2014-01-12 01:32:26 -02:00
parent 024f468406
commit 5acfdbae5d
2 changed files with 307 additions and 272 deletions

View file

@ -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>

View file

@ -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. */