diff options
author | Pedro Alves <palves@redhat.com> | 2011-02-14 11:35:45 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2011-02-14 11:35:45 +0000 |
commit | 8af8e3bc815c464731924d121681ac73cae1ab1d (patch) | |
tree | ff401808e5259498226db71f707f4fdf7aa30c33 /gdb/valops.c | |
parent | 1b28d0b3beda72343ea25f135f17746340cae89c (diff) | |
download | gdb-8af8e3bc815c464731924d121681ac73cae1ab1d.zip gdb-8af8e3bc815c464731924d121681ac73cae1ab1d.tar.gz gdb-8af8e3bc815c464731924d121681ac73cae1ab1d.tar.bz2 |
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.
Diffstat (limited to 'gdb/valops.c')
-rw-r--r-- | gdb/valops.c | 87 |
1 files changed, 52 insertions, 35 deletions
diff --git a/gdb/valops.c b/gdb/valops.c index 1f25a32..5465aba 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -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. */ |