Thu Feb 5 11:57:06 1998 Michael Snyder (msnyder@cleaver.cygnus.com)
authorMichael Snyder <msnyder@vmware.com>
Thu, 5 Feb 1998 20:13:58 +0000 (20:13 +0000)
committerMichael Snyder <msnyder@vmware.com>
Thu, 5 Feb 1998 20:13:58 +0000 (20:13 +0000)
        * tracepoint.c (tracepoint_operation): call free_actions instead
        of free.  (free_actions): eliminate some memory leaks for actions.
        (validate_actionline): pass string arg by reference, so we can
        change the pointer.  Change all memrange collection arguments to
        canonical form (literal address and size), to enforce early
        evaluation.  Accept UNOP_MEMVAL (assembly variables) for
        trace collection.  (parse_and_eval_memrange): accept expressions
        for the address and size fields of a memrange (and evaluate
        them immediately).  (several places): use -1 instead of zero
        to distinguish an absolute memrange from a register-relative one.
        (encode_actions): add handling for UNOP_MEMVAL (assembly variable).

gdb/ChangeLog
gdb/tracepoint.c

index 733ec45ecf9f22a2dda4e4b4149c8fbbd0cf5992..b0d2714655ff2d30fdcb80fc8b45fa932e56b04d 100644 (file)
@@ -1,3 +1,17 @@
+Thu Feb  5 11:57:06 1998  Michael Snyder  (msnyder@cleaver.cygnus.com)
+
+       * tracepoint.c (tracepoint_operation): call free_actions instead
+       of free.  (free_actions): eliminate some memory leaks for actions.
+       (validate_actionline): pass string arg by reference, so we can 
+       change the pointer.  Change all memrange collection arguments to
+       canonical form (literal address and size), to enforce early
+       evaluation.  Accept UNOP_MEMVAL (assembly variables) for 
+       trace collection.  (parse_and_eval_memrange): accept expressions
+       for the address and size fields of a memrange (and evaluate
+       them immediately).  (several places): use -1 instead of zero
+       to distinguish an absolute memrange from a register-relative one.
+       (encode_actions): add handling for UNOP_MEMVAL (assembly variable).
+
 Wed Feb  4 17:40:21 1998  Jason Molenda  (crash@bugshack.cygnus.com)
 
         * Makefile.in (SFILES): add tracepoint.c.
index 11e83d9675838574978d8e3dd0e5d43aa74fb66f..936df3d91ab82850e89654b81f4496b8fcd7c57a 100644 (file)
@@ -517,6 +517,8 @@ enum tracepoint_opcode
   delete
 };
 
+static void  free_actions PARAMS((struct tracepoint *));
+
 /* This function implements enable, disable and delete. */
 static void
 tracepoint_operation (t, from_tty, opcode)
@@ -525,7 +527,6 @@ tracepoint_operation (t, from_tty, opcode)
      enum tracepoint_opcode opcode;
 {
   struct tracepoint *t2;
-  struct action_line *action, *next;
 
   switch (opcode) {
   case enable:
@@ -553,13 +554,9 @@ tracepoint_operation (t, from_tty, opcode)
       free (t->addr_string);
     if (t->source_file)
       free (t->source_file);
-    for (action = t->actions; action; action = next)
-      {
-       next = action->next;
-       if (action->action) 
-         free (action->action);
-       free (action);
-      }
+    if (t->actions)
+      free_actions (t);
+
     free (t);
     break;
   }
@@ -712,7 +709,6 @@ trace_pass_command (args, from_tty)
 
 /* Prototypes for action-parsing utility commands  */
 static void  read_actions PARAMS((struct tracepoint *));
-static void  free_actions PARAMS((struct tracepoint *));
 static char *parse_and_eval_memrange PARAMS ((char *,
                                              CORE_ADDR, 
                                              long *,
@@ -795,7 +791,7 @@ enum actionline_type
   STEPPING =  2,
 };
 
-static enum actionline_type validate_actionline PARAMS((char *, 
+static enum actionline_type validate_actionline PARAMS((char **
                                                        struct tracepoint *));
 
 /* worker function */
@@ -838,7 +834,7 @@ read_actions (t)
       else
        line = gdb_readline (0);
 
-      linetype = validate_actionline (line, t);
+      linetype = validate_actionline (&line, t);
       if (linetype == BADLINE)
        continue;       /* already warned -- collect another line */
 
@@ -879,7 +875,7 @@ read_actions (t)
 /* worker function */
 static enum actionline_type
 validate_actionline (line, t)
-     char *line;
+     char **line;
      struct tracepoint *t;
 {
   struct cmd_list_element *c;
@@ -887,7 +883,7 @@ validate_actionline (line, t)
   value_ptr temp, temp2;
   char *p;
 
-  for (p = line; isspace (*p); )
+  for (p = *line; isspace (*p); )
     p++;
 
   /* symbol lookup etc. */
@@ -921,14 +917,38 @@ validate_actionline (line, t)
              p = strchr (p, ',');
 
            else if (p[1] == '(')       /* literal memrange */
-             p = parse_and_eval_memrange (p, t->address, 
-                                           &typecode, &offset, &size);
+             {
+               char *temp, *newline;
+
+               newline = malloc (strlen (*line) + 32);
+               strcpy (newline, *line);
+               newline[p - *line] = '\0';
+               /* newline is now a copy of line, up to "p" (the memrange) */
+               temp = parse_and_eval_memrange (p, t->address, 
+                                               &typecode, &offset, &size) + 1;
+               /* now compose the memrange as a literal value */
+               if (typecode == -1)
+                 sprintf (newline + strlen (newline), 
+                          "$(0x%x, %d)",
+                          offset, size);
+               else
+                 sprintf (newline + strlen (newline), 
+                          "$($%s, 0x%x, %d)", 
+                          reg_names[typecode], offset, size);
+               /* now add the remainder of the old line to the new one */
+               p = newline + strlen (newline);
+               if (temp && *temp)
+                 strcat (newline, temp);
+               free (*line);
+               *line = newline;
+             }
          }
        else
          {
            exp   = parse_exp_1 (&p, block_for_pc (t->address), 1);
 
            if (exp->elts[0].opcode != OP_VAR_VALUE &&
+               exp->elts[0].opcode != UNOP_MEMVAL  &&
              /*exp->elts[0].opcode != OP_LONG      && */
              /*exp->elts[0].opcode != UNOP_CAST    && */
                exp->elts[0].opcode != OP_REGISTER)
@@ -979,7 +999,7 @@ validate_actionline (line, t)
     return END;
   else
     {
-      warning ("'%s' is not a supported tracepoint action.", line);
+      warning ("'%s' is not a supported tracepoint action.", *line);
       return BADLINE;
     }
 }
@@ -994,6 +1014,8 @@ free_actions (t)
   for (line = t->actions; line; line = next)
     {
       next = line->next;
+      if (line->action) 
+       free (line->action);
       free (line);
     }
   t->actions = NULL;
@@ -1022,11 +1044,12 @@ parse_and_eval_memrange (arg, addr, typecode, offset, size)
      long *typecode, *size;
      bfd_signed_vma *offset;
 {
-  char *start = arg;
+  char *start      = arg;
   struct expression *exp;
+  value_ptr          val;
 
   if (*arg++ != '$' || *arg++ != '(')
-    error ("Internal: bad argument to validate_memrange: %s", start);
+    error ("Internal: bad argument to parse_and_eval_memrange: %s", start);
 
   if (*arg == '$')     /* register for relative memrange? */
     {
@@ -1038,67 +1061,18 @@ parse_and_eval_memrange (arg, addr, typecode, offset, size)
       *typecode = exp->elts[1].longconst;
     }
   else
-    *typecode = 0;
+    *typecode = -1;    /* absolute memrange; */
 
-#if 0
-  /* While attractive, this fails for a number of reasons:
-     1) parse_and_eval_address does not deal with trailing commas,
-        close-parens etc.
-     2) There is no safeguard against the user trying to use
-        an out-of-scope variable in an address expression (for instance).
-     2.5) If you are going to allow semi-arbitrary expressions, you 
-          would need to explain which expressions are allowed, and 
-         which are not (which would provoke endless questions).
-     3) If you are going to allow semi-arbitrary expressions in the
-        offset and size fields, then the leading "$" of a register
-       name no longer disambiguates the typecode field.
-  */
-
-  *offset = parse_and_eval_address (arg);
-  if ((arg = strchr (arg, ',')) == NULL)
-    error ("missing comma for memrange: %s", start);
-  else
-    arg++;
-
-  *size = parse_and_eval_address (arg);
-  if ((arg = strchr (arg, ')')) == NULL)
-    error ("missing close-parenthesis for memrange: %s", start);
-  else
-    arg++;
-#else
-#if 0
-  /* This, on the other hand, doesn't work because "-1" is an 
-     expression, not an OP_LONG!  Fall back to using strtol for now. */
-
-  exp = parse_exp_1 (&arg, block_for_pc (addr), 1);
-  if (exp->elts[0].opcode != OP_LONG)
-    error ("Bad offset operand for memrange: %s", start);
-  *offset = exp->elts[2].longconst;
+  exp = parse_exp_1 (&arg, 0, 1);
+  *offset = value_as_pointer (evaluate_expression (exp));
 
+  /* now parse the size */
   if (*arg++ != ',')
     error ("missing comma for memrange: %s", start);
 
-  exp = parse_exp_1 (&arg, block_for_pc (addr), 1);
-  if (exp->elts[0].opcode != OP_LONG)
-    error ("Bad size operand for memrange: %s", start);
-  *size = exp->elts[2].longconst;
+  exp = parse_exp_1 (&arg, 0, 0);
+  *size = value_as_long (evaluate_expression (exp));
 
-  if (*size <= 0)
-    error ("invalid size in memrange: %s", start);
-
-  if (*arg++ != ')')
-    error ("missing close-parenthesis for memrange: %s", start);
-#else
-  *offset = strtol (arg, &arg, 0);
-  if (*arg++ != ',')
-    error ("missing comma for memrange: %s", start);
-  *size   = strtol (arg, &arg, 0);
-  if (*size <= 0)
-    error ("invalid size in memrange: %s", start);
-  if (*arg++ != ')')
-    error ("missing close-parenthesis for memrange: %s", start);
-#endif
-#endif
   if (info_verbose)
     printf_filtered ("Collecting memrange: (0x%x,0x%x,0x%x)\n", 
                     *typecode, *offset, *size);
@@ -1195,7 +1169,7 @@ add_memrange (memranges, type, base, len)
                                  memranges->listsize);
     }
 
-  if (type != 0)       /* better collect the base register! */
+  if (type != -1)      /* better collect the base register! */
     add_register (memranges, type);
 }
 
@@ -1225,7 +1199,7 @@ collect_symbol (collect, sym)
       printf_filtered ("LOC_STATIC %s: collect %d bytes "
                       "at 0x%08x\n",
                       SYMBOL_NAME (sym), len, offset);
-    add_memrange (collect, 0, offset, len);    /* 0 == memory */
+    add_memrange (collect, -1, offset, len);   /* 0 == memory */
     break;
   case LOC_REGISTER:
   case LOC_REGPARM:
@@ -1404,6 +1378,7 @@ encode_actions (t, tdp_actions, step_count, stepping_actions)
   struct action_line *action;
   bfd_signed_vma      offset;
   long                i;
+  value_ptr           tempval;
   struct collection_list  *collect;
   struct cmd_list_element *cmd;
 
@@ -1474,6 +1449,15 @@ encode_actions (t, tdp_actions, step_count, stepping_actions)
                    printf_filtered ("OP_REGISTER: ");
                  add_register (collect, i);
                  break;
+
+               case UNOP_MEMVAL:
+                 /* safe because we know it's a simple expression */
+                 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);
+                 break;
+
                case OP_VAR_VALUE:
                  collect_symbol (collect, exp->elts[2].symbol);
                  break;
@@ -1493,7 +1477,7 @@ encode_actions (t, tdp_actions, step_count, stepping_actions)
                  else 
                    len = 4;
 
-                 add_memrange (collect, 0, addr, len);
+                 add_memrange (collect, -1, addr, len);
                  break;
 #endif
                }