#include "defs.h"
#include "value.h"
#include "gdb_regex.h"
#include "gdb_string.h"
#include "gdbtypes.h"
#include "gdbcore.h"
#include "cp-abi.h"
struct cp_abi_ops hpacc_abi_ops;
static regex_t constructor_pattern;
static regex_t destructor_pattern;
static regex_t operator_pattern;
static enum dtor_kinds
hpacc_is_destructor_name (const char *name)
{
if (regexec (&destructor_pattern, name, 0, 0, 0) == 0)
return complete_object_dtor;
else
return 0;
}
static enum ctor_kinds
hpacc_is_constructor_name (const char *name)
{
if (regexec (&constructor_pattern, name, 0, 0, 0) == 0)
return complete_object_ctor;
else
return 0;
}
static int
hpacc_is_operator_name (const char *name)
{
return regexec (&operator_pattern, name, 0, 0, 0) == 0;
}
static int
hpacc_is_vtable_name (const char *name)
{
return strcmp (name,
"This will never match anything, please fill it in") == 0;
}
static struct value *
hpacc_virtual_fn_field (struct value **arg1p, struct fn_field * f, int j,
struct type * type, int offset)
{
struct value *arg1 = *arg1p;
struct type *type1 = check_typedef (VALUE_TYPE (arg1));
struct value *vp;
struct value *argp;
CORE_ADDR coreptr;
int class_index;
struct type *ftype = TYPE_FN_FIELD_TYPE (f, j);
argp = value_cast (type, *arg1p);
if (VALUE_ADDRESS (argp) == 0)
error ("Address of object is null; object may not have been created.");
coreptr = *(CORE_ADDR *) (VALUE_CONTENTS (argp));
if (!coreptr)
error
("Virtual table pointer is null for object; object may not have been created.");
if (1)
{
vp = value_at (builtin_type_int,
coreptr + 4 * (TYPE_FN_FIELD_VOFFSET (f, j) +
HP_ACC_VFUNC_START), NULL);
coreptr = *(CORE_ADDR *) (VALUE_CONTENTS (vp));
}
else
{
class_index = class_index_in_primary_list (type);
vp = value_at (builtin_type_int,
coreptr + 4 * (HP_ACC_VFUNC_START + class_index), NULL);
coreptr =
*(CORE_ADDR *) (VALUE_CONTENTS (vp) +
4 * TYPE_FN_FIELD_VOFFSET (f, j));
vp = value_at (builtin_type_int, coreptr, NULL);
coreptr = *(CORE_ADDR *) (VALUE_CONTENTS (vp));
}
if (!coreptr)
error ("Address of virtual function is null; error in virtual table?");
vp = allocate_value (ftype);
VALUE_TYPE (vp) = ftype;
VALUE_ADDRESS (vp) = coreptr;
return vp;
}
static struct type *
hpacc_value_rtti_type (struct value *v, int *full, int *top, int *using_enc)
{
struct type *known_type;
struct type *rtti_type;
CORE_ADDR coreptr;
struct value *vp;
int using_enclosing = 0;
long top_offset = 0;
char rtti_type_name[256];
if (full)
*full = 0;
if (top)
*top = -1;
if (using_enc)
*using_enc = 0;
known_type = VALUE_TYPE (v);
CHECK_TYPEDEF (known_type);
if (TYPE_CODE (known_type) != TYPE_CODE_CLASS)
return NULL;
if (!TYPE_HAS_VTABLE (known_type))
{
known_type = VALUE_ENCLOSING_TYPE (v);
CHECK_TYPEDEF (known_type);
if ((TYPE_CODE (known_type) != TYPE_CODE_CLASS) ||
!TYPE_HAS_VTABLE (known_type))
return NULL;
CHECK_TYPEDEF (known_type);
using_enclosing = 1;
}
if (using_enclosing && using_enc)
*using_enc = 1;
coreptr = *(CORE_ADDR *) ((VALUE_CONTENTS_ALL (v))
+ VALUE_OFFSET (v)
+ (using_enclosing
? 0
: VALUE_EMBEDDED_OFFSET (v)));
if (coreptr == 0)
return NULL;
vp = value_at (builtin_type_int,
coreptr + 4 * HP_ACC_TOP_OFFSET_OFFSET,
VALUE_BFD_SECTION (v));
top_offset = value_as_long (vp);
if (top)
*top = top_offset;
vp = value_at (builtin_type_int, coreptr + 4 * HP_ACC_TYPEINFO_OFFSET,
VALUE_BFD_SECTION (v));
coreptr = *(CORE_ADDR *) (VALUE_CONTENTS (vp));
if (!coreptr)
error ("Retrieved null typeinfo pointer in trying to determine "
"run-time type");
vp = value_at (builtin_type_int, coreptr + 4, VALUE_BFD_SECTION (v));
coreptr = *(CORE_ADDR *) (VALUE_CONTENTS (vp));
read_memory_string (coreptr, rtti_type_name, 256);
if (strlen (rtti_type_name) == 0)
error ("Retrieved null type name from typeinfo");
rtti_type = lookup_typename (rtti_type_name, (struct block *) 0, 1);
if (!rtti_type)
error ("Could not find run-time type: invalid type name %s in typeinfo??",
rtti_type_name);
CHECK_TYPEDEF (rtti_type);
#if 0
printf ("RTTI type name %s, tag %s, full? %d\n", TYPE_NAME (rtti_type),
TYPE_TAG_NAME (rtti_type), full ? *full : -1);
#endif
if (full
&&
(((top_offset == 0) &&
using_enclosing &&
TYPE_LENGTH (known_type) == TYPE_LENGTH (rtti_type))
||
((top_offset == VALUE_EMBEDDED_OFFSET (v)) &&
!using_enclosing &&
TYPE_LENGTH (VALUE_ENCLOSING_TYPE (v)) == TYPE_LENGTH (rtti_type))))
*full = 1;
return rtti_type;
}
extern int gnuv2_baseclass_offset (struct type *type, int index,
char *valaddr, CORE_ADDR address);
static void
init_hpacc_ops (void)
{
hpacc_abi_ops.shortname = "hpaCC";
hpacc_abi_ops.longname = "HP aCC ABI";
hpacc_abi_ops.doc = "HP aCC ABI";
hpacc_abi_ops.is_destructor_name = hpacc_is_destructor_name;
hpacc_abi_ops.is_constructor_name = hpacc_is_constructor_name;
hpacc_abi_ops.is_vtable_name = hpacc_is_vtable_name;
hpacc_abi_ops.is_operator_name = hpacc_is_operator_name;
hpacc_abi_ops.virtual_fn_field = hpacc_virtual_fn_field;
hpacc_abi_ops.rtti_type = hpacc_value_rtti_type;
hpacc_abi_ops.baseclass_offset = gnuv2_baseclass_offset;
}
extern initialize_file_ftype _initialize_hpacc_abi;
void
_initialize_hpacc_abi (void)
{
init_hpacc_ops ();
regcomp (&constructor_pattern,
"^This will never match anything, please fill it in$", REG_NOSUB);
regcomp (&destructor_pattern,
"^This will never match anything, please fill it in$", REG_NOSUB);
regcomp (&operator_pattern,
"^This will never match anything, please fill it in$", REG_NOSUB);
register_cp_abi (&hpacc_abi_ops);
}