-/* GDB-specific functions for operating on agent expressions
- Copyright 1998, 2000 Free Software Foundation, Inc.
+/* GDB-specific functions for operating on agent expressions.
+
+ Copyright 1998, 1999, 2000, 2001, 2003 Free Software Foundation,
+ Inc.
This file is part of GDB.
#include "target.h"
#include "ax.h"
#include "ax-gdb.h"
+#include "gdb_string.h"
+#include "block.h"
+#include "regcache.h"
/* To make sense of this file, you should read doc/agentexpr.texi.
Then look at the types and enums in ax-gdb.h. For the code itself,
static void gen_expr (union exp_element **pc,
struct agent_expr *ax, struct axs_value *value);
-static void print_axs_value (struct ui_file *f, struct axs_value * value);
static void agent_command (char *exp, int from_tty);
\f
{
/* Do we need to sign-extend this? */
if (!TYPE_UNSIGNED (type))
- ax_ext (ax, type->length * TARGET_CHAR_BIT);
+ ax_ext (ax, TYPE_LENGTH (type) * TARGET_CHAR_BIT);
}
static void
gen_extend (struct agent_expr *ax, struct type *type)
{
- int bits = type->length * TARGET_CHAR_BIT;
+ int bits = TYPE_LENGTH (type) * TARGET_CHAR_BIT;
/* I just had to. */
((TYPE_UNSIGNED (type) ? ax_zero_ext : ax_ext) (ax, bits));
}
ax_trace_quick (ax, TYPE_LENGTH (type));
}
- switch (type->code)
+ switch (TYPE_CODE (type))
{
case TYPE_CODE_PTR:
case TYPE_CODE_ENUM:
case TYPE_CODE_CHAR:
/* It's a scalar value, so we know how to dereference it. How
many bytes long is it? */
- switch (type->length)
+ switch (TYPE_LENGTH (type))
{
case 8 / TARGET_CHAR_BIT:
ax_simple (ax, aop_ref8);
implementing something we should be (this code's fault).
In any case, it's a bug the user shouldn't see. */
default:
- internal_error ("ax-gdb.c (gen_fetch): strange size");
+ internal_error (__FILE__, __LINE__,
+ "gen_fetch: strange size");
}
gen_sign_extend (ax, type);
pointer (other code's fault), or we're not implementing
something we should be (this code's fault). In any case,
it's a bug the user shouldn't see. */
- internal_error ("ax-gdb.c (gen_fetch): bad type code");
+ internal_error (__FILE__, __LINE__,
+ "gen_fetch: bad type code");
}
}
static void
gen_frame_args_address (struct agent_expr *ax)
{
- long frame_reg, frame_offset;
+ int frame_reg;
+ LONGEST frame_offset;
TARGET_VIRTUAL_FRAME_POINTER (ax->scope, &frame_reg, &frame_offset);
ax_reg (ax, frame_reg);
static void
gen_frame_locals_address (struct agent_expr *ax)
{
- long frame_reg, frame_offset;
+ int frame_reg;
+ LONGEST frame_offset;
TARGET_VIRTUAL_FRAME_POINTER (ax->scope, &frame_reg, &frame_offset);
ax_reg (ax, frame_reg);
break;
case LOC_CONST_BYTES:
- internal_error ("ax-gdb.c (gen_var_ref): LOC_CONST_BYTES symbols are not supported");
+ internal_error (__FILE__, __LINE__,
+ "gen_var_ref: LOC_CONST_BYTES symbols are not supported");
/* Variable at a fixed location in memory. Easy. */
case LOC_STATIC:
case LOC_TYPEDEF:
error ("Cannot compute value of typedef `%s'.",
- SYMBOL_SOURCE_NAME (var));
+ SYMBOL_PRINT_NAME (var));
break;
case LOC_BLOCK:
case LOC_UNRESOLVED:
{
struct minimal_symbol *msym
- = lookup_minimal_symbol (SYMBOL_NAME (var), NULL, NULL);
+ = lookup_minimal_symbol (DEPRECATED_SYMBOL_NAME (var), NULL, NULL);
if (!msym)
- error ("Couldn't resolve symbol `%s'.", SYMBOL_SOURCE_NAME (var));
+ error ("Couldn't resolve symbol `%s'.", SYMBOL_PRINT_NAME (var));
/* Push the address of the variable. */
ax_const_l (ax, SYMBOL_VALUE_ADDRESS (msym));
}
break;
+ case LOC_COMPUTED:
+ case LOC_COMPUTED_ARG:
+ /* FIXME: cagney/2004-01-26: It should be possible to
+ unconditionally call the SYMBOL_OPS method when available.
+ Unfortunately DWARF 2 stores the frame-base (instead of the
+ function) location in a function's symbol. Oops! For the
+ moment enable this when/where applicable. */
+ SYMBOL_OPS (var)->tracepoint_var_ref (var, ax, value);
+ break;
+
case LOC_OPTIMIZED_OUT:
error ("The variable `%s' has been optimized out.",
- SYMBOL_SOURCE_NAME (var));
+ SYMBOL_PRINT_NAME (var));
break;
default:
error ("Cannot find value of botched symbol `%s'.",
- SYMBOL_SOURCE_NAME (var));
+ SYMBOL_PRINT_NAME (var));
break;
}
}
the stack. Should we tweak the type? */
/* Some types require special handling. */
- switch (value->type->code)
+ switch (TYPE_CODE (value->type))
{
/* Functions get converted to a pointer to the function. */
case TYPE_CODE_FUNC:
/* Dereference typedefs. */
type = check_typedef (type);
- switch (type->code)
+ switch (TYPE_CODE (type))
{
case TYPE_CODE_PTR:
/* It's implementation-defined, and I'll bet this is what GCC
{
struct type *element = TYPE_TARGET_TYPE (type);
- if (element->length != 1)
+ if (TYPE_LENGTH (element) != 1)
{
- ax_const_l (ax, element->length);
+ ax_const_l (ax, TYPE_LENGTH (element));
ax_simple (ax, op);
}
}
struct axs_value *value1, struct axs_value *value2, char *name)
{
/* Is it INT+PTR? */
- if (value1->type->code == TYPE_CODE_INT
- && value2->type->code == TYPE_CODE_PTR)
+ if (TYPE_CODE (value1->type) == TYPE_CODE_INT
+ && TYPE_CODE (value2->type) == TYPE_CODE_PTR)
{
/* Swap the values and proceed normally. */
ax_simple (ax, aop_swap);
}
/* Is it PTR+INT? */
- else if (value1->type->code == TYPE_CODE_PTR
- && value2->type->code == TYPE_CODE_INT)
+ else if (TYPE_CODE (value1->type) == TYPE_CODE_PTR
+ && TYPE_CODE (value2->type) == TYPE_CODE_INT)
{
gen_scale (ax, aop_mul, value1->type);
ax_simple (ax, aop_add);
/* Must be number + number; the usual binary conversions will have
brought them both to the same width. */
- else if (value1->type->code == TYPE_CODE_INT
- && value2->type->code == TYPE_CODE_INT)
+ else if (TYPE_CODE (value1->type) == TYPE_CODE_INT
+ && TYPE_CODE (value2->type) == TYPE_CODE_INT)
{
ax_simple (ax, aop_add);
gen_extend (ax, value1->type); /* Catch overflow. */
gen_sub (struct agent_expr *ax, struct axs_value *value,
struct axs_value *value1, struct axs_value *value2)
{
- if (value1->type->code == TYPE_CODE_PTR)
+ if (TYPE_CODE (value1->type) == TYPE_CODE_PTR)
{
/* Is it PTR - INT? */
- if (value2->type->code == TYPE_CODE_INT)
+ if (TYPE_CODE (value2->type) == TYPE_CODE_INT)
{
gen_scale (ax, aop_mul, value1->type);
ax_simple (ax, aop_sub);
/* Is it PTR - PTR? Strictly speaking, the types ought to
match, but this is what the normal GDB expression evaluator
tests for. */
- else if (value2->type->code == TYPE_CODE_PTR
+ else if (TYPE_CODE (value2->type) == TYPE_CODE_PTR
&& (TYPE_LENGTH (TYPE_TARGET_TYPE (value1->type))
== TYPE_LENGTH (TYPE_TARGET_TYPE (value2->type))))
{
}
/* Must be number + number. */
- else if (value1->type->code == TYPE_CODE_INT
- && value2->type->code == TYPE_CODE_INT)
+ else if (TYPE_CODE (value1->type) == TYPE_CODE_INT
+ && TYPE_CODE (value2->type) == TYPE_CODE_INT)
{
ax_simple (ax, aop_sub);
gen_extend (ax, value1->type); /* Catch overflow. */
enum agent_op op_unsigned, int may_carry, char *name)
{
/* We only handle INT op INT. */
- if ((value1->type->code != TYPE_CODE_INT)
- || (value2->type->code != TYPE_CODE_INT))
+ if ((TYPE_CODE (value1->type) != TYPE_CODE_INT)
+ || (TYPE_CODE (value2->type) != TYPE_CODE_INT))
error ("Illegal combination of types in %s.", name);
ax_simple (ax,
{
/* The caller should check the type, because several operators use
this, and we don't know what error message to generate. */
- if (value->type->code != TYPE_CODE_PTR)
- internal_error ("ax-gdb.c (gen_deref): expected a pointer");
+ if (TYPE_CODE (value->type) != TYPE_CODE_PTR)
+ internal_error (__FILE__, __LINE__,
+ "gen_deref: expected a pointer");
/* We've got an rvalue now, which is a pointer. We want to yield an
lvalue, whose address is exactly that pointer. So we don't
T" to "T", and mark the value as an lvalue in memory. Leave it
to the consumer to actually dereference it. */
value->type = check_typedef (TYPE_TARGET_TYPE (value->type));
- value->kind = ((value->type->code == TYPE_CODE_FUNC)
+ value->kind = ((TYPE_CODE (value->type) == TYPE_CODE_FUNC)
? axs_rvalue : axs_lvalue_memory);
}
/* Special case for taking the address of a function. The ANSI
standard describes this as a special case, too, so this
arrangement is not without motivation. */
- if (value->type->code == TYPE_CODE_FUNC)
+ if (TYPE_CODE (value->type) == TYPE_CODE_FUNC)
/* The value's already an rvalue on the stack, so we just need to
change the type. */
value->type = lookup_pointer_type (value->type);
/* Make sure this isn't C++. */
if (TYPE_N_BASECLASSES (type) != 0)
- internal_error ("ax-gdb.c (find_field): derived classes supported");
+ internal_error (__FILE__, __LINE__,
+ "find_field: derived classes supported");
for (i = 0; i < TYPE_NFIELDS (type); i++)
{
char *this_name = TYPE_FIELD_NAME (type, i);
- if (this_name && STREQ (name, this_name))
+ if (this_name && strcmp (name, this_name) == 0)
return i;
if (this_name[0] == '\0')
- internal_error ("ax-gdb.c (find_field): anonymous unions not supported");
+ internal_error (__FILE__, __LINE__,
+ "find_field: anonymous unions not supported");
}
error ("Couldn't find member named `%s' in struct/union `%s'",
- name, type->tag_name);
+ name, TYPE_TAG_NAME (type));
return 0;
}
/* Can we fetch the number of bits requested at all? */
if ((end - start) > ((1 << num_ops) * 8))
- internal_error ("ax-gdb.c (gen_bitfield_ref): bitfield too wide");
+ internal_error (__FILE__, __LINE__,
+ "gen_bitfield_ref: bitfield too wide");
/* Note that we know here that we only need to try each opcode once.
That may not be true on machines with weird byte sizes. */
the sign/zero extension will wipe them out.
- If we're in the interior of the word, then there is no garbage
on either end, because the ref operators zero-extend. */
- if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
gen_left_shift (ax, end - (offset + op_size));
else
gen_left_shift (ax, offset - start);
/* Follow pointers until we reach a non-pointer. These aren't the C
semantics, but they're what the normal GDB evaluator does, so we
should at least be consistent. */
- while (value->type->code == TYPE_CODE_PTR)
+ while (TYPE_CODE (value->type) == TYPE_CODE_PTR)
{
gen_usual_unary (ax, value);
gen_deref (ax, value);
if (!v)
error ("Right operand of `@' must be a constant, in agent expressions.");
- if (v->type->code != TYPE_CODE_INT)
+ if (TYPE_CODE (v->type) != TYPE_CODE_INT)
error ("Right operand of `@' must be an integer.");
length = value_as_long (v);
if (length <= 0)
default:
/* We should only list operators in the outer case statement
that we actually handle in the inner case statement. */
- internal_error ("ax-gdb.c (gen_expr): op case sets don't match");
+ internal_error (__FILE__, __LINE__,
+ "gen_expr: op case sets don't match");
}
break;
(*pc) += 3;
value->kind = axs_lvalue_register;
value->u.reg = reg;
- value->type = REGISTER_VIRTUAL_TYPE (reg);
+ value->type = register_type (current_gdbarch, reg);
}
break;
the given type, and dereference it. */
if (value->kind != axs_rvalue)
/* This would be weird. */
- internal_error ("ax-gdb.c (gen_expr): OP_MEMVAL operand isn't an rvalue???");
+ internal_error (__FILE__, __LINE__,
+ "gen_expr: OP_MEMVAL operand isn't an rvalue???");
value->type = type;
value->kind = axs_lvalue_memory;
}
else
/* If this `if' chain doesn't handle it, then the case list
shouldn't mention it, and we shouldn't be here. */
- internal_error ("ax-gdb.c (gen_expr): unhandled struct case");
+ internal_error (__FILE__, __LINE__,
+ "gen_expr: unhandled struct case");
}
break;
discard_cleanups (old_chain);
return ax;
}
-\f
-
-
-/* The "agent" command, for testing: compile and disassemble an expression. */
-
-static void
-print_axs_value (struct ui_file *f, struct axs_value *value)
-{
- switch (value->kind)
- {
- case axs_rvalue:
- fputs_filtered ("rvalue", f);
- break;
-
- case axs_lvalue_memory:
- fputs_filtered ("memory lvalue", f);
- break;
-
- case axs_lvalue_register:
- fprintf_filtered (f, "register %d lvalue", value->u.reg);
- break;
- }
-
- fputs_filtered (" : ", f);
- type_print (value->type, "", f, -1);
-}
-
static void
agent_command (char *exp, int from_tty)
expr = parse_expression (exp);
old_chain = make_cleanup (free_current_contents, &expr);
- agent = gen_trace_for_expr (fi->pc, expr);
+ agent = gen_trace_for_expr (get_frame_pc (fi), expr);
make_cleanup_free_agent_expr (agent);
ax_print (gdb_stdout, agent);