X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fgnu-v3-abi.c;h=83deed5965792fa3ef5a7568007f0bbcfdf0c87b;hb=b4991d292edd84c16bd2050bd071198ceae764fe;hp=88543396526b80448b9d9076838161b750eb43a5;hpb=b811d2c2920ddcb1adcd438da38e90912b31f45f;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/gnu-v3-abi.c b/gdb/gnu-v3-abi.c index 8854339652..83deed5965 100644 --- a/gdb/gnu-v3-abi.c +++ b/gdb/gnu-v3-abi.c @@ -30,6 +30,7 @@ #include "typeprint.h" #include #include "cli/cli-style.h" +#include "dwarf2/loc.h" static struct cp_abi_ops gnu_v3_abi_ops; @@ -461,6 +462,31 @@ gnuv3_baseclass_offset (struct type *type, int index, if (!BASETYPE_VIA_VIRTUAL (type, index)) return TYPE_BASECLASS_BITPOS (type, index) / 8; + /* If we have a DWARF expression for the offset, evaluate it. */ + if (TYPE_FIELD_LOC_KIND (type, index) == FIELD_LOC_KIND_DWARF_BLOCK) + { + struct dwarf2_property_baton baton; + baton.property_type + = lookup_pointer_type (TYPE_FIELD_TYPE (type, index)); + baton.locexpr = *TYPE_FIELD_DWARF_BLOCK (type, index); + + struct dynamic_prop prop; + prop.kind = PROP_LOCEXPR; + prop.data.baton = &baton; + + struct property_addr_info addr_stack; + addr_stack.type = type; + /* Note that we don't set "valaddr" here. Doing so causes + regressions. FIXME. */ + addr_stack.addr = address + embedded_offset; + addr_stack.next = nullptr; + + CORE_ADDR result; + if (dwarf2_evaluate_property (&prop, nullptr, &addr_stack, &result, + true)) + return (int) (result - addr_stack.addr); + } + /* To access a virtual base, we need to use the vbase offset stored in our vtable. Recent GCC versions provide this information. If it isn't available, we could get what we needed from RTTI, or from drawing the @@ -1064,7 +1090,8 @@ gnuv3_get_typeid (struct value *value) struct type *type; struct gdbarch *gdbarch; struct value *result; - std::string type_name, canonical; + std::string type_name; + gdb::unique_xmalloc_ptr canonical; /* We have to handle values a bit trickily here, to allow this code to work properly with non_lvalue values that are really just @@ -1092,8 +1119,9 @@ gnuv3_get_typeid (struct value *value) uses. E.g., GDB tends to use "const char *" as a type name, but the demangler uses "char const *". */ canonical = cp_canonicalize_string (type_name.c_str ()); - if (!canonical.empty ()) - type_name = canonical; + const char *name = (canonical == nullptr + ? type_name.c_str () + : canonical.get ()); typeinfo_type = gnuv3_get_typeid_type (gdbarch); @@ -1109,19 +1137,19 @@ gnuv3_get_typeid (struct value *value) vtable = gnuv3_get_vtable (gdbarch, type, address); if (vtable == NULL) error (_("cannot find typeinfo for object of type '%s'"), - type_name.c_str ()); + name); typeinfo_value = value_field (vtable, vtable_field_type_info); result = value_ind (value_cast (make_pointer_type (typeinfo_type, NULL), typeinfo_value)); } else { - std::string sym_name = std::string ("typeinfo for ") + type_name; + std::string sym_name = std::string ("typeinfo for ") + name; bound_minimal_symbol minsym = lookup_minimal_symbol (sym_name.c_str (), NULL, NULL); if (minsym.minsym == NULL) - error (_("could not find typeinfo symbol for '%s'"), type_name.c_str ()); + error (_("could not find typeinfo symbol for '%s'"), name); result = value_at_lazy (typeinfo_type, BMSYMBOL_VALUE_ADDRESS (minsym)); } @@ -1568,8 +1596,9 @@ init_gnuv3_ops (void) gnu_v3_abi_ops.pass_by_reference = gnuv3_pass_by_reference; } +void _initialize_gnu_v3_abi (); void -_initialize_gnu_v3_abi (void) +_initialize_gnu_v3_abi () { init_gnuv3_ops ();