public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM] archer-sergiodj-stap: Implementing the compilation for agent expressions, and fixing a bug.
@ 2011-03-18 7:30 sergiodj
0 siblings, 0 replies; only message in thread
From: sergiodj @ 2011-03-18 7:30 UTC (permalink / raw)
To: archer-commits
The branch, archer-sergiodj-stap has been updated
via 7938adaa88d884b0a0bf81a213ed0d100222214e (commit)
from 3d0f221b6a17aa114b9e1bf52f62306ceae9b72d (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email.
- Log -----------------------------------------------------------------
commit 7938adaa88d884b0a0bf81a213ed0d100222214e
Author: Sergio Durigan Junior <sergiodj@redhat.com>
Date: Fri Mar 18 04:27:40 2011 -0300
Implementing the compilation for agent expressions, and fixing a bug.
This commit implements the basic features for compiling probe's
arguments into agent expressions, for tracepoint support. It still has
some questionable points, which I intend to fix ASAP.
I have also fixed a bug in the evaluation code, which were causing
expressions like `(~(2) * 3)' to be evaluated like `~(2 * 3)'.
-----------------------------------------------------------------------
Summary of changes:
gdb/elfread.c | 12 ++-
gdb/stap-probe.c | 288 ++++++++++++++++++++++++++++++++++++++++++++++++------
gdb/stap-probe.h | 17 +++-
3 files changed, 284 insertions(+), 33 deletions(-)
First 500 lines of diff:
diff --git a/gdb/elfread.c b/gdb/elfread.c
index 37e19e7..cf41fbf 100644
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
@@ -1273,6 +1273,16 @@ elf_evaluate_probe_argument (struct objfile *objfile,
}
static void
+elf_compile_to_ax (struct objfile *objfile,
+ const struct stap_probe *probe,
+ struct agent_expr *expr,
+ struct axs_value *value,
+ int n)
+{
+ stap_compile_to_ax (objfile, probe, expr, value, n);
+}
+
+static void
elf_symfile_relocate_probe (struct objfile *objfile,
struct section_offsets *new_offsets,
struct section_offsets *delta)
@@ -1312,7 +1322,7 @@ static const struct sym_probe_fns elf_probe_fns =
elf_get_probes, /* sym_get_probes */
elf_get_probe_argument_count, /* sym_get_probe_argument_count */
elf_evaluate_probe_argument, /* sym_evaluate_probe_argument */
- NULL, /* sym_compile_to_ax */
+ elf_compile_to_ax, /* sym_compile_to_ax */
elf_symfile_relocate_probe, /* sym_relocate_probe */
};
diff --git a/gdb/stap-probe.c b/gdb/stap-probe.c
index 7613400..eb2fb7f 100644
--- a/gdb/stap-probe.c
+++ b/gdb/stap-probe.c
@@ -70,6 +70,7 @@ struct stap_args_info
/* Struct that contains all the necessary information to evaluate
an expression. */
+
struct stap_evaluation_info
{
/* The constant pointer which holds the expression. This is primarily
@@ -90,21 +91,36 @@ struct stap_evaluation_info
/* The bitness specified for this argument. */
enum stap_arg_bitness bitness;
+
+ /* Flag to indicate if we are compiling an agent expression. */
+ int compiling_p;
+
+ /* If the above flag is true (one), this field will contain the
+ pointer to the agent expression. */
+ struct agent_expr *aexpr;
+
+ /* The value we are modifying (for agent expression). */
+ struct axs_value *value;
};
/* This dummy variable is used when parsing a probe's argument fails.
In this case, the number of arguments for this probe is zero, so that's
why this variable is useful. */
+
static struct stap_args_info dummy_stap_args_info =
{ 0, NULL, NULL };
/* Evaluation function for probe's argument expressions. LHS represents
the left side of the expression, and PREC is the precedence of the
last operator identified before calling the function. */
+
static struct value *
stap_evaluate_probe_argument_2 (struct stap_evaluation_info *eval_info,
struct value *lhs, int prec);
+static struct value *
+stap_evaluate_conditionally (struct stap_evaluation_info *eval_info);
+
static void
stap_skip_whitespace_cond (char **s, int inside_paren)
{
@@ -625,6 +641,106 @@ stap_get_opcode (char **s, enum exp_opcode *op)
return ret;
}
+static void
+stap_opcode_to_ax (struct stap_evaluation_info *eval_info,
+ enum exp_opcode opcode)
+{
+ struct agent_expr *expr = eval_info->aexpr;
+
+ switch (opcode)
+ {
+ case BINOP_MUL:
+ ax_simple (expr, aop_mul);
+ break;
+
+ case BINOP_DIV:
+ /* FIXME: Should we sign-extend the operands? */
+ ax_simple (expr, aop_div_signed);
+ break;
+
+ case BINOP_REM:
+ ax_simple (expr, aop_rem_unsigned);
+ break;
+
+ case BINOP_LESS:
+ /* FIXME: Should we sign-extend the operands? */
+ ax_simple (expr, aop_less_signed);
+ break;
+
+ case BINOP_LEQ:
+ /* A <= B is !(B < A) */
+ ax_simple (expr, aop_swap);
+ ax_simple (expr, aop_less_signed);
+ ax_simple (expr, aop_log_not);
+ break;
+
+ case BINOP_GTR:
+ /* A > B is B < A */
+ ax_simple (expr, aop_swap);
+ ax_simple (expr, aop_less_signed);
+ break;
+
+ case BINOP_GEQ:
+ /* A >= B is !(A < B) */
+ ax_simple (expr, aop_less_signed);
+ ax_simple (expr, aop_log_not);
+ break;
+
+ case BINOP_NOTEQUAL:
+ ax_simple (expr, aop_equal);
+ ax_simple (expr, aop_log_not);
+ break;
+
+ case BINOP_LSH:
+ ax_simple (expr, aop_lsh);
+ break;
+
+ case BINOP_RSH:
+ ax_simple (expr, aop_rsh_unsigned);
+ break;
+
+ case BINOP_BITWISE_IOR:
+ ax_simple (expr, aop_bit_or);
+ break;
+
+ case BINOP_LOGICAL_OR:
+ /* FIXME: ????? */
+// ax_simple (expr, aop_
+ break;
+
+ case BINOP_BITWISE_AND:
+ ax_simple (expr, aop_bit_and);
+ break;
+
+ case BINOP_LOGICAL_AND:
+ /* FIXME: ???? */
+ break;
+
+ case BINOP_BITWISE_XOR:
+ ax_simple (expr, aop_bit_xor);
+ break;
+
+ case UNOP_LOGICAL_NOT:
+ ax_simple (expr, aop_log_not);
+ break;
+
+ case BINOP_ADD:
+ ax_simple (expr, aop_add);
+ break;
+
+ case BINOP_SUB:
+ ax_simple (expr, aop_sub);
+ break;
+
+ case BINOP_EQUAL:
+ ax_simple (expr, aop_equal);
+ break;
+
+ default:
+ error (_("Invalid operator."));
+ }
+}
+
/* Returns 1 if *S is an operator, zero otherwise. */
static int
@@ -727,11 +843,15 @@ stap_fetch_reg_value (struct stap_evaluation_info *eval_info,
error (_("Invalid register name `%s' on expression `%s'."),
regname, eval_info->saved_expr);
- ret = value_of_register (regnum, frame);
+ if (eval_info->compiling_p)
+ ax_reg (eval_info->aexpr, regnum);
+ else
+ ret = value_of_register (regnum, frame);
if (indirect_p)
{
struct type *t = NULL;
+ enum agent_op aop;
/* If the user has specified that the register must be indirected,
we should know what's the correct type to cast it before making
@@ -742,28 +862,43 @@ stap_fetch_reg_value (struct stap_evaluation_info *eval_info,
switch (bitness)
{
case STAP_ARG_BITNESS_UNDEFINED:
- t = lookup_pointer_type
- (builtin_type (gdbarch)->builtin_unsigned_long);
+ if (eval_info->compiling_p)
+ aop = aop_ref32;
+ else
+ t = lookup_pointer_type
+ (builtin_type (gdbarch)->builtin_unsigned_long);
break;
case STAP_ARG_BITNESS_32BIT_SIGNED:
- t = lookup_pointer_type
- (builtin_type (gdbarch)->builtin_int32);
+ if (eval_info->compiling_p)
+ aop = aop_ref32;
+ else
+ t = lookup_pointer_type
+ (builtin_type (gdbarch)->builtin_int32);
break;
case STAP_ARG_BITNESS_32BIT_UNSIGNED:
- t = lookup_pointer_type
- (builtin_type (gdbarch)->builtin_uint32);
+ if (eval_info->compiling_p)
+ aop = aop_ref32;
+ else
+ t = lookup_pointer_type
+ (builtin_type (gdbarch)->builtin_uint32);
break;
case STAP_ARG_BITNESS_64BIT_SIGNED:
- t = lookup_pointer_type
- (builtin_type (gdbarch)->builtin_int64);
+ if (eval_info->compiling_p)
+ aop = aop_ref64;
+ else
+ t = lookup_pointer_type
+ (builtin_type (gdbarch)->builtin_int64);
break;
case STAP_ARG_BITNESS_64BIT_UNSIGNED:
- t = lookup_pointer_type
- (builtin_type (gdbarch)->builtin_uint64);
+ if (eval_info->compiling_p)
+ aop = aop_ref64;
+ else
+ t = lookup_pointer_type
+ (builtin_type (gdbarch)->builtin_uint64);
break;
default:
@@ -773,17 +908,31 @@ stap_fetch_reg_value (struct stap_evaluation_info *eval_info,
}
if (displacement)
- ret = value_ptradd (ret, value_as_long (displacement));
+ {
+ if (eval_info->compiling_p)
+ {
+ ax_const_l (eval_info->aexpr, value_as_long (displacement));
+ /* FIXME: Is this correct? */
+ ax_simple (eval_info->aexpr, aop_add);
+ }
+ else
+ ret = value_ptradd (ret, value_as_long (displacement));
+ }
- ret = value_cast (t, ret);
- ret = value_ind (ret);
+ if (eval_info->compiling_p)
+ ax_simple (eval_info->aexpr, aop);
+ else
+ {
+ ret = value_cast (t, ret);
+ ret = value_ind (ret);
+ }
}
/* Updating the expression buffer pointer, because we have made
some modifications to it before. */
eval_info->exp_buf = s;
- return ret;
+ return eval_info->compiling_p ? (struct value *) 1 : ret;
}
/* This function tries to evaluate a single operand of the expression.
@@ -800,7 +949,7 @@ stap_evaluate_single_operand (struct stap_evaluation_info *eval_info)
struct gdbarch *gdbarch = eval_info->gdbarch;
struct frame_info *frame = eval_info->frame;
enum stap_arg_bitness bitness = eval_info->bitness;
- struct value *res = NULL;
+ struct value *res;
switch (*eval_info->exp_buf)
{
@@ -836,14 +985,27 @@ stap_evaluate_single_operand (struct stap_evaluation_info *eval_info)
to evaluate the right side of the expression (i.e., the
parenthesis), and then apply the specified operation
(either `-' or `~') to it. */
- tmp_res = stap_evaluate_probe_argument_2 (eval_info,
- /*lhs=*/NULL,
- /*prec=*/0);
+ tmp_res = stap_evaluate_conditionally (eval_info);
if (c == '-')
- res = value_neg (tmp_res);
+ {
+ if (eval_info->compiling_p)
+ {
+ /* We have to add `-1' to the stack, and multiply
+ the two values. */
+ ax_const_l (eval_info->aexpr, -1);
+ ax_simple (eval_info->aexpr, aop_mul);
+ }
+ else
+ res = value_neg (tmp_res);
+ }
else
- res = value_complement (tmp_res);
+ {
+ if (eval_info->compiling_p)
+ ax_simple (eval_info->aexpr, aop_bit_not);
+ else
+ res = value_complement (tmp_res);
+ }
}
else if (isdigit (*eval_info->exp_buf))
{
@@ -884,16 +1046,30 @@ stap_evaluate_single_operand (struct stap_evaluation_info *eval_info)
number = strtol (eval_info->exp_buf,
&eval_info->exp_buf, 0);
- res
- = value_from_longest (builtin_type (gdbarch)->builtin_int,
- number);
+ if (!eval_info->compiling_p)
+ res
+ = value_from_longest (builtin_type (gdbarch)->builtin_int,
+ number);
+
+ if (eval_info->compiling_p)
+ ax_const_l (eval_info->aexpr, number);
eval_info->exp_buf = skip_spaces (eval_info->exp_buf);
if (c == '-')
- res = value_neg (res);
+ {
+ if (eval_info->compiling_p)
+ ax_simple (eval_info->aexpr, aop_log_not);
+ else
+ res = value_neg (res);
+ }
else
- res = value_complement (res);
+ {
+ if (eval_info->compiling_p)
+ ax_simple (eval_info->aexpr, aop_bit_not);
+ else
+ res = value_complement (res);
+ }
}
else
error (_("Invalid operand to unary operator `%c' on "
@@ -932,8 +1108,11 @@ stap_evaluate_single_operand (struct stap_evaluation_info *eval_info)
number = strtol (eval_info->exp_buf, &eval_info->exp_buf, 0);
- res = value_from_longest (builtin_type (gdbarch)->builtin_int,
- number);
+ if (eval_info->compiling_p)
+ ax_const_l (eval_info->aexpr, number);
+ else
+ res = value_from_longest (builtin_type (gdbarch)->builtin_int,
+ number);
eval_info->exp_buf = skip_spaces (eval_info->exp_buf);
}
@@ -953,7 +1132,7 @@ stap_evaluate_single_operand (struct stap_evaluation_info *eval_info)
}
}
- return res;
+ return eval_info->compiling_p ? (struct value *) 1 : res;
}
/* This function is responsible for checking the necessary type of evaluation
@@ -1006,6 +1185,7 @@ stap_evaluate_probe_argument_2 (struct stap_evaluation_info *eval_info,
struct value *lhs, int prec)
{
struct value *rhs = NULL;
+ int compiling_p = eval_info->compiling_p;
/* This is an operator-precedence parser and evaluator.
@@ -1086,7 +1266,10 @@ stap_evaluate_probe_argument_2 (struct stap_evaluation_info *eval_info,
/* Now, "join" both left and right sides into one left-side, using
the specified operator. */
- lhs = value_binop (lhs, rhs, opcode);
+ if (compiling_p)
+ stap_opcode_to_ax (eval_info, opcode);
+ else
+ lhs = value_binop (lhs, rhs, opcode);
}
return lhs;
@@ -1103,7 +1286,6 @@ stap_evaluate_probe_argument_1 (struct objfile *objfile,
int n)
{
struct stap_evaluation_info eval_info;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
char *s = (char *) probe->parsed_args->arg[n].arg_str;
struct value *res, *vs[4];
#if TEST /*TESTING*/
@@ -1120,6 +1302,9 @@ stap_evaluate_probe_argument_1 (struct objfile *objfile,
eval_info.gdbarch = get_objfile_arch (objfile);
eval_info.frame = frame;
eval_info.bitness = probe->parsed_args->arg[n].bitness;
+ /* We are not compiling to an agent expression. */
+ eval_info.compiling_p = 0;
+ eval_info.aexpr = NULL;
res = stap_evaluate_probe_argument_2 (&eval_info,
/*lhs=*/NULL, /*prec=*/0);
@@ -1158,6 +1343,47 @@ stap_evaluate_probe_argument (struct objfile *objfile,
return stap_evaluate_probe_argument_1 (objfile, probe, frame, n);
}
+static void
+stap_compile_to_ax_1 (struct objfile *objfile,
+ const struct stap_probe *probe,
+ struct agent_expr *expr,
+ struct axs_value *value,
+ int n)
+{
+ struct stap_evaluation_info eval_info;
+ char *s = (char *) probe->parsed_args->arg[n].arg_str;
+
+ /* Filling necessary information for evaluation function. */
+ eval_info.saved_expr = s;
+ eval_info.exp_buf = s;
+ eval_info.gdbarch = expr->gdbarch;
+ eval_info.frame = NULL;
+ eval_info.bitness = probe->parsed_args->arg[n].bitness;
+ /* We are compiling to an agent expression. */
+ eval_info.compiling_p = 1;
+ eval_info.aexpr = expr;
+
+ stap_evaluate_probe_argument_2 (&eval_info,
+ /*lhs=*/NULL, /*prec=*/0);
+}
+
+void
+stap_compile_to_ax (struct objfile *objfile,
+ const struct stap_probe *probe,
+ struct agent_expr *expr,
+ struct axs_value *value,
+ int n)
+{
+ if (!probe->parsed_args)
+ stap_parse_probe_arguments ((struct stap_probe *) probe);
+
+ if (!probe->parsed_args->arg
+ || n >= probe->parsed_args->n_args)
+ return;
+
+ stap_compile_to_ax_1 (objfile, probe, expr, value, n);
+}
+
/* See documentation in stap-probe.h. */
struct value *
diff --git a/gdb/stap-probe.h b/gdb/stap-probe.h
index f6e67c2..3a7941f 100644
--- a/gdb/stap-probe.h
+++ b/gdb/stap-probe.h
@@ -21,6 +21,7 @@
#define STAP_PROBE_H 1
struct stap_args_info;
+struct axs_value;
struct stap_probe
{
@@ -70,25 +71,39 @@ extern const struct stap_probe *find_probe_by_pc (CORE_ADDR pc,
/* Given PROBE, this function will parse its arguments and fill the
`struct stap_args_info' with proper information about them. */
+
extern void stap_parse_probe_arguments (struct stap_probe *probe);
/* Given PROBE, returns the number of arguments present in that probe's
hooks/post-receive
--
Repository for Project Archer.
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2011-03-18 7:30 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-03-18 7:30 [SCM] archer-sergiodj-stap: Implementing the compilation for agent expressions, and fixing a bug sergiodj
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).