delete
};
+static void free_actions PARAMS((struct tracepoint *));
+
/* This function implements enable, disable and delete. */
static void
tracepoint_operation (t, from_tty, opcode)
enum tracepoint_opcode opcode;
{
struct tracepoint *t2;
- struct action_line *action, *next;
switch (opcode) {
case enable:
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;
}
/* 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 *,
STEPPING = 2,
};
-static enum actionline_type validate_actionline PARAMS((char *,
+static enum actionline_type validate_actionline PARAMS((char **,
struct tracepoint *));
/* worker function */
else
line = gdb_readline (0);
- linetype = validate_actionline (line, t);
+ linetype = validate_actionline (&line, t);
if (linetype == BADLINE)
continue; /* already warned -- collect another line */
/* worker function */
static enum actionline_type
validate_actionline (line, t)
- char *line;
+ char **line;
struct tracepoint *t;
{
struct cmd_list_element *c;
value_ptr temp, temp2;
char *p;
- for (p = line; isspace (*p); )
+ for (p = *line; isspace (*p); )
p++;
/* symbol lookup etc. */
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)
return END;
else
{
- warning ("'%s' is not a supported tracepoint action.", line);
+ warning ("'%s' is not a supported tracepoint action.", *line);
return BADLINE;
}
}
for (line = t->actions; line; line = next)
{
next = line->next;
+ if (line->action)
+ free (line->action);
free (line);
}
t->actions = NULL;
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? */
{
*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);
memranges->listsize);
}
- if (type != 0) /* better collect the base register! */
+ if (type != -1) /* better collect the base register! */
add_register (memranges, type);
}
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:
struct action_line *action;
bfd_signed_vma offset;
long i;
+ value_ptr tempval;
struct collection_list *collect;
struct cmd_list_element *cmd;
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;
else
len = 4;
- add_memrange (collect, 0, addr, len);
+ add_memrange (collect, -1, addr, len);
break;
#endif
}