]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/tracepoint.c
Copyright updates for 2007.
[thirdparty/binutils-gdb.git] / gdb / tracepoint.c
index b005c566e2a090c1da9081199a9ada4ae6ed5a80..3ad005f1cabf3bd713948f9b08f4cd0763479465 100644 (file)
@@ -1,7 +1,7 @@
 /* Tracing functionality for remote targets in custom GDB protocol
 
-   Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free
-   Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+   2007 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -17,8 +17,8 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 #include "defs.h"
 #include "symtab.h"
@@ -68,7 +68,6 @@
 extern void (*deprecated_readline_begin_hook) (char *, ...);
 extern char *(*deprecated_readline_hook) (char *);
 extern void (*deprecated_readline_end_hook) (void);
-extern void x_command (char *, int);
 extern int addressprint;       /* Print machine addresses? */
 
 /* GDB commands implemented in other modules:
@@ -150,7 +149,7 @@ static void trace_mention (struct tracepoint *);
 
 struct collection_list;
 static void add_aexpr (struct collection_list *, struct agent_expr *);
-static unsigned char *mem2hex (unsigned char *, unsigned char *, int);
+static char *mem2hex (gdb_byte *, char *, int);
 static void add_register (struct collection_list *collection,
                          unsigned int regno);
 static struct cleanup *make_cleanup_free_actions (struct tracepoint *t);
@@ -164,7 +163,8 @@ static int
 target_is_remote (void)
 {
   if (current_target.to_shortname &&
-      strcmp (current_target.to_shortname, "remote") == 0)
+      (strcmp (current_target.to_shortname, "remote") == 0
+       || strcmp (current_target.to_shortname, "extended-remote") == 0))
     return 1;
   else
     return 0;
@@ -193,13 +193,15 @@ trace_error (char *buf)
 
 /* Utility: wait for reply from stub, while accepting "O" packets.  */
 static char *
-remote_get_noisy_reply (char *buf,
-                       long sizeof_buf)
+remote_get_noisy_reply (char **buf_p,
+                       long *sizeof_buf)
 {
   do                           /* Loop on reply from remote stub.  */
     {
+      char *buf;
       QUIT;                    /* allow user to bail out with ^C */
-      getpkt (buf, sizeof_buf, 0);
+      getpkt (buf_p, sizeof_buf, 0);
+      buf = *buf_p;
       if (buf[0] == 0)
        error (_("Target does not support this command."));
       else if (buf[0] == 'E')
@@ -860,6 +862,9 @@ read_actions (struct tracepoint *t)
       else
        line = gdb_readline (0);
 
+      if (!line)
+       line = "end";
+      
       linetype = validate_actionline (&line, t);
       if (linetype == BADLINE)
        continue;               /* already warned -- collect another line */
@@ -1065,16 +1070,21 @@ make_cleanup_free_actions (struct tracepoint *t)
   return make_cleanup (do_free_actions_cleanup, t);
 }
 
+enum {
+  memrange_absolute = -1
+};
+
 struct memrange
 {
-  int type;            /* 0 for absolute memory range, else basereg number */
+  int type;            /* memrange_absolute for absolute memory range,
+                           else basereg number */
   bfd_signed_vma start;
   bfd_signed_vma end;
 };
 
 struct collection_list
   {
-    unsigned char regs_mask[8];        /* room for up to 256 regs */
+    unsigned char regs_mask[32];       /* room for up to 256 regs */
     long listsize;
     long next_memrange;
     struct memrange *list;
@@ -1099,7 +1109,7 @@ memrange_cmp (const void *va, const void *vb)
     return -1;
   if (a->type > b->type)
     return 1;
-  if (a->type == 0)
+  if (a->type == memrange_absolute)
     {
       if ((bfd_vma) a->start < (bfd_vma) b->start)
        return -1;
@@ -1171,7 +1181,7 @@ add_memrange (struct collection_list *memranges,
       printf_filtered (",%ld)\n", len);
     }
 
-  /* type: 0 == memory, n == basereg */
+  /* type: memrange_absolute == memory, other n == basereg */
   memranges->list[memranges->next_memrange].type = type;
   /* base: addr if memory, offset if reg relative.  */
   memranges->list[memranges->next_memrange].start = base;
@@ -1185,7 +1195,7 @@ add_memrange (struct collection_list *memranges,
                                  memranges->listsize);
     }
 
-  if (type != -1)              /* Better collect the base register!  */
+  if (type != memrange_absolute)               /* Better collect the base register!  */
     add_register (memranges, type);
 }
 
@@ -1222,7 +1232,7 @@ collect_symbol (struct collection_list *collect,
                           DEPRECATED_SYMBOL_NAME (sym), len, 
                           tmp /* address */);
        }
-      add_memrange (collect, -1, offset, len); /* 0 == memory */
+      add_memrange (collect, memrange_absolute, offset, len);
       break;
     case LOC_REGISTER:
     case LOC_REGPARM:
@@ -1433,13 +1443,21 @@ stringify_collection_list (struct collection_list *list, char *string)
          end = temp_buf;
        }
 
-      sprintf (end, "M%X,%s,%lX", 
-              list->list[i].type,
-              tmp2,
-              (long) (list->list[i].end - list->list[i].start));
+      {
+        bfd_signed_vma length = list->list[i].end - list->list[i].start;
+
+        /* The "%X" conversion specifier expects an unsigned argument,
+           so passing -1 (memrange_absolute) to it directly gives you
+           "FFFFFFFF" (or more, depending on sizeof (unsigned)).
+           Special-case it.  */
+        if (list->list[i].type == memrange_absolute)
+          sprintf (end, "M-1,%s,%lX", tmp2, (long) length);
+        else
+          sprintf (end, "M%X,%s,%lX", list->list[i].type, tmp2, (long) length);
+      }
 
       count += strlen (end);
-      end += count;
+      end = temp_buf + count;
     }
 
   for (i = 0; i < list->next_aexpr_elt; i++)
@@ -1594,7 +1612,7 @@ encode_actions (struct tracepoint *t, char ***tdp_actions,
                      tempval = evaluate_expression (exp);
                      addr = VALUE_ADDRESS (tempval) + value_offset (tempval);
                      len = TYPE_LENGTH (check_typedef (exp->elts[1].type));
-                     add_memrange (collect, -1, addr, len);
+                     add_memrange (collect, memrange_absolute, addr, len);
                      break;
 
                    case OP_VAR_VALUE:
@@ -1683,7 +1701,8 @@ add_aexpr (struct collection_list *collect, struct agent_expr *aexpr)
   collect->next_aexpr_elt++;
 }
 
-static char target_buf[2048];
+static char *target_buf;
+static long target_buf_size;
 
 /* Set "transparent" memory ranges
 
@@ -1725,7 +1744,7 @@ remote_set_transparent_ranges (void)
   if (anysecs)
     {
       putpkt (target_buf);
-      getpkt (target_buf, sizeof (target_buf), 0);
+      getpkt (&target_buf, &target_buf_size, 0);
     }
 }
 
@@ -1751,7 +1770,7 @@ trace_start_command (char *args, int from_tty)
   if (target_is_remote ())
     {
       putpkt ("QTinit");
-      remote_get_noisy_reply (target_buf, sizeof (target_buf));
+      remote_get_noisy_reply (&target_buf, &target_buf_size);
       if (strcmp (target_buf, "OK"))
        error (_("Target does not support this command."));
 
@@ -1768,7 +1787,7 @@ trace_start_command (char *args, int from_tty)
        if (t->actions)
          strcat (buf, "-");
        putpkt (buf);
-       remote_get_noisy_reply (target_buf, sizeof (target_buf));
+       remote_get_noisy_reply (&target_buf, &target_buf_size);
        if (strcmp (target_buf, "OK"))
          error (_("Target does not support tracepoints."));
 
@@ -1792,8 +1811,8 @@ trace_start_command (char *args, int from_tty)
                             ((tdp_actions[ndx + 1] || stepping_actions)
                              ? '-' : 0));
                    putpkt (buf);
-                   remote_get_noisy_reply (target_buf, 
-                                           sizeof (target_buf));
+                   remote_get_noisy_reply (&target_buf,
+                                           &target_buf_size);
                    if (strcmp (target_buf, "OK"))
                      error (_("Error on target while setting tracepoints."));
                  }
@@ -1809,8 +1828,8 @@ trace_start_command (char *args, int from_tty)
                             stepping_actions[ndx],
                             (stepping_actions[ndx + 1] ? "-" : ""));
                    putpkt (buf);
-                   remote_get_noisy_reply (target_buf, 
-                                           sizeof (target_buf));
+                   remote_get_noisy_reply (&target_buf,
+                                           &target_buf_size);
                    if (strcmp (target_buf, "OK"))
                      error (_("Error on target while setting tracepoints."));
                  }
@@ -1823,7 +1842,7 @@ trace_start_command (char *args, int from_tty)
       remote_set_transparent_ranges ();
       /* Now insert traps and begin collecting data.  */
       putpkt ("QTStart");
-      remote_get_noisy_reply (target_buf, sizeof (target_buf));
+      remote_get_noisy_reply (&target_buf, &target_buf_size);
       if (strcmp (target_buf, "OK"))
        error (_("Bogus reply from target: %s"), target_buf);
       set_traceframe_num (-1); /* All old traceframes invalidated.  */
@@ -1845,7 +1864,7 @@ trace_stop_command (char *args, int from_tty)
   if (target_is_remote ())
     {
       putpkt ("QTStop");
-      remote_get_noisy_reply (target_buf, sizeof (target_buf));
+      remote_get_noisy_reply (&target_buf, &target_buf_size);
       if (strcmp (target_buf, "OK"))
        error (_("Bogus reply from target: %s"), target_buf);
       trace_running_p = 0;
@@ -1865,7 +1884,7 @@ trace_status_command (char *args, int from_tty)
   if (target_is_remote ())
     {
       putpkt ("qTStatus");
-      remote_get_noisy_reply (target_buf, sizeof (target_buf));
+      remote_get_noisy_reply (&target_buf, &target_buf_size);
 
       if (target_buf[0] != 'T' ||
          (target_buf[1] != '0' && target_buf[1] != '1'))
@@ -1880,8 +1899,8 @@ trace_status_command (char *args, int from_tty)
 
 /* Worker function for the various flavors of the tfind command.  */
 static void
-finish_tfind_command (char *msg,
-                     long sizeof_msg,
+finish_tfind_command (char **msg,
+                     long *sizeof_msg,
                      int from_tty)
 {
   int target_frameno = -1, target_tracept = -1;
@@ -1892,7 +1911,7 @@ finish_tfind_command (char *msg,
   old_frame_addr = get_frame_base (get_current_frame ());
   old_func = find_pc_function (read_pc ());
 
-  putpkt (msg);
+  putpkt (*msg);
   reply = remote_get_noisy_reply (msg, sizeof_msg);
 
   while (reply && *reply)
@@ -2037,7 +2056,7 @@ trace_find_command (char *args, int from_tty)
        error (_("invalid input (%d is less than zero)"), frameno);
 
       sprintf (target_buf, "QTFrame:%x", frameno);
-      finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
+      finish_tfind_command (&target_buf, &target_buf_size, from_tty);
     }
   else
     error (_("Trace can only be run on remote targets."));
@@ -2080,7 +2099,7 @@ trace_find_pc_command (char *args, int from_tty)
 
       sprintf_vma (tmp, pc);
       sprintf (target_buf, "QTFrame:pc:%s", tmp);
-      finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
+      finish_tfind_command (&target_buf, &target_buf_size, from_tty);
     }
   else
     error (_("Trace can only be run on remote targets."));
@@ -2105,7 +2124,7 @@ trace_find_tracepoint_command (char *args, int from_tty)
        tdp = parse_and_eval_long (args);
 
       sprintf (target_buf, "QTFrame:tdp:%x", tdp);
-      finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
+      finish_tfind_command (&target_buf, &target_buf_size, from_tty);
     }
   else
     error (_("Trace can only be run on remote targets."));
@@ -2203,7 +2222,7 @@ trace_find_line_command (char *args, int from_tty)
       else
        sprintf (target_buf, "QTFrame:outside:%s:%s", 
                 startpc_str, endpc_str);
-      finish_tfind_command (target_buf, sizeof (target_buf), 
+      finish_tfind_command (&target_buf, &target_buf_size,
                            from_tty);
       do_cleanups (old_chain);
     }
@@ -2244,7 +2263,7 @@ trace_find_range_command (char *args, int from_tty)
       sprintf_vma (start_str, start);
       sprintf_vma (stop_str, stop);
       sprintf (target_buf, "QTFrame:range:%s:%s", start_str, stop_str);
-      finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
+      finish_tfind_command (&target_buf, &target_buf_size, from_tty);
     }
   else
     error (_("Trace can only be run on remote targets."));
@@ -2283,7 +2302,7 @@ trace_find_outside_command (char *args, int from_tty)
       sprintf_vma (start_str, start);
       sprintf_vma (stop_str, stop);
       sprintf (target_buf, "QTFrame:outside:%s:%s", start_str, stop_str);
-      finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
+      finish_tfind_command (&target_buf, &target_buf_size, from_tty);
     }
   else
     error (_("Trace can only be run on remote targets."));
@@ -2301,7 +2320,7 @@ tracepoint_save_command (char *args, int from_tty)
   char tmp[40];
 
   if (args == 0 || *args == 0)
-    error (_("Argument required (file name in which to save tracepoints"));
+    error (_("Argument required (file name in which to save tracepoints)"));
 
   if (tracepoint_chain == 0)
     {
@@ -2641,10 +2660,10 @@ trace_dump_command (char *args, int from_tty)
 
 static const char hexchars[] = "0123456789abcdef";
 
-static unsigned char *
-mem2hex (unsigned char *mem, unsigned char *buf, int count)
+static char *
+mem2hex (gdb_byte *mem, char *buf, int count)
 {
-  unsigned char ch;
+  gdb_byte ch;
 
   while (count-- > 0)
     {
@@ -2677,11 +2696,6 @@ _initialize_tracepoint (void)
   traceframe_number = -1;
   tracepoint_number = -1;
 
-  set_internalvar (lookup_internalvar ("tpnum"),
-                  value_from_longest (builtin_type_int, (LONGEST) 0));
-  set_internalvar (lookup_internalvar ("trace_frame"),
-                  value_from_longest (builtin_type_int, (LONGEST) - 1));
-
   if (tracepoint_list.list == NULL)
     {
       tracepoint_list.listsize = 128;
@@ -2710,30 +2724,30 @@ _initialize_tracepoint (void)
     }
 
   add_info ("scope", scope_info,
-           "List the variables local to a scope");
+           _("List the variables local to a scope"));
 
   add_cmd ("tracepoints", class_trace, NULL,
           _("Tracing of program execution without stopping the program."),
           &cmdlist);
 
-  add_info ("tracepoints", tracepoints_info,
-           "Status of tracepoints, or tracepoint number NUMBER.\n\
+  add_info ("tracepoints", tracepoints_info, _("\
+Status of tracepoints, or tracepoint number NUMBER.\n\
 Convenience variable \"$tpnum\" contains the number of the\n\
-last tracepoint set.");
+last tracepoint set."));
 
   add_info_alias ("tp", "tracepoints", 1);
 
-  c = add_com ("save-tracepoints", class_trace, tracepoint_save_command,
-              "Save current tracepoint definitions as a script.\n\
-Use the 'source' command in another debug session to restore them.");
+  c = add_com ("save-tracepoints", class_trace, tracepoint_save_command, _("\
+Save current tracepoint definitions as a script.\n\
+Use the 'source' command in another debug session to restore them."));
   set_cmd_completer (c, filename_completer);
 
   add_com ("tdump", class_trace, trace_dump_command,
-          "Print everything collected at the current tracepoint.");
+          _("Print everything collected at the current tracepoint."));
 
-  add_prefix_cmd ("tfind", class_trace, trace_find_command,
-                 "Select a trace frame;\n\
-No argument means forward by one frame; '-' means backward by one frame.",
+  add_prefix_cmd ("tfind", class_trace, trace_find_command, _("\
+Select a trace frame;\n\
+No argument means forward by one frame; '-' means backward by one frame."),
                  &tfindlist, "tfind ", 1, &cmdlist);
 
   add_cmd ("outside", class_trace, trace_find_outside_command, _("\
@@ -2777,53 +2791,53 @@ De-select any trace frame and resume 'live' debugging."),
           &tfindlist);
 
   add_com ("tstatus", class_trace, trace_status_command,
-          "Display the status of the current trace data collection.");
+          _("Display the status of the current trace data collection."));
 
   add_com ("tstop", class_trace, trace_stop_command,
-          "Stop trace data collection.");
+          _("Stop trace data collection."));
 
   add_com ("tstart", class_trace, trace_start_command,
-          "Start trace data collection.");
+          _("Start trace data collection."));
 
-  add_com ("passcount", class_trace, trace_pass_command,
-          "Set the passcount for a tracepoint.\n\
+  add_com ("passcount", class_trace, trace_pass_command, _("\
+Set the passcount for a tracepoint.\n\
 The trace will end when the tracepoint has been passed 'count' times.\n\
 Usage: passcount COUNT TPNUM, where TPNUM may also be \"all\";\n\
-if TPNUM is omitted, passcount refers to the last tracepoint defined.");
+if TPNUM is omitted, passcount refers to the last tracepoint defined."));
 
-  add_com ("end", class_trace, end_actions_pseudocommand,
-          "Ends a list of commands or actions.\n\
+  add_com ("end", class_trace, end_actions_pseudocommand, _("\
+Ends a list of commands or actions.\n\
 Several GDB commands allow you to enter a list of commands or actions.\n\
 Entering \"end\" on a line by itself is the normal way to terminate\n\
 such a list.\n\n\
-Note: the \"end\" command cannot be used at the gdb prompt.");
+Note: the \"end\" command cannot be used at the gdb prompt."));
 
-  add_com ("while-stepping", class_trace, while_stepping_pseudocommand,
-          "Specify single-stepping behavior at a tracepoint.\n\
+  add_com ("while-stepping", class_trace, while_stepping_pseudocommand, _("\
+Specify single-stepping behavior at a tracepoint.\n\
 Argument is number of instructions to trace in single-step mode\n\
 following the tracepoint.  This command is normally followed by\n\
 one or more \"collect\" commands, to specify what to collect\n\
 while single-stepping.\n\n\
-Note: this command can only be used in a tracepoint \"actions\" list.");
+Note: this command can only be used in a tracepoint \"actions\" list."));
 
   add_com_alias ("ws", "while-stepping", class_alias, 0);
   add_com_alias ("stepping", "while-stepping", class_alias, 0);
 
-  add_com ("collect", class_trace, collect_pseudocommand,
-          "Specify one or more data items to be collected at a tracepoint.\n\
+  add_com ("collect", class_trace, collect_pseudocommand, _("\
+Specify one or more data items to be collected at a tracepoint.\n\
 Accepts a comma-separated list of (one or more) expressions.  GDB will\n\
 collect all data (variables, registers) referenced by that expression.\n\
 Also accepts the following special arguments:\n\
     $regs   -- all registers.\n\
     $args   -- all function arguments.\n\
     $locals -- all variables local to the block/function scope.\n\
-Note: this command can only be used in a tracepoint \"actions\" list.");
+Note: this command can only be used in a tracepoint \"actions\" list."));
 
-  add_com ("actions", class_trace, trace_actions_command,
-          "Specify the actions to be taken at a tracepoint.\n\
+  add_com ("actions", class_trace, trace_actions_command, _("\
+Specify the actions to be taken at a tracepoint.\n\
 Tracepoint actions may include collecting of specified data, \n\
 single-stepping, or enabling/disabling other tracepoints, \n\
-depending on target's capabilities.");
+depending on target's capabilities."));
 
   add_cmd ("tracepoints", class_trace, delete_trace_command, _("\
 Delete specified tracepoints.\n\
@@ -2843,16 +2857,19 @@ Arguments are tracepoint numbers, separated by spaces.\n\
 No argument means enable all tracepoints."),
           &enablelist);
 
-  c = add_com ("trace", class_trace, trace_command,
-              "Set a tracepoint at a specified line or function or address.\n\
+  c = add_com ("trace", class_trace, trace_command, _("\
+Set a tracepoint at a specified line or function or address.\n\
 Argument may be a line number, function name, or '*' plus an address.\n\
 For a line number or function, trace at the start of its code.\n\
 If an address is specified, trace at that exact address.\n\n\
-Do \"help tracepoints\" for info on other tracepoint commands.");
+Do \"help tracepoints\" for info on other tracepoint commands."));
   set_cmd_completer (c, location_completer);
 
   add_com_alias ("tp", "trace", class_alias, 0);
   add_com_alias ("tr", "trace", class_alias, 1);
   add_com_alias ("tra", "trace", class_alias, 1);
   add_com_alias ("trac", "trace", class_alias, 1);
+
+  target_buf_size = 2048;
+  target_buf = xmalloc (target_buf_size);
 }