* tracepoint.h (decode_agent_options): Add 'trace_string'
authorTom Tromey <tromey@redhat.com>
Thu, 21 Mar 2013 16:09:27 +0000 (16:09 +0000)
committerTom Tromey <tromey@redhat.com>
Thu, 21 Mar 2013 16:09:27 +0000 (16:09 +0000)
argument.
* tracepoint.c (decode_agent_options): Add 'trace_string'
argument.
(validate_actionline): Update.
(collect_symbol): Add 'trace_string' argument.
(struct add_local_symbols_data) <trace_string>: New field.
(do_collect_symbol): Update.
(add_local_symbols): Add 'trace_string' argument.
(encode_actions_1): Update.
(trace_dump_actions): Update.
* dwarf2loc.c (access_memory): Update.
* ax.h (struct agent_expr) <tracing, trace_string>: New fields.
* ax-general.c (new_agent_expr): Update.
* ax-gdb.h (gen_trace_for_expr, gen_trace_for_var)
(gen_trace_for_return_address): Add argument.
(trace_kludge, trace_string_kludge): Remove.
* ax-gdb.c (trace_kludge, trace_string_kludge): Remove.
(gen_traced_pop, gen_fetch, gen_bitfield_ref, gen_expr): Update.
(gen_trace_for_var): Add 'trace_string' argument.
(gen_trace_for_expr, gen_trace_for_return_address): Likewise.
(gen_printf, agent_eval_command_one): Update.

gdb/ChangeLog
gdb/ax-gdb.c
gdb/ax-gdb.h
gdb/ax-general.c
gdb/ax.h
gdb/dwarf2loc.c
gdb/tracepoint.c
gdb/tracepoint.h

index 7aab4effec8b89d806f98aee679e4eb12b9fc175..6aac6d79eacdb6e6333d29f14bed93588dfa470e 100644 (file)
@@ -1,3 +1,28 @@
+2013-03-11  Tom Tromey  <tromey@redhat.com>
+
+       * tracepoint.h (decode_agent_options): Add 'trace_string'
+       argument.
+       * tracepoint.c (decode_agent_options): Add 'trace_string'
+       argument.
+       (validate_actionline): Update.
+       (collect_symbol): Add 'trace_string' argument.
+       (struct add_local_symbols_data) <trace_string>: New field.
+       (do_collect_symbol): Update.
+       (add_local_symbols): Add 'trace_string' argument.
+       (encode_actions_1): Update.
+       (trace_dump_actions): Update.
+       * dwarf2loc.c (access_memory): Update.
+       * ax.h (struct agent_expr) <tracing, trace_string>: New fields.
+       * ax-general.c (new_agent_expr): Update.
+       * ax-gdb.h (gen_trace_for_expr, gen_trace_for_var)
+       (gen_trace_for_return_address): Add argument.
+       (trace_kludge, trace_string_kludge): Remove.
+       * ax-gdb.c (trace_kludge, trace_string_kludge): Remove.
+       (gen_traced_pop, gen_fetch, gen_bitfield_ref, gen_expr): Update.
+       (gen_trace_for_var): Add 'trace_string' argument.
+       (gen_trace_for_expr, gen_trace_for_return_address): Likewise.
+       (gen_printf, agent_eval_command_one): Update.
+
 2013-03-21  Tom Tromey  <tromey@redhat.com>
 
        PR exp/15109:
index 25179ad91db4621c4eda7be47d226cb497b40b2e..4196655e61d8a0409c9b69c0689930398cb0bed2 100644 (file)
@@ -312,36 +312,6 @@ maybe_const_expr (union exp_element **pc)
    sizes), and this is simpler.)  */
 \f
 
-/* Generating bytecode from GDB expressions: the `trace' kludge  */
-
-/* The compiler in this file is a general-purpose mechanism for
-   translating GDB expressions into bytecode.  One ought to be able to
-   find a million and one uses for it.
-
-   However, at the moment it is HOPELESSLY BRAIN-DAMAGED for the sake
-   of expediency.  Let he who is without sin cast the first stone.
-
-   For the data tracing facility, we need to insert `trace' bytecodes
-   before each data fetch; this records all the memory that the
-   expression touches in the course of evaluation, so that memory will
-   be available when the user later tries to evaluate the expression
-   in GDB.
-
-   This should be done (I think) in a post-processing pass, that walks
-   an arbitrary agent expression and inserts `trace' operations at the
-   appropriate points.  But it's much faster to just hack them
-   directly into the code.  And since we're in a crunch, that's what
-   I've done.
-
-   Setting the flag trace_kludge to non-zero enables the code that
-   emits the trace bytecodes at the appropriate points.  */
-int trace_kludge;
-
-/* Inspired by trace_kludge, this indicates that pointers to chars
-   should get an added tracenz bytecode to record nonzero bytes, up to
-   a length that is the value of trace_string_kludge.  */
-int trace_string_kludge;
-
 /* Scan for all static fields in the given class, including any base
    classes, and generate tracing bytecodes for each.  */
 
@@ -401,19 +371,19 @@ gen_traced_pop (struct gdbarch *gdbarch,
                struct agent_expr *ax, struct axs_value *value)
 {
   int string_trace = 0;
-  if (trace_string_kludge
+  if (ax->trace_string
       && TYPE_CODE (value->type) == TYPE_CODE_PTR
       && c_textual_element_type (check_typedef (TYPE_TARGET_TYPE (value->type)),
                                 's'))
     string_trace = 1;
 
-  if (trace_kludge)
+  if (ax->tracing)
     switch (value->kind)
       {
       case axs_rvalue:
        if (string_trace)
          {
-           ax_const_l (ax, trace_string_kludge);
+           ax_const_l (ax, ax->trace_string);
            ax_simple (ax, aop_tracenz);
          }
        else
@@ -441,7 +411,7 @@ gen_traced_pop (struct gdbarch *gdbarch,
          if (string_trace)
            {
              ax_simple (ax, aop_ref32);
-             ax_const_l (ax, trace_string_kludge);
+             ax_const_l (ax, ax->trace_string);
              ax_simple (ax, aop_tracenz);
            }
        }
@@ -459,7 +429,7 @@ gen_traced_pop (struct gdbarch *gdbarch,
        if (string_trace)
          {
            ax_reg (ax, value->u.reg);
-           ax_const_l (ax, trace_string_kludge);
+           ax_const_l (ax, ax->trace_string);
            ax_simple (ax, aop_tracenz);
          }
        break;
@@ -469,7 +439,7 @@ gen_traced_pop (struct gdbarch *gdbarch,
     ax_simple (ax, aop_pop);
 
   /* To trace C++ classes with static fields stored elsewhere.  */
-  if (trace_kludge
+  if (ax->tracing
       && (TYPE_CODE (value->type) == TYPE_CODE_STRUCT
          || TYPE_CODE (value->type) == TYPE_CODE_UNION))
     gen_trace_static_fields (gdbarch, ax, value->type);
@@ -509,7 +479,7 @@ gen_extend (struct agent_expr *ax, struct type *type)
 static void
 gen_fetch (struct agent_expr *ax, struct type *type)
 {
-  if (trace_kludge)
+  if (ax->tracing)
     {
       /* Record the area of memory we're about to fetch.  */
       ax_trace_quick (ax, TYPE_LENGTH (type));
@@ -1361,7 +1331,7 @@ gen_bitfield_ref (struct expression *exp, struct agent_expr *ax,
          /* Add the offset.  */
          gen_offset (ax, offset / TARGET_CHAR_BIT);
 
-         if (trace_kludge)
+         if (ax->tracing)
            {
              /* Record the area of memory we're about to fetch.  */
              ax_trace_quick (ax, op_size / TARGET_CHAR_BIT);
@@ -1930,7 +1900,7 @@ gen_expr (struct expression *exp, union exp_element **pc,
          if (tsv)
            {
              ax_tsv (ax, aop_setv, tsv->number);
-             if (trace_kludge)
+             if (ax->tracing)
                ax_tsv (ax, aop_tracev, tsv->number);
            }
          else
@@ -1957,7 +1927,7 @@ gen_expr (struct expression *exp, union exp_element **pc,
            {
              /* The tsv will be the left half of the binary operation.  */
              ax_tsv (ax, aop_getv, tsv->number);
-             if (trace_kludge)
+             if (ax->tracing)
                ax_tsv (ax, aop_tracev, tsv->number);
              /* Trace state variables are always 64-bit integers.  */
              value1.kind = axs_rvalue;
@@ -1966,7 +1936,7 @@ gen_expr (struct expression *exp, union exp_element **pc,
              gen_expr_binop_rest (exp, op2, pc, ax, value, &value1, &value2);
              /* We have a result of the binary op, set the tsv.  */
              ax_tsv (ax, aop_setv, tsv->number);
-             if (trace_kludge)
+             if (ax->tracing)
                ax_tsv (ax, aop_tracev, tsv->number);
            }
          else
@@ -2047,7 +2017,7 @@ gen_expr (struct expression *exp, union exp_element **pc,
        if (tsv)
          {
            ax_tsv (ax, aop_getv, tsv->number);
-           if (trace_kludge)
+           if (ax->tracing)
              ax_tsv (ax, aop_tracev, tsv->number);
            /* Trace state variables are always 64-bit integers.  */
            value->kind = axs_rvalue;
@@ -2424,7 +2394,7 @@ gen_expr_binop_rest (struct expression *exp,
 
 struct agent_expr *
 gen_trace_for_var (CORE_ADDR scope, struct gdbarch *gdbarch,
-                  struct symbol *var)
+                  struct symbol *var, int trace_string)
 {
   struct cleanup *old_chain = 0;
   struct agent_expr *ax = new_agent_expr (gdbarch, scope);
@@ -2432,7 +2402,8 @@ gen_trace_for_var (CORE_ADDR scope, struct gdbarch *gdbarch,
 
   old_chain = make_cleanup_free_agent_expr (ax);
 
-  trace_kludge = 1;
+  ax->tracing = 1;
+  ax->trace_string = trace_string;
   gen_var_ref (gdbarch, ax, &value, var);
 
   /* If there is no actual variable to trace, flag it by returning
@@ -2464,7 +2435,8 @@ gen_trace_for_var (CORE_ADDR scope, struct gdbarch *gdbarch,
    caller can then use the ax_reqs function to discover which
    registers it relies upon.  */
 struct agent_expr *
-gen_trace_for_expr (CORE_ADDR scope, struct expression *expr)
+gen_trace_for_expr (CORE_ADDR scope, struct expression *expr,
+                   int trace_string)
 {
   struct cleanup *old_chain = 0;
   struct agent_expr *ax = new_agent_expr (expr->gdbarch, scope);
@@ -2474,7 +2446,8 @@ gen_trace_for_expr (CORE_ADDR scope, struct expression *expr)
   old_chain = make_cleanup_free_agent_expr (ax);
 
   pc = expr->elts;
-  trace_kludge = 1;
+  ax->tracing = 1;
+  ax->trace_string = trace_string;
   value.optimized_out = 0;
   gen_expr (expr, &pc, ax, &value);
 
@@ -2509,7 +2482,7 @@ gen_eval_for_expr (CORE_ADDR scope, struct expression *expr)
   old_chain = make_cleanup_free_agent_expr (ax);
 
   pc = expr->elts;
-  trace_kludge = 0;
+  ax->tracing = 0;
   value.optimized_out = 0;
   gen_expr (expr, &pc, ax, &value);
 
@@ -2526,7 +2499,8 @@ gen_eval_for_expr (CORE_ADDR scope, struct expression *expr)
 }
 
 struct agent_expr *
-gen_trace_for_return_address (CORE_ADDR scope, struct gdbarch *gdbarch)
+gen_trace_for_return_address (CORE_ADDR scope, struct gdbarch *gdbarch,
+                             int trace_string)
 {
   struct cleanup *old_chain = 0;
   struct agent_expr *ax = new_agent_expr (gdbarch, scope);
@@ -2534,7 +2508,8 @@ gen_trace_for_return_address (CORE_ADDR scope, struct gdbarch *gdbarch)
 
   old_chain = make_cleanup_free_agent_expr (ax);
 
-  trace_kludge = 1;
+  ax->tracing = 1;
+  ax->trace_string = trace_string;
 
   gdbarch_gen_return_address (gdbarch, ax, &value, scope);
 
@@ -2570,13 +2545,14 @@ gen_printf (CORE_ADDR scope, struct gdbarch *gdbarch,
 
   old_chain = make_cleanup_free_agent_expr (ax);
 
+  /* We're computing values, not doing side effects.  */
+  ax->tracing = 0;
+
   /* Evaluate and push the args on the stack in reverse order,
      for simplicity of collecting them on the target side.  */
   for (tem = nargs - 1; tem >= 0; --tem)
     {
       pc = exprs[tem]->elts;
-      /* We're computing values, not doing side effects.  */
-      trace_kludge = 0;
       value.optimized_out = 0;
       gen_expr (exprs[tem], &pc, ax, &value);
       require_rvalue (ax, &value);
@@ -2609,18 +2585,19 @@ agent_eval_command_one (const char *exp, int eval, CORE_ADDR pc)
   struct expression *expr;
   struct agent_expr *agent;
   const char *arg;
+  int trace_string = 0;
 
   if (!eval)
     {
-      trace_string_kludge = 0;
       if (*exp == '/')
-        exp = decode_agent_options (exp);
+        exp = decode_agent_options (exp, &trace_string);
     }
 
   arg = exp;
   if (!eval && strcmp (arg, "$_ret") == 0)
     {
-      agent = gen_trace_for_return_address (pc, get_current_arch ());
+      agent = gen_trace_for_return_address (pc, get_current_arch (),
+                                           trace_string);
       old_chain = make_cleanup_free_agent_expr (agent);
     }
   else
@@ -2628,9 +2605,12 @@ agent_eval_command_one (const char *exp, int eval, CORE_ADDR pc)
       expr = parse_exp_1 (&arg, pc, block_for_pc (pc), 0);
       old_chain = make_cleanup (free_current_contents, &expr);
       if (eval)
-       agent = gen_eval_for_expr (pc, expr);
+       {
+         gdb_assert (trace_string == 0);
+         agent = gen_eval_for_expr (pc, expr);
+       }
       else
-       agent = gen_trace_for_expr (pc, expr);
+       agent = gen_trace_for_expr (pc, expr, trace_string);
       make_cleanup_free_agent_expr (agent);
     }
 
index 04772b77ff77f589dc798a67e4e1fde8e194eec0..65e703e137c1d03b1f1e618484af03689df309dc 100644 (file)
@@ -100,13 +100,15 @@ struct axs_value
    record the value of all memory touched by the expression, and leave
    no values on the stack.  The caller can then use the ax_reqs
    function to discover which registers the expression uses.  */
-extern struct agent_expr *gen_trace_for_expr (CORE_ADDR, struct expression *);
+extern struct agent_expr *gen_trace_for_expr (CORE_ADDR, struct expression *,
+                                             int);
 
 extern struct agent_expr *gen_trace_for_var (CORE_ADDR, struct gdbarch *,
-                                            struct symbol *);
+                                            struct symbol *, int);
 
 extern struct agent_expr *gen_trace_for_return_address (CORE_ADDR,
-                                                       struct gdbarch *);
+                                                       struct gdbarch *,
+                                                       int);
 
 extern struct agent_expr *gen_eval_for_expr (CORE_ADDR, struct expression *);
 
@@ -121,7 +123,4 @@ extern struct agent_expr *gen_printf (CORE_ADDR, struct gdbarch *,
                                      struct format_piece *,
                                      int, struct expression **);
 
-extern int trace_kludge;
-extern int trace_string_kludge;
-
 #endif /* AX_GDB_H */
index 8bd4df6acfa0d1b19a84af83b023e712a739ba1b..78d7f7e5731ff17645e47c651558bfbc55f10e24 100644 (file)
@@ -58,6 +58,9 @@ new_agent_expr (struct gdbarch *gdbarch, CORE_ADDR scope)
   x->reg_mask = xmalloc (x->reg_mask_len * sizeof (x->reg_mask[0]));
   memset (x->reg_mask, 0, x->reg_mask_len * sizeof (x->reg_mask[0]));
 
+  x->tracing = 0;
+  x->trace_string = 0;
+
   return x;
 }
 
index 32887efeeb4b073253e6b0eba2e7ac4b5ebb131b..3bb2d5bea5945732a1b23889e52b2f0d48c248ed 100644 (file)
--- a/gdb/ax.h
+++ b/gdb/ax.h
@@ -143,6 +143,23 @@ struct agent_expr
     */
     int reg_mask_len;
     unsigned char *reg_mask;
+
+    /* For the data tracing facility, we need to insert `trace' bytecodes
+       before each data fetch; this records all the memory that the
+       expression touches in the course of evaluation, so that memory will
+       be available when the user later tries to evaluate the expression
+       in GDB.
+
+       Setting the flag 'tracing' to non-zero enables the code that
+       emits the trace bytecodes at the appropriate points.  */
+
+    unsigned int tracing : 1;
+
+    /* This indicates that pointers to chars should get an added
+       tracenz bytecode to record nonzero bytes, up to a length that
+       is the value of trace_string.  */
+
+    int trace_string;
   };
 
 /* Pointer to an agent_expr structure.  */
index 700d1944b42100f84f212531db8f66af39114f51..18699e0d2ce6e363c71877cb394e30a9d76cd5f3 100644 (file)
@@ -2568,7 +2568,7 @@ access_memory (struct gdbarch *arch, struct agent_expr *expr, ULONGEST nbits)
 
   gdb_assert (nbytes > 0 && nbytes <= sizeof (LONGEST));
 
-  if (trace_kludge)
+  if (expr->tracing)
     ax_trace_quick (expr, nbytes);
 
   if (nbits <= 8)
index 66533f72c4326e256d3c1704814f4b6aeabedfef..9a2425b5215273341ad66695cdb10fa69786c25d 100644 (file)
@@ -612,10 +612,12 @@ teval_pseudocommand (char *args, int from_tty)
 /* Parse any collection options, such as /s for strings.  */
 
 const char *
-decode_agent_options (const char *exp)
+decode_agent_options (const char *exp, int *trace_string)
 {
   struct value_print_options opts;
 
+  *trace_string = 0;
+
   if (*exp != '/')
     return exp;
 
@@ -631,10 +633,10 @@ decode_agent_options (const char *exp)
          /* Allow an optional decimal number giving an explicit maximum
             string length, defaulting it to the "print elements" value;
             so "collect/s80 mystr" gets at most 80 bytes of string.  */
-         trace_string_kludge = opts.print_max;
+         *trace_string = opts.print_max;
          exp++;
          if (*exp >= '0' && *exp <= '9')
-           trace_string_kludge = atoi (exp);
+           *trace_string = atoi (exp);
          while (*exp >= '0' && *exp <= '9')
            exp++;
        }
@@ -731,9 +733,10 @@ validate_actionline (const char *line, struct breakpoint *b)
 
   if (cmd_cfunc_eq (c, collect_pseudocommand))
     {
-      trace_string_kludge = 0;
+      int trace_string = 0;
+
       if (*p == '/')
-       p = decode_agent_options (p);
+       p = decode_agent_options (p, &trace_string);
 
       do
        {                       /* Repeat over a comma-separated list.  */
@@ -782,7 +785,7 @@ validate_actionline (const char *line, struct breakpoint *b)
              /* We have something to collect, make sure that the expr to
                 bytecode translator can handle it and that it's not too
                 long.  */
-             aexpr = gen_trace_for_expr (loc->address, exp);
+             aexpr = gen_trace_for_expr (loc->address, exp, trace_string);
              make_cleanup_free_agent_expr (aexpr);
 
              if (aexpr->len > MAX_AGENT_EXPR_LEN)
@@ -989,7 +992,8 @@ collect_symbol (struct collection_list *collect,
                struct symbol *sym,
                struct gdbarch *gdbarch,
                long frame_regno, long frame_offset,
-               CORE_ADDR scope)
+               CORE_ADDR scope,
+               int trace_string)
 {
   unsigned long len;
   unsigned int reg;
@@ -1100,7 +1104,7 @@ collect_symbol (struct collection_list *collect,
       struct agent_expr *aexpr;
       struct cleanup *old_chain1 = NULL;
 
-      aexpr = gen_trace_for_var (scope, gdbarch, sym);
+      aexpr = gen_trace_for_var (scope, gdbarch, sym, trace_string);
 
       /* It can happen that the symbol is recorded as a computed
         location, but it's been optimized away and doesn't actually
@@ -1153,6 +1157,7 @@ struct add_local_symbols_data
   long frame_regno;
   long frame_offset;
   int count;
+  int trace_string;
 };
 
 /* The callback for the locals and args iterators.  */
@@ -1165,7 +1170,7 @@ do_collect_symbol (const char *print_name,
   struct add_local_symbols_data *p = cb_data;
 
   collect_symbol (p->collect, sym, p->gdbarch, p->frame_regno,
-                 p->frame_offset, p->pc);
+                 p->frame_offset, p->pc, p->trace_string);
   p->count++;
 }
 
@@ -1173,7 +1178,8 @@ do_collect_symbol (const char *print_name,
 static void
 add_local_symbols (struct collection_list *collect,
                   struct gdbarch *gdbarch, CORE_ADDR pc,
-                  long frame_regno, long frame_offset, int type)
+                  long frame_regno, long frame_offset, int type,
+                  int trace_string)
 {
   struct block *block;
   struct add_local_symbols_data cb_data;
@@ -1184,6 +1190,7 @@ add_local_symbols (struct collection_list *collect,
   cb_data.frame_regno = frame_regno;
   cb_data.frame_offset = frame_offset;
   cb_data.count = 0;
+  cb_data.trace_string = trace_string;
 
   if (type == 'L')
     {
@@ -1391,9 +1398,10 @@ encode_actions_1 (struct command_line *action,
 
       if (cmd_cfunc_eq (cmd, collect_pseudocommand))
        {
-         trace_string_kludge = 0;
+         int trace_string = 0;
+
          if (*action_exp == '/')
-           action_exp = decode_agent_options (action_exp);
+           action_exp = decode_agent_options (action_exp, &trace_string);
 
          do
            {                   /* Repeat over a comma-separated list.  */
@@ -1413,7 +1421,8 @@ encode_actions_1 (struct command_line *action,
                                     tloc->address,
                                     frame_reg,
                                     frame_offset,
-                                    'A');
+                                    'A',
+                                    trace_string);
                  action_exp = strchr (action_exp, ',');        /* more? */
                }
              else if (0 == strncasecmp ("$loc", action_exp, 4))
@@ -1423,7 +1432,8 @@ encode_actions_1 (struct command_line *action,
                                     tloc->address,
                                     frame_reg,
                                     frame_offset,
-                                    'L');
+                                    'L',
+                                    trace_string);
                  action_exp = strchr (action_exp, ',');        /* more? */
                }
              else if (0 == strncasecmp ("$_ret", action_exp, 5))
@@ -1431,7 +1441,8 @@ encode_actions_1 (struct command_line *action,
                  struct cleanup *old_chain1 = NULL;
 
                  aexpr = gen_trace_for_return_address (tloc->address,
-                                                       tloc->gdbarch);
+                                                       tloc->gdbarch,
+                                                       trace_string);
 
                  old_chain1 = make_cleanup_free_agent_expr (aexpr);
 
@@ -1512,11 +1523,13 @@ encode_actions_1 (struct command_line *action,
                                      tloc->gdbarch,
                                      frame_reg,
                                      frame_offset,
-                                     tloc->address);
+                                     tloc->address,
+                                     trace_string);
                      break;
 
                    default:    /* Full-fledged expression.  */
-                     aexpr = gen_trace_for_expr (tloc->address, exp);
+                     aexpr = gen_trace_for_expr (tloc->address, exp,
+                                                 trace_string);
 
                      old_chain1 = make_cleanup_free_agent_expr (aexpr);
 
@@ -2846,9 +2859,10 @@ trace_dump_actions (struct command_line *action,
              char *cmd = NULL;
              struct cleanup *old_chain
                = make_cleanup (free_current_contents, &cmd);
+             int trace_string = 0;
 
              if (*action_exp == '/')
-               action_exp = decode_agent_options (action_exp);
+               action_exp = decode_agent_options (action_exp, &trace_string);
 
              do
                {               /* Repeat over a comma-separated list.  */
index 2a809c7ee104993dff82d4d67a476866a5de7f03..c7eef7b0e7b683fb8cc54b840edc22f1252c44fc 100644 (file)
@@ -342,7 +342,7 @@ struct cleanup *make_cleanup_restore_traceframe_number (void);
 
 void free_actions (struct breakpoint *);
 
-extern const char *decode_agent_options (const char *exp);
+extern const char *decode_agent_options (const char *exp, int *trace_string);
 
 extern void encode_actions (struct breakpoint *t, struct bp_location *tloc,
                            char ***tdp_actions, char ***stepping_actions);