mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-01-07 04:21:13 +00:00
2010-03-15 Stan Shebs <stan@codesourcery.com>
* ax-gdb.c: Include cp-support.h. (find_field): Remove. (gen_primitive_field): New function. (gen_struct_ref_recursive): New function. (gen_struct_ref): Rewrite to call gen_struct_ref_recursive instead of find_field. (gen_static_field): New function. (gen_struct_elt_for_reference): New. (gen_namespace_elt): New. (gen_maybe_namespace_elt): New. (gen_aggregate_elt_ref): New. (gen_expr): Add OP_SCOPE, display opcode name in error message.
This commit is contained in:
parent
f5f4f512c3
commit
b6e7192fae
@ -1,3 +1,18 @@
|
||||
2010-03-15 Stan Shebs <stan@codesourcery.com>
|
||||
|
||||
* ax-gdb.c: Include cp-support.h.
|
||||
(find_field): Remove.
|
||||
(gen_primitive_field): New function.
|
||||
(gen_struct_ref_recursive): New function.
|
||||
(gen_struct_ref): Rewrite to call gen_struct_ref_recursive instead
|
||||
of find_field.
|
||||
(gen_static_field): New function.
|
||||
(gen_struct_elt_for_reference): New.
|
||||
(gen_namespace_elt): New.
|
||||
(gen_maybe_namespace_elt): New.
|
||||
(gen_aggregate_elt_ref): New.
|
||||
(gen_expr): Add OP_SCOPE, display opcode name in error message.
|
||||
|
||||
2010-03-15 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* dwarf2read.c (die_needs_namespace): Also return 0 for
|
||||
|
307
gdb/ax-gdb.c
307
gdb/ax-gdb.c
@ -39,6 +39,7 @@
|
||||
#include "dictionary.h"
|
||||
#include "breakpoint.h"
|
||||
#include "tracepoint.h"
|
||||
#include "cp-support.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,
|
||||
@ -127,14 +128,25 @@ static void gen_logical_not (struct agent_expr *ax, struct axs_value *value,
|
||||
static void gen_complement (struct agent_expr *ax, struct axs_value *value);
|
||||
static void gen_deref (struct agent_expr *, struct axs_value *);
|
||||
static void gen_address_of (struct agent_expr *, struct axs_value *);
|
||||
static int find_field (struct type *type, char *name);
|
||||
static void gen_bitfield_ref (struct expression *exp, struct agent_expr *ax,
|
||||
struct axs_value *value,
|
||||
struct type *type, int start, int end);
|
||||
static void gen_primitive_field (struct expression *exp,
|
||||
struct agent_expr *ax,
|
||||
struct axs_value *value,
|
||||
int offset, int fieldno, struct type *type);
|
||||
static int gen_struct_ref_recursive (struct expression *exp,
|
||||
struct agent_expr *ax,
|
||||
struct axs_value *value,
|
||||
char *field, int offset,
|
||||
struct type *type);
|
||||
static void gen_struct_ref (struct expression *exp, struct agent_expr *ax,
|
||||
struct axs_value *value,
|
||||
char *field,
|
||||
char *operator_name, char *operand_name);
|
||||
static void gen_static_field (struct expression *exp,
|
||||
struct agent_expr *ax, struct axs_value *value,
|
||||
struct type *type, int fieldno);
|
||||
static void gen_repeat (struct expression *exp, union exp_element **pc,
|
||||
struct agent_expr *ax, struct axs_value *value);
|
||||
static void gen_sizeof (struct expression *exp, union exp_element **pc,
|
||||
@ -1116,46 +1128,6 @@ gen_address_of (struct agent_expr *ax, struct axs_value *value)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* A lot of this stuff will have to change to support C++. But we're
|
||||
not going to deal with that at the moment. */
|
||||
|
||||
/* Find the field in the structure type TYPE named NAME, and return
|
||||
its index in TYPE's field array. */
|
||||
static int
|
||||
find_field (struct type *type, char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
CHECK_TYPEDEF (type);
|
||||
|
||||
/* Make sure this isn't C++. */
|
||||
if (TYPE_N_BASECLASSES (type) != 0)
|
||||
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)
|
||||
{
|
||||
if (strcmp (name, this_name) == 0)
|
||||
return i;
|
||||
|
||||
if (this_name[0] == '\0')
|
||||
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 (type));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Generate code to push the value of a bitfield of a structure whose
|
||||
address is on the top of the stack. START and END give the
|
||||
starting and one-past-ending *bit* numbers of the field within the
|
||||
@ -1316,6 +1288,90 @@ gen_bitfield_ref (struct expression *exp, struct agent_expr *ax,
|
||||
value->type = type;
|
||||
}
|
||||
|
||||
/* Generate bytecodes for field number FIELDNO of type TYPE. OFFSET
|
||||
is an accumulated offset (in bytes), will be nonzero for objects
|
||||
embedded in other objects, like C++ base classes. Behavior should
|
||||
generally follow value_primitive_field. */
|
||||
|
||||
static void
|
||||
gen_primitive_field (struct expression *exp,
|
||||
struct agent_expr *ax, struct axs_value *value,
|
||||
int offset, int fieldno, struct type *type)
|
||||
{
|
||||
/* Is this a bitfield? */
|
||||
if (TYPE_FIELD_PACKED (type, fieldno))
|
||||
gen_bitfield_ref (exp, ax, value, TYPE_FIELD_TYPE (type, fieldno),
|
||||
(offset * TARGET_CHAR_BIT
|
||||
+ TYPE_FIELD_BITPOS (type, fieldno)),
|
||||
(offset * TARGET_CHAR_BIT
|
||||
+ TYPE_FIELD_BITPOS (type, fieldno)
|
||||
+ TYPE_FIELD_BITSIZE (type, fieldno)));
|
||||
else
|
||||
{
|
||||
gen_offset (ax, offset
|
||||
+ TYPE_FIELD_BITPOS (type, fieldno) / TARGET_CHAR_BIT);
|
||||
value->kind = axs_lvalue_memory;
|
||||
value->type = TYPE_FIELD_TYPE (type, fieldno);
|
||||
}
|
||||
}
|
||||
|
||||
/* Search for the given field in either the given type or one of its
|
||||
base classes. Return 1 if found, 0 if not. */
|
||||
|
||||
static int
|
||||
gen_struct_ref_recursive (struct expression *exp, struct agent_expr *ax,
|
||||
struct axs_value *value,
|
||||
char *field, int offset, struct type *type)
|
||||
{
|
||||
int i, rslt;
|
||||
int nbases = TYPE_N_BASECLASSES (type);
|
||||
|
||||
CHECK_TYPEDEF (type);
|
||||
|
||||
for (i = TYPE_NFIELDS (type) - 1; i >= nbases; i--)
|
||||
{
|
||||
char *this_name = TYPE_FIELD_NAME (type, i);
|
||||
|
||||
if (this_name)
|
||||
{
|
||||
if (strcmp (field, this_name) == 0)
|
||||
{
|
||||
/* Note that bytecodes for the struct's base (aka
|
||||
"this") will have been generated already, which will
|
||||
be unnecessary but not harmful if the static field is
|
||||
being handled as a global. */
|
||||
if (field_is_static (&TYPE_FIELD (type, i)))
|
||||
{
|
||||
gen_static_field (exp, ax, value, type, i);
|
||||
return 1;
|
||||
}
|
||||
|
||||
gen_primitive_field (exp, ax, value, offset, i, type);
|
||||
return 1;
|
||||
}
|
||||
#if 0 /* is this right? */
|
||||
if (this_name[0] == '\0')
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("find_field: anonymous unions not supported"));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Now scan through base classes recursively. */
|
||||
for (i = 0; i < nbases; i++)
|
||||
{
|
||||
struct type *basetype = check_typedef (TYPE_BASECLASS (type, i));
|
||||
|
||||
rslt = gen_struct_ref_recursive (exp, ax, value, field,
|
||||
offset + TYPE_BASECLASS_BITPOS (type, i) / TARGET_CHAR_BIT,
|
||||
basetype);
|
||||
if (rslt)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Not found anywhere, flag so caller can complain. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Generate code to reference the member named FIELD of a structure or
|
||||
union. The top of the stack, as described by VALUE, should have
|
||||
@ -1328,7 +1384,7 @@ gen_struct_ref (struct expression *exp, struct agent_expr *ax,
|
||||
char *operator_name, char *operand_name)
|
||||
{
|
||||
struct type *type;
|
||||
int i;
|
||||
int found;
|
||||
|
||||
/* 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
|
||||
@ -1351,22 +1407,151 @@ gen_struct_ref (struct expression *exp, struct agent_expr *ax,
|
||||
if (value->kind != axs_lvalue_memory)
|
||||
error (_("Structure does not live in memory."));
|
||||
|
||||
i = find_field (type, field);
|
||||
/* Search through fields and base classes recursively. */
|
||||
found = gen_struct_ref_recursive (exp, ax, value, field, 0, type);
|
||||
|
||||
if (!found)
|
||||
error (_("Couldn't find member named `%s' in struct/union/class `%s'"),
|
||||
field, TYPE_TAG_NAME (type));
|
||||
}
|
||||
|
||||
/* Is this a bitfield? */
|
||||
if (TYPE_FIELD_PACKED (type, i))
|
||||
gen_bitfield_ref (exp, ax, value, TYPE_FIELD_TYPE (type, i),
|
||||
TYPE_FIELD_BITPOS (type, i),
|
||||
(TYPE_FIELD_BITPOS (type, i)
|
||||
+ TYPE_FIELD_BITSIZE (type, i)));
|
||||
static int
|
||||
gen_namespace_elt (struct expression *exp,
|
||||
struct agent_expr *ax, struct axs_value *value,
|
||||
const struct type *curtype, char *name);
|
||||
static int
|
||||
gen_maybe_namespace_elt (struct expression *exp,
|
||||
struct agent_expr *ax, struct axs_value *value,
|
||||
const struct type *curtype, char *name);
|
||||
|
||||
static void
|
||||
gen_static_field (struct expression *exp,
|
||||
struct agent_expr *ax, struct axs_value *value,
|
||||
struct type *type, int fieldno)
|
||||
{
|
||||
if (TYPE_FIELD_LOC_KIND (type, fieldno) == FIELD_LOC_KIND_PHYSADDR)
|
||||
{
|
||||
ax_const_l (ax, TYPE_FIELD_STATIC_PHYSADDR (type, fieldno));
|
||||
value->kind = axs_lvalue_memory;
|
||||
value->type = TYPE_FIELD_TYPE (type, fieldno);
|
||||
}
|
||||
else
|
||||
{
|
||||
gen_offset (ax, TYPE_FIELD_BITPOS (type, i) / TARGET_CHAR_BIT);
|
||||
value->kind = axs_lvalue_memory;
|
||||
value->type = TYPE_FIELD_TYPE (type, i);
|
||||
char *phys_name = TYPE_FIELD_STATIC_PHYSNAME (type, fieldno);
|
||||
struct symbol *sym = lookup_symbol (phys_name, 0, VAR_DOMAIN, 0);
|
||||
if (sym == NULL)
|
||||
error (_("symbol not found"));
|
||||
|
||||
gen_var_ref (exp->gdbarch, ax, value, sym);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
gen_struct_elt_for_reference (struct expression *exp,
|
||||
struct agent_expr *ax, struct axs_value *value,
|
||||
struct type *type, char *fieldname)
|
||||
{
|
||||
struct type *t = type;
|
||||
int i;
|
||||
struct value *v, *result;
|
||||
|
||||
if (TYPE_CODE (t) != TYPE_CODE_STRUCT
|
||||
&& TYPE_CODE (t) != TYPE_CODE_UNION)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("non-aggregate type to gen_struct_elt_for_reference"));
|
||||
|
||||
for (i = TYPE_NFIELDS (t) - 1; i >= TYPE_N_BASECLASSES (t); i--)
|
||||
{
|
||||
char *t_field_name = TYPE_FIELD_NAME (t, i);
|
||||
|
||||
if (t_field_name && strcmp (t_field_name, fieldname) == 0)
|
||||
{
|
||||
if (field_is_static (&TYPE_FIELD (t, i)))
|
||||
{
|
||||
gen_static_field (exp, ax, value, t, i);
|
||||
return 1;
|
||||
}
|
||||
if (TYPE_FIELD_PACKED (t, i))
|
||||
error (_("pointers to bitfield members not allowed"));
|
||||
|
||||
/* FIXME we need a way to do "want_address" equivalent */
|
||||
|
||||
error (_("Cannot reference non-static field \"%s\""), fieldname);
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME add other scoped-reference cases here */
|
||||
|
||||
/* Do a last-ditch lookup. */
|
||||
return gen_maybe_namespace_elt (exp, ax, value, type, fieldname);
|
||||
}
|
||||
|
||||
/* C++: Return the member NAME of the namespace given by the type
|
||||
CURTYPE. */
|
||||
|
||||
static int
|
||||
gen_namespace_elt (struct expression *exp,
|
||||
struct agent_expr *ax, struct axs_value *value,
|
||||
const struct type *curtype, char *name)
|
||||
{
|
||||
int found = gen_maybe_namespace_elt (exp, ax, value, curtype, name);
|
||||
|
||||
if (!found)
|
||||
error (_("No symbol \"%s\" in namespace \"%s\"."),
|
||||
name, TYPE_TAG_NAME (curtype));
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
/* A helper function used by value_namespace_elt and
|
||||
value_struct_elt_for_reference. It looks up NAME inside the
|
||||
context CURTYPE; this works if CURTYPE is a namespace or if CURTYPE
|
||||
is a class and NAME refers to a type in CURTYPE itself (as opposed
|
||||
to, say, some base class of CURTYPE). */
|
||||
|
||||
static int
|
||||
gen_maybe_namespace_elt (struct expression *exp,
|
||||
struct agent_expr *ax, struct axs_value *value,
|
||||
const struct type *curtype, char *name)
|
||||
{
|
||||
const char *namespace_name = TYPE_TAG_NAME (curtype);
|
||||
struct symbol *sym;
|
||||
|
||||
sym = cp_lookup_symbol_namespace (namespace_name, name,
|
||||
block_for_pc (ax->scope),
|
||||
VAR_DOMAIN, 0);
|
||||
|
||||
if (sym == NULL)
|
||||
return 0;
|
||||
|
||||
gen_var_ref (exp->gdbarch, ax, value, sym);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gen_aggregate_elt_ref (struct expression *exp,
|
||||
struct agent_expr *ax, struct axs_value *value,
|
||||
struct type *type, char *field,
|
||||
char *operator_name, char *operand_name)
|
||||
{
|
||||
switch (TYPE_CODE (type))
|
||||
{
|
||||
case TYPE_CODE_STRUCT:
|
||||
case TYPE_CODE_UNION:
|
||||
return gen_struct_elt_for_reference (exp, ax, value, type, field);
|
||||
break;
|
||||
case TYPE_CODE_NAMESPACE:
|
||||
return gen_namespace_elt (exp, ax, value, type, field);
|
||||
break;
|
||||
default:
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("non-aggregate type in gen_aggregate_elt_ref"));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Generate code for GDB's magical `repeat' operator.
|
||||
LVALUE @ INT creates an array INT elements long, and whose elements
|
||||
@ -1823,11 +2008,27 @@ gen_expr (struct expression *exp, union exp_element **pc,
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_SCOPE:
|
||||
{
|
||||
struct type *type = (*pc)[1].type;
|
||||
int length = longest_to_int ((*pc)[2].longconst);
|
||||
char *name = &(*pc)[3].string;
|
||||
int found;
|
||||
|
||||
found = gen_aggregate_elt_ref (exp, ax, value, type, name,
|
||||
"?", "??");
|
||||
if (!found)
|
||||
error (_("There is no field named %s"), name);
|
||||
(*pc) += 5 + BYTES_TO_EXP_ELEM (length + 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_TYPE:
|
||||
error (_("Attempt to use a type name as an expression."));
|
||||
|
||||
default:
|
||||
error (_("Unsupported operator in expression."));
|
||||
error (_("Unsupported operator %s (%d) in expression."),
|
||||
op_string (op), op);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user