diff options
author | David Taylor <taylor@redhat.com> | 1998-12-28 23:06:13 +0000 |
---|---|---|
committer | David Taylor <taylor@redhat.com> | 1998-12-28 23:06:13 +0000 |
commit | 4ef1f4677390c085543fe80eec41b0fe5d58ddca (patch) | |
tree | d0e8320e4871a81733155e8ce653507dd3d64825 /gdb/values.c | |
parent | d6fdf61c78fbce1dad62cd1022e606fdaaad4202 (diff) | |
download | gdb-4ef1f4677390c085543fe80eec41b0fe5d58ddca.zip gdb-4ef1f4677390c085543fe80eec41b0fe5d58ddca.tar.gz gdb-4ef1f4677390c085543fe80eec41b0fe5d58ddca.tar.bz2 |
hp merge changes -- too numerous to mention here; see ChangeLog and
ChangeLog-gdbtk for details.
Diffstat (limited to 'gdb/values.c')
-rw-r--r-- | gdb/values.c | 277 |
1 files changed, 204 insertions, 73 deletions
diff --git a/gdb/values.c b/gdb/values.c index db6f204..ecc11fe 100644 --- a/gdb/values.c +++ b/gdb/values.c @@ -86,6 +86,7 @@ allocate_value (type) VALUE_NEXT (val) = all_values; all_values = val; VALUE_TYPE (val) = type; + VALUE_ENCLOSING_TYPE (val) = type; VALUE_LVAL (val) = not_lval; VALUE_ADDRESS (val) = 0; VALUE_FRAME (val) = 0; @@ -96,6 +97,8 @@ allocate_value (type) VALUE_LAZY (val) = 0; VALUE_OPTIMIZED_OUT (val) = 0; VALUE_BFD_SECTION (val) = NULL; + VALUE_EMBEDDED_OFFSET (val) = 0; + VALUE_POINTED_TO_OFFSET (val) = 0; val->modifiable = 1; return val; } @@ -213,8 +216,9 @@ value_ptr value_copy (arg) value_ptr arg; { - register struct type *type = VALUE_TYPE (arg); - register value_ptr val = allocate_value (type); + register struct type *encl_type = VALUE_ENCLOSING_TYPE (arg); + register value_ptr val = allocate_value (encl_type); + VALUE_TYPE (val) = VALUE_TYPE (arg); VALUE_LVAL (val) = VALUE_LVAL (arg); VALUE_ADDRESS (val) = VALUE_ADDRESS (arg); VALUE_OFFSET (val) = VALUE_OFFSET (arg); @@ -224,12 +228,15 @@ value_copy (arg) VALUE_REGNO (val) = VALUE_REGNO (arg); VALUE_LAZY (val) = VALUE_LAZY (arg); VALUE_OPTIMIZED_OUT (val) = VALUE_OPTIMIZED_OUT (arg); + VALUE_EMBEDDED_OFFSET (val) = VALUE_EMBEDDED_OFFSET (arg); + VALUE_POINTED_TO_OFFSET (val) = VALUE_POINTED_TO_OFFSET (arg); VALUE_BFD_SECTION (val) = VALUE_BFD_SECTION (arg); val->modifiable = arg->modifiable; if (!VALUE_LAZY (val)) { - memcpy (VALUE_CONTENTS_RAW (val), VALUE_CONTENTS_RAW (arg), - TYPE_LENGTH (VALUE_TYPE (arg))); + memcpy (VALUE_CONTENTS_ALL_RAW (val), VALUE_CONTENTS_ALL_RAW (arg), + TYPE_LENGTH (VALUE_ENCLOSING_TYPE (arg))); + } return val; } @@ -744,9 +751,23 @@ value_static_field (type, fieldno) char *phys_name = TYPE_FIELD_STATIC_PHYSNAME (type, fieldno); struct symbol *sym = lookup_symbol (phys_name, 0, VAR_NAMESPACE, 0, NULL); if (sym == NULL) - return NULL; - addr = SYMBOL_VALUE_ADDRESS (sym); - sect = SYMBOL_BFD_SECTION (sym); + { + /* With some compilers, e.g. HP aCC, static data members are reported + as non-debuggable symbols */ + struct minimal_symbol * msym = lookup_minimal_symbol (phys_name, NULL, NULL); + if (!msym) + return NULL; + else + { + addr = SYMBOL_VALUE_ADDRESS (msym); + sect = SYMBOL_BFD_SECTION (msym); + } + } + else + { + addr = SYMBOL_VALUE_ADDRESS (sym); + sect = SYMBOL_BFD_SECTION (sym); + } SET_FIELD_PHYSADDR (TYPE_FIELD (type, fieldno), addr); } return value_at (TYPE_FIELD_TYPE (type, fieldno), addr, sect); @@ -782,23 +803,43 @@ value_primitive_field (arg1, offset, fieldno, arg_type) VALUE_BITPOS (v) = TYPE_FIELD_BITPOS (arg_type, fieldno) % 8; VALUE_BITSIZE (v) = TYPE_FIELD_BITSIZE (arg_type, fieldno); } + else if (fieldno < TYPE_N_BASECLASSES (arg_type)) + { + /* This field is actually a base subobject, so preserve the + entire object's contents for later references to virtual + bases, etc. */ + v = allocate_value (VALUE_ENCLOSING_TYPE (arg1)); + VALUE_TYPE (v) = arg_type; + if (VALUE_LAZY (arg1)) + VALUE_LAZY (v) = 1; + else + memcpy (VALUE_CONTENTS_ALL_RAW (v), VALUE_CONTENTS_ALL_RAW (arg1), + TYPE_LENGTH (VALUE_ENCLOSING_TYPE (arg1))); + VALUE_OFFSET (v) = VALUE_OFFSET (arg1); + VALUE_EMBEDDED_OFFSET (v) + = offset + + VALUE_EMBEDDED_OFFSET (arg1) + + TYPE_FIELD_BITPOS (arg_type, fieldno) / 8; + } else { + /* Plain old data member */ + offset += TYPE_FIELD_BITPOS (arg_type, fieldno) / 8; v = allocate_value (type); if (VALUE_LAZY (arg1)) VALUE_LAZY (v) = 1; else memcpy (VALUE_CONTENTS_RAW (v), - VALUE_CONTENTS_RAW (arg1) + offset - + TYPE_FIELD_BITPOS (arg_type, fieldno) / 8, + VALUE_CONTENTS_RAW (arg1) + offset, TYPE_LENGTH (type)); + VALUE_OFFSET (v) = VALUE_OFFSET (arg1) + offset; } VALUE_LVAL (v) = VALUE_LVAL (arg1); if (VALUE_LVAL (arg1) == lval_internalvar) VALUE_LVAL (v) = lval_internalvar_component; VALUE_ADDRESS (v) = VALUE_ADDRESS (arg1); - VALUE_OFFSET (v) = VALUE_OFFSET (arg1) + offset - + TYPE_FIELD_BITPOS (arg_type, fieldno) / 8; +/* VALUE_OFFSET (v) = VALUE_OFFSET (arg1) + offset + + TYPE_FIELD_BITPOS (arg_type, fieldno) / 8; */ return v; } @@ -875,74 +916,164 @@ value_virtual_fn_field (arg1p, f, j, type, offset) { value_ptr arg1 = *arg1p; struct type *type1 = check_typedef (VALUE_TYPE (arg1)); - struct type *entry_type; - /* First, get the virtual function table pointer. That comes - with a strange type, so cast it to type `pointer to long' (which - should serve just fine as a function type). Then, index into - the table, and convert final value to appropriate function type. */ - value_ptr entry, vfn, vtbl; - value_ptr vi = value_from_longest (builtin_type_int, - (LONGEST) TYPE_FN_FIELD_VOFFSET (f, j)); - struct type *fcontext = TYPE_FN_FIELD_FCONTEXT (f, j); - struct type *context; - if (fcontext == NULL) - /* We don't have an fcontext (e.g. the program was compiled with - g++ version 1). Try to get the vtbl from the TYPE_VPTR_BASETYPE. - This won't work right for multiple inheritance, but at least we - should do as well as GDB 3.x did. */ - fcontext = TYPE_VPTR_BASETYPE (type); - context = lookup_pointer_type (fcontext); - /* Now context is a pointer to the basetype containing the vtbl. */ - if (TYPE_TARGET_TYPE (context) != type1) - { - arg1 = value_ind (value_cast (context, value_addr (arg1))); - type1 = check_typedef (VALUE_TYPE (arg1)); - } - context = type1; - /* Now context is the basetype containing the vtbl. */ - - /* This type may have been defined before its virtual function table - was. If so, fill in the virtual function table entry for the - type now. */ - if (TYPE_VPTR_FIELDNO (context) < 0) - fill_in_vptr_fieldno (context); - - /* The virtual function table is now an array of structures - which have the form { int16 offset, delta; void *pfn; }. */ - vtbl = value_ind (value_primitive_field (arg1, 0, - TYPE_VPTR_FIELDNO (context), - TYPE_VPTR_BASETYPE (context))); - - /* Index into the virtual function table. This is hard-coded because - looking up a field is not cheap, and it may be important to save - time, e.g. if the user has set a conditional breakpoint calling - a virtual function. */ - entry = value_subscript (vtbl, vi); - entry_type = check_typedef (VALUE_TYPE (entry)); - - if (TYPE_CODE (entry_type) == TYPE_CODE_STRUCT) + if (TYPE_HAS_VTABLE (type)) { - /* Move the `this' pointer according to the virtual function table. */ - VALUE_OFFSET (arg1) += value_as_long (value_field (entry, 0)); + /* Deal with HP/Taligent runtime model for virtual functions */ + value_ptr vp; + value_ptr argp; /* arg1 cast to base */ + CORE_ADDR vfunc_addr; /* address of virtual method */ + CORE_ADDR coreptr; /* pointer to target address */ + int class_index; /* which class segment pointer to use */ + struct type * ftype = TYPE_FN_FIELD_TYPE (f, j); /* method type */ + + argp = value_cast (type, *arg1p); + + if (VALUE_ADDRESS (argp) == 0) + error ("Address of object is null; object may not have been created."); - if (! VALUE_LAZY (arg1)) - { - VALUE_LAZY (arg1) = 1; - value_fetch_lazy (arg1); - } + /* pai: FIXME -- 32x64 possible problem? */ + /* First word (4 bytes) in object layout is the vtable pointer */ + coreptr = * (CORE_ADDR *) (VALUE_CONTENTS (argp)); /* pai: (temp) */ + /* + offset + VALUE_EMBEDDED_OFFSET (argp)); */ - vfn = value_field (entry, 2); + if (!coreptr) + error ("Virtual table pointer is null for object; object may not have been created."); + + /* pai/1997-05-09 + * FIXME: The code here currently handles only + * the non-RRBC case of the Taligent/HP runtime spec; when RRBC + * is introduced, the condition for the "if" below will have to + * be changed to be a test for the RRBC case. */ + + if (1) + { + /* Non-RRBC case; the virtual function pointers are stored at fixed + * offsets in the virtual table. */ + + /* Retrieve the offset in the virtual table from the debug + * info. The offset of the vfunc's entry is in words from + * the beginning of the vtable; but first we have to adjust + * by HP_ACC_VFUNC_START to account for other entries */ + + /* pai: FIXME: 32x64 problem here, a word may be 8 bytes in + * which case the multiplier should be 8 and values should be long */ + 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)); + /* coreptr now contains the address of the virtual function */ + /* (Actually, it contains the pointer to the plabel for the function. */ + } + else + { + /* RRBC case; the virtual function pointers are found by double + * indirection through the class segment tables. */ + + /* Choose class segment depending on type we were passed */ + class_index = class_index_in_primary_list (type); + + /* Find class segment pointer. These are in the vtable slots after + * some other entries, so adjust by HP_ACC_VFUNC_START for that. */ + /* pai: FIXME 32x64 problem here, if words are 8 bytes long + * the multiplier below has to be 8 and value should be long. */ + vp = value_at (builtin_type_int, + coreptr + 4 * (HP_ACC_VFUNC_START + class_index), NULL); + /* Indirect once more, offset by function index */ + /* pai: FIXME 32x64 problem here, again multiplier could be 8 and value long */ + 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)); + + /* coreptr now contains the address of the virtual function */ + /* (Actually, it contains the pointer to the plabel for the function.) */ + + } + + if (!coreptr) + error ("Address of virtual function is null; error in virtual table?"); + + /* Wrap this addr in a value and return pointer */ + vp = allocate_value (ftype); + VALUE_TYPE (vp) = ftype; + VALUE_ADDRESS (vp) = coreptr; + + /* pai: (temp) do we need the value_ind stuff in value_fn_field? */ + return vp; } - else if (TYPE_CODE (entry_type) == TYPE_CODE_PTR) - vfn = entry; - else - error ("I'm confused: virtual function table has bad type"); - /* Reinstantiate the function pointer with the correct type. */ - VALUE_TYPE (vfn) = lookup_pointer_type (TYPE_FN_FIELD_TYPE (f, j)); + else + { /* Not using HP/Taligent runtime conventions; so try to + * use g++ conventions for virtual table */ + + struct type *entry_type; + /* First, get the virtual function table pointer. That comes + with a strange type, so cast it to type `pointer to long' (which + should serve just fine as a function type). Then, index into + the table, and convert final value to appropriate function type. */ + value_ptr entry, vfn, vtbl; + value_ptr vi = value_from_longest (builtin_type_int, + (LONGEST) TYPE_FN_FIELD_VOFFSET (f, j)); + struct type *fcontext = TYPE_FN_FIELD_FCONTEXT (f, j); + struct type *context; + if (fcontext == NULL) + /* We don't have an fcontext (e.g. the program was compiled with + g++ version 1). Try to get the vtbl from the TYPE_VPTR_BASETYPE. + This won't work right for multiple inheritance, but at least we + should do as well as GDB 3.x did. */ + fcontext = TYPE_VPTR_BASETYPE (type); + context = lookup_pointer_type (fcontext); + /* Now context is a pointer to the basetype containing the vtbl. */ + if (TYPE_TARGET_TYPE (context) != type1) + { + arg1 = value_ind (value_cast (context, value_addr (arg1))); + type1 = check_typedef (VALUE_TYPE (arg1)); + } + + context = type1; + /* Now context is the basetype containing the vtbl. */ + + /* This type may have been defined before its virtual function table + was. If so, fill in the virtual function table entry for the + type now. */ + if (TYPE_VPTR_FIELDNO (context) < 0) + fill_in_vptr_fieldno (context); + + /* The virtual function table is now an array of structures + which have the form { int16 offset, delta; void *pfn; }. */ + vtbl = value_ind (value_primitive_field (arg1, 0, + TYPE_VPTR_FIELDNO (context), + TYPE_VPTR_BASETYPE (context))); + + /* Index into the virtual function table. This is hard-coded because + looking up a field is not cheap, and it may be important to save + time, e.g. if the user has set a conditional breakpoint calling + a virtual function. */ + entry = value_subscript (vtbl, vi); + entry_type = check_typedef (VALUE_TYPE (entry)); + + if (TYPE_CODE (entry_type) == TYPE_CODE_STRUCT) + { + /* Move the `this' pointer according to the virtual function table. */ + VALUE_OFFSET (arg1) += value_as_long (value_field (entry, 0)); + + if (! VALUE_LAZY (arg1)) + { + VALUE_LAZY (arg1) = 1; + value_fetch_lazy (arg1); + } + + vfn = value_field (entry, 2); + } + else if (TYPE_CODE (entry_type) == TYPE_CODE_PTR) + vfn = entry; + else + error ("I'm confused: virtual function table has bad type"); + /* Reinstantiate the function pointer with the correct type. */ + VALUE_TYPE (vfn) = lookup_pointer_type (TYPE_FN_FIELD_TYPE (f, j)); - *arg1p = arg1; - return vfn; + *arg1p = arg1; + return vfn; + } } /* ARG is a pointer to an object we know to be at least |