* exceptions.h (NOT_AVAILABLE_ERROR): New error.
	* value.c: Include "exceptions.h".
	(require_available): Throw NOT_AVAILABLE_ERROR instead of a
	generic error.
	* cp-abi.c: Include gdb_assert.h.
	(baseclass_offset): Add `embedded_offset' and `val' parameters.
	Assert the method is implemented.  Wrap NOT_AVAILABLE_ERROR
	errors.
	* cp-abi.h (baseclass_offset): Add `embedded_offset' and `val'
	parameters.  No longer returns -1 on error.
	(struct cp_abi_ops) <baseclass_offset>: Add `embedded_offset' and
	`val' parameters.
	* cp-valprint.c: Include exceptions.h.
	(cp_print_value): Handle NOT_AVAILABLE_ERROR errors when fetching
	the baseclass_offset.  Handle unavailable base classes.  Use
	val_print_invalid_address.
	* p-valprint.c: Include exceptions.h.
	(pascal_object_print_value): Handle NOT_AVAILABLE_ERROR errors
	when fetching the baseclass_offset.  No longer expect
	baseclass_offset returning -1.  Handle unavailable base classes.
	Use val_print_invalid_address.
	* valops.c (dynamic_cast_check_1): Rename `contents' parameter to
	`valaddr' parameter, and change its type to gdb_byte pointer.  Add
	`embedded_offset' and `val' parameters.  Adjust.
	(dynamic_cast_check_2): Rename `contents' parameter to `valaddr'
	parameter, and change its type to gdb_byte pointer.  Add
	`embedded_offset' and `val' parameters.  Adjust.  No longer expect
	baseclass_offset returning -1.
	(value_dynamic_cast): Use value_contents_for_printing rather than
	value_contents.  Adjust.
	(search_struct_field): No longer expect baseclass_offset returning
	-1.
	(search_struct_method): If reading memory from the target is
	necessary, wrap it in a new value to pass to baseclass_offset.  No
	longer expect baseclass_offset returning -1.
	(find_method_list): No longer expect baseclass_offset returning
	-1.  Use value_contents_for_printing rather than value_contents.
	* valprint.c (val_print_invalid_address): New function.
	* valprint.h (val_print_invalid_address): Declare.
	* gdbtypes.c (is_unique_ancestor_worker): New `embedded_offset'
	and `val' parameters.  No longer expect baseclass_offset returning
	-1.  Adjust.
	* gnu-v2-abi.c: Include "exceptions.h".
	(gnuv2_baseclass_offset): Add `embedded_offset' and `val'
	parameters.  Handle unavailable memory.  Recurse through
	gnuv2_baseclass_offset directly, rather than through
	baseclass_offset.  No longer returns -1 on not found, instead
	throw an error.
	* gnu-v3-abi.c (gnuv3_baseclass_offset): Add `embedded_offset' and
	`val' parameters.  Adjust.

	gdb/testsuite/
	* gdb.trace/unavailable.cc (class Base, class Middle, class
	Derived): New types.
	(derived_unavail, derived_partial, derived_whole): New globals.
	(virtual_partial): New global.
	(virtualp): Point at virtual_partial.
	* gdb.trace/unavailable.exp (gdb_collect_globals_test): Add tests
	related to unavailable vptr.
This commit is contained in:
Pedro Alves
2011-02-14 11:35:45 +00:00
parent 1b28d0b3be
commit 8af8e3bc81
16 changed files with 385 additions and 146 deletions

View File

@@ -652,8 +652,10 @@ value_reinterpret_cast (struct type *type, struct value *arg)
static int
dynamic_cast_check_1 (struct type *desired_type,
const bfd_byte *contents,
const gdb_byte *valaddr,
int embedded_offset,
CORE_ADDR address,
struct value *val,
struct type *search_type,
CORE_ADDR arg_addr,
struct type *arg_type,
@@ -663,25 +665,25 @@ dynamic_cast_check_1 (struct type *desired_type,
for (i = 0; i < TYPE_N_BASECLASSES (search_type) && result_count < 2; ++i)
{
int offset = baseclass_offset (search_type, i, contents, address);
int offset = baseclass_offset (search_type, i, valaddr, embedded_offset,
address, val);
if (offset == -1)
error (_("virtual baseclass botch"));
if (class_types_same_p (desired_type, TYPE_BASECLASS (search_type, i)))
{
if (address + offset >= arg_addr
&& address + offset < arg_addr + TYPE_LENGTH (arg_type))
if (address + embedded_offset + offset >= arg_addr
&& address + embedded_offset + offset < arg_addr + TYPE_LENGTH (arg_type))
{
++result_count;
if (!*result)
*result = value_at_lazy (TYPE_BASECLASS (search_type, i),
address + offset);
address + embedded_offset + offset);
}
}
else
result_count += dynamic_cast_check_1 (desired_type,
contents + offset,
address + offset,
valaddr,
embedded_offset + offset,
address, val,
TYPE_BASECLASS (search_type, i),
arg_addr,
arg_type,
@@ -697,8 +699,10 @@ dynamic_cast_check_1 (struct type *desired_type,
static int
dynamic_cast_check_2 (struct type *desired_type,
const bfd_byte *contents,
const gdb_byte *valaddr,
int embedded_offset,
CORE_ADDR address,
struct value *val,
struct type *search_type,
struct value **result)
{
@@ -711,20 +715,20 @@ dynamic_cast_check_2 (struct type *desired_type,
if (! BASETYPE_VIA_PUBLIC (search_type, i))
continue;
offset = baseclass_offset (search_type, i, contents, address);
if (offset == -1)
error (_("virtual baseclass botch"));
offset = baseclass_offset (search_type, i, valaddr, embedded_offset,
address, val);
if (class_types_same_p (desired_type, TYPE_BASECLASS (search_type, i)))
{
++result_count;
if (*result == NULL)
*result = value_at_lazy (TYPE_BASECLASS (search_type, i),
address + offset);
address + embedded_offset + offset);
}
else
result_count += dynamic_cast_check_2 (desired_type,
contents + offset,
address + offset,
valaddr,
embedded_offset + offset,
address, val,
TYPE_BASECLASS (search_type, i),
result);
}
@@ -822,7 +826,9 @@ value_dynamic_cast (struct type *type, struct value *arg)
return tem;
result = NULL;
if (dynamic_cast_check_1 (TYPE_TARGET_TYPE (resolved_type),
value_contents (tem), value_address (tem),
value_contents_for_printing (tem),
value_embedded_offset (tem),
value_address (tem), tem,
rtti_type, addr,
arg_type,
&result) == 1)
@@ -834,7 +840,9 @@ value_dynamic_cast (struct type *type, struct value *arg)
result = NULL;
if (is_public_ancestor (arg_type, rtti_type)
&& dynamic_cast_check_2 (TYPE_TARGET_TYPE (resolved_type),
value_contents (tem), value_address (tem),
value_contents_for_printing (tem),
value_embedded_offset (tem),
value_address (tem), tem,
rtti_type, &result) == 1)
return value_cast (type,
is_ref ? value_ref (result) : value_addr (result));
@@ -1323,6 +1331,7 @@ value_assign (struct value *toval, struct value *fromval)
int offset = value_offset (parent) + value_offset (toval);
int changed_len;
gdb_byte buffer[sizeof (LONGEST)];
int optim, unavail;
changed_len = (value_bitpos (toval)
+ value_bitsize (toval)
@@ -2075,12 +2084,10 @@ search_struct_field (const char *name, struct value *arg1, int offset,
struct value *v2;
boffset = baseclass_offset (type, i,
value_contents (arg1) + offset,
value_address (arg1)
+ value_embedded_offset (arg1)
+ offset);
if (boffset == -1)
error (_("virtual baseclass botch"));
value_contents_for_printing (arg1),
value_embedded_offset (arg1) + offset,
value_address (arg1),
arg1);
/* The virtual base class pointer might have been clobbered
by the user program. Make sure that it still points to a
@@ -2202,10 +2209,13 @@ search_struct_method (const char *name, struct value **arg1p,
for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--)
{
int base_offset;
int skip = 0;
int this_offset;
if (BASETYPE_VIA_VIRTUAL (type, i))
{
struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i));
struct value *base_val;
const gdb_byte *base_valaddr;
/* The virtual base class pointer might have been
@@ -2215,19 +2225,28 @@ search_struct_method (const char *name, struct value **arg1p,
if (offset < 0 || offset >= TYPE_LENGTH (type))
{
gdb_byte *tmp = alloca (TYPE_LENGTH (baseclass));
CORE_ADDR address = value_address (*arg1p);
if (target_read_memory (value_address (*arg1p) + offset,
if (target_read_memory (address + offset,
tmp, TYPE_LENGTH (baseclass)) != 0)
error (_("virtual baseclass botch"));
base_valaddr = tmp;
base_val = value_from_contents_and_address (baseclass,
tmp,
address + offset);
base_valaddr = value_contents_for_printing (base_val);
this_offset = 0;
}
else
base_valaddr = value_contents (*arg1p) + offset;
{
base_val = *arg1p;
base_valaddr = value_contents_for_printing (*arg1p);
this_offset = offset;
}
base_offset = baseclass_offset (type, i, base_valaddr,
value_address (*arg1p) + offset);
if (base_offset == -1)
error (_("virtual baseclass botch"));
this_offset, value_address (base_val),
base_val);
}
else
{
@@ -2405,12 +2424,10 @@ find_method_list (struct value **argp, const char *method,
if (BASETYPE_VIA_VIRTUAL (type, i))
{
base_offset = value_offset (*argp) + offset;
base_offset = baseclass_offset (type, i,
value_contents (*argp) + base_offset,
value_address (*argp) + base_offset);
if (base_offset == -1)
error (_("virtual baseclass botch"));
value_contents_for_printing (*argp),
value_offset (*argp) + offset,
value_address (*argp), *argp);
}
else /* Non-virtual base, simply use bit position from debug
info. */