X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fvalues.c;h=7b6dd6b9e7de3b10f0e5759f74ad8f56d769b7e0;hb=b3d32d4f8f2637d2ae041d90b2e01fc841423747;hp=916bf6f27ab1c074741f435c47f216d7bd5bef32;hpb=b8176214a5bb9810bf6d5244815e9a49c5055dce;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/values.c b/gdb/values.c index 916bf6f27a..7b6dd6b9e7 100644 --- a/gdb/values.c +++ b/gdb/values.c @@ -1,5 +1,5 @@ /* Low level packing and unpacking of values for GDB, the GNU Debugger. - Copyright 1986, 1987, 1989, 1991, 1993, 1994 + Copyright 1986, 87, 89, 91, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc. This file is part of GDB. @@ -16,10 +16,10 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software -Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "defs.h" -#include +#include "gdb_string.h" #include "symtab.h" #include "gdbtypes.h" #include "value.h" @@ -28,9 +28,15 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "command.h" #include "gdbcmd.h" #include "target.h" +#include "language.h" +#include "scm-lang.h" #include "demangle.h" -/* Local function prototypes. */ +/* Prototypes for exported functions. */ + +void _initialize_values PARAMS ((void)); + +/* Prototypes for local functions. */ static value_ptr value_headof PARAMS ((value_ptr, struct type *, struct type *)); @@ -39,6 +45,8 @@ static void show_values PARAMS ((char *, int)); static void show_convenience PARAMS ((char *, int)); +static int vb_match PARAMS ((struct type *, int, struct type *)); + /* The value-history records all the values printed by print commands during this session. Each chunk records 60 consecutive values. The first chunk on @@ -72,24 +80,25 @@ allocate_value (type) struct type *type; { register value_ptr val; + struct type *atype = check_typedef (type); - check_stub_type (type); - - val = (struct value *) xmalloc (sizeof (struct value) + TYPE_LENGTH (type)); + val = (struct value *) xmalloc (sizeof (struct value) + TYPE_LENGTH (atype)); 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; VALUE_OFFSET (val) = 0; VALUE_BITPOS (val) = 0; VALUE_BITSIZE (val) = 0; - VALUE_REPEATED (val) = 0; - VALUE_REPETITIONS (val) = 0; VALUE_REGNO (val) = -1; 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; } @@ -102,25 +111,16 @@ allocate_repeat_value (type, count) struct type *type; int count; { - register value_ptr val; - - val = - (value_ptr) xmalloc (sizeof (struct value) + TYPE_LENGTH (type) * count); - VALUE_NEXT (val) = all_values; - all_values = val; - VALUE_TYPE (val) = type; - VALUE_LVAL (val) = not_lval; - VALUE_ADDRESS (val) = 0; - VALUE_FRAME (val) = 0; - VALUE_OFFSET (val) = 0; - VALUE_BITPOS (val) = 0; - VALUE_BITSIZE (val) = 0; - VALUE_REPEATED (val) = 1; - VALUE_REPETITIONS (val) = count; - VALUE_REGNO (val) = -1; - VALUE_LAZY (val) = 0; - VALUE_OPTIMIZED_OUT (val) = 0; - return val; + int low_bound = current_language->string_lower_bound; /* ??? */ + /* FIXME-type-allocation: need a way to free this type when we are + done with it. */ + struct type *range_type + = create_range_type ((struct type *) NULL, builtin_type_int, + low_bound, count + low_bound - 1); + /* FIXME-type-allocation: need a way to free this type when we are + done with it. */ + return allocate_value (create_array_type ((struct type *) NULL, + type, range_type)); } /* Return a mark in the value chain. All values allocated after the @@ -216,25 +216,27 @@ value_ptr value_copy (arg) value_ptr arg; { - register value_ptr val; - register struct type *type = VALUE_TYPE (arg); - if (VALUE_REPEATED (arg)) - val = allocate_repeat_value (type, VALUE_REPETITIONS (arg)); - else - 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); VALUE_BITPOS (val) = VALUE_BITPOS (arg); VALUE_BITSIZE (val) = VALUE_BITSIZE (arg); + VALUE_FRAME (val) = VALUE_FRAME (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)) - * (VALUE_REPEATED (arg) ? VALUE_REPETITIONS (arg) : 1)); + memcpy (VALUE_CONTENTS_ALL_RAW (val), VALUE_CONTENTS_ALL_RAW (arg), + TYPE_LENGTH (VALUE_ENCLOSING_TYPE (arg))); + } return val; } @@ -252,14 +254,6 @@ record_latest_value (val) { int i; - /* Check error now if about to store an invalid float. We return -1 - to the caller, but allow them to continue, e.g. to print it as "Nan". */ - if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_FLT) - { - unpack_double (VALUE_TYPE (val), VALUE_CONTENTS (val), &i); - if (i) return -1; /* Indicate value not saved in history */ - } - /* We don't want this value to have anything to do with the inferior anymore. In particular, "set $1 = 50" should not affect the variable from which the value was taken, and fast watchpoints should be able to assume that @@ -484,6 +478,7 @@ set_internalvar (var, val) #endif newval = value_copy (val); + newval->modifiable = 1; /* Force the value to be fetched from the target now, to avoid problems later when this internalvar is referenced and the target is gone or @@ -568,16 +563,15 @@ value_as_long (val) /* This coerces arrays and functions, which is necessary (e.g. in disassemble_command). It also dereferences references, which I suspect is the most logical thing to do. */ - if (TYPE_CODE (VALUE_TYPE (val)) != TYPE_CODE_ENUM) - COERCE_ARRAY (val); + COERCE_ARRAY (val); return unpack_long (VALUE_TYPE (val), VALUE_CONTENTS (val)); } -double +DOUBLEST value_as_double (val) register value_ptr val; { - double foo; + DOUBLEST foo; int inv; foo = unpack_double (VALUE_TYPE (val), VALUE_CONTENTS (val), &inv); @@ -626,8 +620,14 @@ unpack_long (type, valaddr) register int len = TYPE_LENGTH (type); register int nosign = TYPE_UNSIGNED (type); + if (current_language->la_language == language_scm + && is_scmvalue_type (type)) + return scm_unpack (type, valaddr, TYPE_CODE_INT); + switch (code) { + case TYPE_CODE_TYPEDEF: + return unpack_long (check_typedef (type), valaddr); case TYPE_CODE_ENUM: case TYPE_CODE_BOOL: case TYPE_CODE_INT: @@ -645,6 +645,10 @@ unpack_long (type, valaddr) case TYPE_CODE_REF: /* Assume a CORE_ADDR can fit in a LONGEST (for now). Not sure whether we want this to be true eventually. */ +#ifdef GDB_TARGET_IS_D10V + if (len == 2) + return D10V_MAKE_DADDR(extract_address (valaddr, len)); +#endif return extract_address (valaddr, len); case TYPE_CODE_MEMBER: @@ -662,17 +666,21 @@ unpack_long (type, valaddr) the returned double is OK to use. Argument is in target format, result is in host format. */ -double +DOUBLEST unpack_double (type, valaddr, invp) struct type *type; char *valaddr; int *invp; { - register enum type_code code = TYPE_CODE (type); - register int len = TYPE_LENGTH (type); - register int nosign = TYPE_UNSIGNED (type); + enum type_code code; + int len; + int nosign; *invp = 0; /* Assume valid. */ + CHECK_TYPEDEF (type); + code = TYPE_CODE (type); + len = TYPE_LENGTH (type); + nosign = TYPE_UNSIGNED (type); if (code == TYPE_CODE_FLT) { #ifdef INVALID_FLOAT @@ -687,7 +695,12 @@ unpack_double (type, valaddr, invp) else if (nosign) { /* Unsigned -- be sure we compensate for signed LONGEST. */ - return (unsigned LONGEST) unpack_long (type, valaddr); +#if !defined (_MSC_VER) || (_MSC_VER > 900) + return (ULONGEST) unpack_long (type, valaddr); +#else + /* FIXME!!! msvc22 doesn't support unsigned __int64 -> double */ + return (LONGEST) unpack_long (type, valaddr); +#endif /* _MSC_VER */ } else { @@ -719,12 +732,51 @@ unpack_pointer (type, valaddr) return unpack_long (type, valaddr); } +/* Get the value of the FIELDN'th field (which must be static) of TYPE. */ + +value_ptr +value_static_field (type, fieldno) + struct type *type; + int fieldno; +{ + CORE_ADDR addr; + asection *sect; + if (TYPE_FIELD_STATIC_HAS_ADDR (type, fieldno)) + { + addr = TYPE_FIELD_STATIC_PHYSADDR (type, fieldno); + sect = NULL; + } + else + { + char *phys_name = TYPE_FIELD_STATIC_PHYSNAME (type, fieldno); + struct symbol *sym = lookup_symbol (phys_name, 0, VAR_NAMESPACE, 0, NULL); + if (sym == NULL) + { + /* 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); +} + /* Given a value ARG1 (offset by OFFSET bytes) of a struct or union type ARG_TYPE, - extract and return the value of one of its fields. - FIELDNO says which field. - - For C++, must also be able to return values from static fields */ + extract and return the value of one of its (non-static) fields. + FIELDNO says which field. */ value_ptr value_primitive_field (arg1, offset, fieldno, arg_type) @@ -736,43 +788,64 @@ value_primitive_field (arg1, offset, fieldno, arg_type) register value_ptr v; register struct type *type; - check_stub_type (arg_type); + CHECK_TYPEDEF (arg_type); type = TYPE_FIELD_TYPE (arg_type, fieldno); /* Handle packed fields */ - offset += TYPE_FIELD_BITPOS (arg_type, fieldno) / 8; if (TYPE_FIELD_BITSIZE (arg_type, fieldno)) { v = value_from_longest (type, - unpack_field_as_long (arg_type, - VALUE_CONTENTS (arg1), - fieldno)); + unpack_field_as_long (arg_type, + VALUE_CONTENTS (arg1) + + offset, + fieldno)); 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, + memcpy (VALUE_CONTENTS_RAW (v), + 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) = offset + VALUE_OFFSET (arg1); +/* VALUE_OFFSET (v) = VALUE_OFFSET (arg1) + offset + + TYPE_FIELD_BITPOS (arg_type, fieldno) / 8; */ return v; } /* Given a value ARG1 of a struct or union type, - extract and return the value of one of its fields. - FIELDNO says which field. - - For C++, must also be able to return values from static fields */ + extract and return the value of one of its (non-static) fields. + FIELDNO says which field. */ value_ptr value_field (arg1, fieldno) @@ -842,69 +915,181 @@ value_virtual_fn_field (arg1p, f, j, type, offset) int offset; { value_ptr arg1 = *arg1p; - /* 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) != VALUE_TYPE (arg1)) - arg1 = value_ind (value_cast (context, value_addr (arg1))); - - context = VALUE_TYPE (arg1); - /* 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); - - if (TYPE_CODE (VALUE_TYPE (entry)) == TYPE_CODE_STRUCT) + struct type *type1 = check_typedef (VALUE_TYPE (arg1)); + + 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."); + + /* 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)); */ + + 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 + { /* Not using HP/Taligent runtime conventions; so try to + * use g++ conventions for virtual table */ - if (! VALUE_LAZY (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_primitive_field (arg1, 0, TYPE_VPTR_FIELDNO (context), + TYPE_VPTR_BASETYPE (context)); + + /* With older versions of g++, the vtbl field pointed to an array + of structures. Nowadays it points directly to the structure. */ + if (TYPE_CODE (VALUE_TYPE (vtbl)) == TYPE_CODE_PTR + && TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (vtbl))) == TYPE_CODE_ARRAY) { - VALUE_LAZY (arg1) = 1; - value_fetch_lazy (arg1); + /* Handle the case where the vtbl field points to an + array of structures. */ + vtbl = value_ind (vtbl); + + /* 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); + } + else + { + /* Handle the case where the vtbl field points directly to a structure. */ + vtbl = value_add (vtbl, vi); + entry = value_ind (vtbl); } - vfn = value_field (entry, 2); - } - else if (TYPE_CODE (VALUE_TYPE (entry)) == 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)); + 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)); - *arg1p = arg1; - return vfn; + 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; + } } /* ARG is a pointer to an object we know to be at least @@ -932,7 +1117,7 @@ value_headof (in_arg, btype, dtype) struct minimal_symbol *msymbol; btype = TYPE_VPTR_BASETYPE (dtype); - check_stub_type (btype); + CHECK_TYPEDEF (btype); arg = in_arg; if (btype != dtype) arg = value_cast (lookup_pointer_type (btype), arg); @@ -962,7 +1147,7 @@ value_headof (in_arg, btype, dtype) entry = value_subscript (vtbl, value_from_longest (builtin_type_int, (LONGEST) i)); /* This won't work if we're using thunks. */ - if (TYPE_CODE (VALUE_TYPE (entry)) != TYPE_CODE_STRUCT) + if (TYPE_CODE (check_typedef (VALUE_TYPE (entry))) != TYPE_CODE_STRUCT) break; offset = longest_to_int (value_as_long (value_field (entry, 0))); /* If we use '<=' we can handle single inheritance @@ -1017,7 +1202,7 @@ value_from_vtable_info (arg, type) /* Take care of preliminaries. */ if (TYPE_VPTR_FIELDNO (type) < 0) fill_in_vptr_fieldno (type); - if (TYPE_VPTR_FIELDNO (type) < 0 || VALUE_REPEATED (arg)) + if (TYPE_VPTR_FIELDNO (type) < 0) return 0; return value_headof (arg, 0, type); @@ -1039,7 +1224,7 @@ vb_match (type, index, basetype) if (*name != '_') return 0; /* gcc 2.4 uses _vb$. */ - if (name[1] == 'v' && name[2] == 'b' && name[3] == CPLUS_MARKER) + if (name[1] == 'v' && name[2] == 'b' && is_cplus_marker (name[3])) field_class_name = name + 4; /* gcc 2.5 will use __vb_. */ if (name[1] == '_' && name[2] == 'v' && name[3] == 'b' && name[4] == '_') @@ -1073,19 +1258,19 @@ vb_match (type, index, basetype) } /* Compute the offset of the baseclass which is - the INDEXth baseclass of class TYPE, for a value ARG, - wih extra offset of OFFSET. - The result is the offste of the baseclass value relative + 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. */ int -baseclass_offset (type, index, arg, offset) +baseclass_offset (type, index, valaddr, address) struct type *type; int index; - value_ptr arg; - int offset; + char *valaddr; + CORE_ADDR address; { struct type *basetype = TYPE_BASECLASS (type, index); @@ -1103,22 +1288,16 @@ baseclass_offset (type, index, arg, offset) { CORE_ADDR addr = unpack_pointer (TYPE_FIELD_TYPE (type, i), - VALUE_CONTENTS (arg) + VALUE_OFFSET (arg) - + offset - + (TYPE_FIELD_BITPOS (type, i) / 8)); - - if (VALUE_LVAL (arg) != lval_memory) - return -1; + valaddr + (TYPE_FIELD_BITPOS (type, i) / 8)); - return addr - - (LONGEST) (VALUE_ADDRESS (arg) + VALUE_OFFSET (arg) + offset); + return addr - (LONGEST) address; } } /* Not in the fields, so try looking through the baseclasses. */ for (i = index+1; i < n_baseclasses; i++) { int boffset = - baseclass_offset (type, i, arg, offset); + baseclass_offset (type, i, valaddr, address); if (boffset) return boffset; } @@ -1129,95 +1308,6 @@ baseclass_offset (type, index, arg, offset) /* Baseclass is easily computed. */ return TYPE_BASECLASS_BITPOS (type, index) / 8; } - -/* Compute the address of the baseclass which is - the INDEXth baseclass of class TYPE. The TYPE base - of the object is at VALADDR. - - If ERRP is non-NULL, set *ERRP to be the errno code of any error, - or 0 if no error. In that case the return value is not the address - of the baseclasss, but the address which could not be read - successfully. */ - -/* FIXME Fix remaining uses of baseclass_addr to use baseclass_offset */ - -char * -baseclass_addr (type, index, valaddr, valuep, errp) - struct type *type; - int index; - char *valaddr; - value_ptr *valuep; - int *errp; -{ - struct type *basetype = TYPE_BASECLASS (type, index); - - if (errp) - *errp = 0; - - if (BASETYPE_VIA_VIRTUAL (type, index)) - { - /* Must hunt for the pointer to this virtual baseclass. */ - register int i, len = TYPE_NFIELDS (type); - register int n_baseclasses = TYPE_N_BASECLASSES (type); - - /* First look for the virtual baseclass pointer - in the fields. */ - for (i = n_baseclasses; i < len; i++) - { - if (vb_match (type, i, basetype)) - { - value_ptr val = allocate_value (basetype); - CORE_ADDR addr; - int status; - - addr - = unpack_pointer (TYPE_FIELD_TYPE (type, i), - valaddr + (TYPE_FIELD_BITPOS (type, i) / 8)); - - status = target_read_memory (addr, - VALUE_CONTENTS_RAW (val), - TYPE_LENGTH (basetype)); - VALUE_LVAL (val) = lval_memory; - VALUE_ADDRESS (val) = addr; - - if (status != 0) - { - if (valuep) - *valuep = NULL; - release_value (val); - value_free (val); - if (errp) - *errp = status; - return (char *)addr; - } - else - { - if (valuep) - *valuep = val; - return (char *) VALUE_CONTENTS (val); - } - } - } - /* Not in the fields, so try looking through the baseclasses. */ - for (i = index+1; i < n_baseclasses; i++) - { - char *baddr; - - baddr = baseclass_addr (type, i, valaddr, valuep, errp); - if (baddr) - return baddr; - } - /* Not found. */ - if (valuep) - *valuep = 0; - return 0; - } - - /* Baseclass is easily computed. */ - if (valuep) - *valuep = 0; - return valaddr + TYPE_BASECLASS_BITPOS (type, index) / 8; -} /* Unpack a field FIELDNO of the specified TYPE, from the anonymous object at VALADDR. @@ -1239,13 +1329,16 @@ unpack_field_as_long (type, valaddr, fieldno) char *valaddr; int fieldno; { - unsigned LONGEST val; - unsigned LONGEST valmask; + ULONGEST val; + ULONGEST valmask; int bitpos = TYPE_FIELD_BITPOS (type, fieldno); int bitsize = TYPE_FIELD_BITSIZE (type, fieldno); int lsbcount; + struct type *field_type; val = extract_unsigned_integer (valaddr + bitpos / 8, sizeof (val)); + field_type = TYPE_FIELD_TYPE (type, fieldno); + CHECK_TYPEDEF (field_type); /* Extract bits. See comment above. */ @@ -1258,11 +1351,11 @@ unpack_field_as_long (type, valaddr, fieldno) /* If the field does not entirely fill a LONGEST, then zero the sign bits. If the field is signed, and is negative, then sign extend. */ - if ((bitsize > 0) && (bitsize < 8 * sizeof (val))) + if ((bitsize > 0) && (bitsize < 8 * (int) sizeof (val))) { - valmask = (((unsigned LONGEST) 1) << bitsize) - 1; + valmask = (((ULONGEST) 1) << bitsize) - 1; val &= valmask; - if (!TYPE_UNSIGNED (TYPE_FIELD_TYPE (type, fieldno))) + if (!TYPE_UNSIGNED (field_type)) { if (val & (valmask ^ (valmask >> 1))) { @@ -1286,14 +1379,22 @@ modify_field (addr, fieldval, bitpos, bitsize) { LONGEST oword; - /* Reject values too big to fit in the field in question, - otherwise adjoining fields may be corrupted. */ - if (bitsize < (8 * sizeof (fieldval)) + /* If a negative fieldval fits in the field in question, chop + off the sign extension bits. */ + if (bitsize < (8 * (int) sizeof (fieldval)) + && (~fieldval & ~((1 << (bitsize - 1)) - 1)) == 0) + fieldval = fieldval & ((1 << bitsize) - 1); + + /* Warn if value is too big to fit in the field in question. */ + if (bitsize < (8 * (int) sizeof (fieldval)) && 0 != (fieldval & ~((1<= size of oword */ - if (bitsize < 8 * sizeof (oword)) - oword &= ~(((((unsigned LONGEST)1) << bitsize) - 1) << bitpos); + if (bitsize < 8 * (int) sizeof (oword)) + oword &= ~(((((ULONGEST)1) << bitsize) - 1) << bitpos); else - oword &= ~((~(unsigned LONGEST)0) << bitpos); + oword &= ~((~(ULONGEST)0) << bitpos); oword |= fieldval << bitpos; store_signed_integer (addr, sizeof oword, oword); @@ -1320,11 +1421,17 @@ value_from_longest (type, num) register LONGEST num; { register value_ptr val = allocate_value (type); - register enum type_code code = TYPE_CODE (type); - register int len = TYPE_LENGTH (type); + register enum type_code code; + register int len; + retry: + code = TYPE_CODE (type); + len = TYPE_LENGTH (type); switch (code) { + case TYPE_CODE_TYPEDEF: + type = check_typedef (type); + goto retry; case TYPE_CODE_INT: case TYPE_CODE_CHAR: case TYPE_CODE_ENUM: @@ -1339,9 +1446,9 @@ value_from_longest (type, num) have the same form. */ store_address (VALUE_CONTENTS_RAW (val), len, (CORE_ADDR) num); break; - + default: - error ("Unexpected type encountered for integer constant."); + error ("Unexpected type (%d) encountered for integer constant.", code); } return val; } @@ -1349,11 +1456,12 @@ value_from_longest (type, num) value_ptr value_from_double (type, num) struct type *type; - double num; + DOUBLEST num; { register value_ptr val = allocate_value (type); - register enum type_code code = TYPE_CODE (type); - register int len = TYPE_LENGTH (type); + struct type *base_type = check_typedef (type); + register enum type_code code = TYPE_CODE (base_type); + register int len = TYPE_LENGTH (base_type); if (code == TYPE_CODE_FLT) { @@ -1395,11 +1503,12 @@ value_being_returned (valtype, retbuf, struct_return) addr = EXTRACT_STRUCT_VALUE_ADDRESS (retbuf); if (!addr) error ("Function return value unknown"); - return value_at (valtype, addr); + return value_at (valtype, addr, NULL); } #endif val = allocate_value (valtype); + CHECK_TYPEDEF (valtype); EXTRACT_RETURN_VALUE (valtype, retbuf, VALUE_CONTENTS_RAW (val)); return val; @@ -1419,14 +1528,29 @@ value_being_returned (valtype, retbuf, struct_return) 2.0-2.3.3. This is somewhat unfortunate, but changing gcc2_compiled would cause more chaos than dealing with some struct returns being handled wrong. */ -#if !defined (USE_STRUCT_CONVENTION) -#define USE_STRUCT_CONVENTION(gcc_p, type)\ - (!((gcc_p == 1) && (TYPE_LENGTH (value_type) == 1 \ - || TYPE_LENGTH (value_type) == 2 \ - || TYPE_LENGTH (value_type) == 4 \ - || TYPE_LENGTH (value_type) == 8 \ - ) \ - )) + +int +generic_use_struct_convention (gcc_p, value_type) + int gcc_p; + struct type *value_type; +{ + return !((gcc_p == 1) + && (TYPE_LENGTH (value_type) == 1 + || TYPE_LENGTH (value_type) == 2 + || TYPE_LENGTH (value_type) == 4 + || TYPE_LENGTH (value_type) == 8)); +} + +#ifndef USE_STRUCT_CONVENTION +#define USE_STRUCT_CONVENTION(gcc_p,type) generic_use_struct_convention (gcc_p, type) +#endif + +/* Some fundamental types (such as long double) are returned on the stack for + certain architectures. This macro should return true for any type besides + struct, union or array that gets returned on the stack. */ + +#ifndef RETURN_VALUE_ON_STACK +#define RETURN_VALUE_ON_STACK(TYPE) 0 #endif /* Return true if the function specified is using the structure returning @@ -1449,9 +1573,10 @@ using_struct_return (function, funcaddr, value_type, gcc_p) if (code == TYPE_CODE_ERROR) error ("Function return type unknown."); - if (code == TYPE_CODE_STRUCT || - code == TYPE_CODE_UNION || - code == TYPE_CODE_ARRAY) + if (code == TYPE_CODE_STRUCT + || code == TYPE_CODE_UNION + || code == TYPE_CODE_ARRAY + || RETURN_VALUE_ON_STACK (value_type)) return USE_STRUCT_CONVENTION (gcc_p, value_type); return 0; @@ -1465,9 +1590,8 @@ void set_return_value (val) value_ptr val; { - register enum type_code code = TYPE_CODE (VALUE_TYPE (val)); - double dbuf; - LONGEST lbuf; + struct type *type = check_typedef (VALUE_TYPE (val)); + register enum type_code code = TYPE_CODE (type); if (code == TYPE_CODE_ERROR) error ("Function return type unknown."); @@ -1476,19 +1600,7 @@ set_return_value (val) || code == TYPE_CODE_UNION) /* FIXME, implement struct return. */ error ("GDB does not support specifying a struct or union return value."); - /* FIXME, this is bogus. We don't know what the return conventions - are, or how values should be promoted.... */ - if (code == TYPE_CODE_FLT) - { - dbuf = value_as_double (val); - - STORE_RETURN_VALUE (VALUE_TYPE (val), (char *)&dbuf); - } - else - { - lbuf = value_as_long (val); - STORE_RETURN_VALUE (VALUE_TYPE (val), (char *)&lbuf); - } + STORE_RETURN_VALUE (type, VALUE_CONTENTS (val)); } void