mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-26 17:18:55 +00:00
gdb/
* 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:
@@ -28,6 +28,7 @@
|
||||
#include "demangle.h"
|
||||
#include "cp-abi.h"
|
||||
#include "cp-support.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
@@ -334,17 +335,15 @@ vb_match (struct type *type, int index, struct type *basetype)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Compute the offset of the baseclass which is
|
||||
the INDEXth baseclass of class TYPE,
|
||||
for value at VALADDR (in host) at ADDRESS (in target).
|
||||
The result is the offset of the baseclass value relative
|
||||
to (the address of)(ARG) + OFFSET.
|
||||
|
||||
-1 is returned on error. */
|
||||
/* Compute the offset of the baseclass which is the INDEXth baseclass
|
||||
of class TYPE, for value at VALADDR (in host) at ADDRESS (in
|
||||
target). The result is the offset of the baseclass value relative
|
||||
to (the address of)(ARG) + OFFSET. */
|
||||
|
||||
static int
|
||||
gnuv2_baseclass_offset (struct type *type, int index,
|
||||
const bfd_byte *valaddr, CORE_ADDR address)
|
||||
const bfd_byte *valaddr, int embedded_offset,
|
||||
CORE_ADDR address, const struct value *val)
|
||||
{
|
||||
struct type *basetype = TYPE_BASECLASS (type, index);
|
||||
|
||||
@@ -360,24 +359,41 @@ gnuv2_baseclass_offset (struct type *type, int index,
|
||||
{
|
||||
if (vb_match (type, i, basetype))
|
||||
{
|
||||
CORE_ADDR addr
|
||||
= unpack_pointer (TYPE_FIELD_TYPE (type, i),
|
||||
valaddr + (TYPE_FIELD_BITPOS (type, i) / 8));
|
||||
struct type *field_type;
|
||||
int field_offset;
|
||||
int field_length;
|
||||
CORE_ADDR addr;
|
||||
|
||||
return addr - (LONGEST) address;
|
||||
field_type = check_typedef (TYPE_FIELD_TYPE (type, i));
|
||||
field_offset = TYPE_FIELD_BITPOS (type, i) / 8;
|
||||
field_length = TYPE_LENGTH (field_type);
|
||||
|
||||
if (!value_bytes_available (val, embedded_offset + field_offset,
|
||||
field_length))
|
||||
throw_error (NOT_AVAILABLE_ERROR,
|
||||
_("Virtual baseclass pointer is not available"));
|
||||
|
||||
addr = unpack_pointer (field_type,
|
||||
valaddr + embedded_offset + field_offset);
|
||||
|
||||
return addr - (LONGEST) address + embedded_offset;
|
||||
}
|
||||
}
|
||||
/* Not in the fields, so try looking through the baseclasses. */
|
||||
for (i = index + 1; i < n_baseclasses; i++)
|
||||
{
|
||||
/* Don't go through baseclass_offset, as that wraps
|
||||
exceptions, thus, inner exceptions would be wrapped more
|
||||
than once. */
|
||||
int boffset =
|
||||
baseclass_offset (type, i, valaddr, address);
|
||||
gnuv2_baseclass_offset (type, i, valaddr,
|
||||
embedded_offset, address, val);
|
||||
|
||||
if (boffset)
|
||||
return boffset;
|
||||
}
|
||||
/* Not found. */
|
||||
return -1;
|
||||
|
||||
error (_("Baseclass offset not found"));
|
||||
}
|
||||
|
||||
/* Baseclass is easily computed. */
|
||||
|
||||
Reference in New Issue
Block a user