X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fvalues.c;h=c399f8b69c8a444fc5252116fdacf4b4dc4bb303;hb=2c320e35984957fbca00f3bad8cea39bc75f4c49;hp=ce0bc45f449eb7273320f43bdd406ee07f5b9a75;hpb=96b2f51cdce670745f5d159680892945b33c7ac6;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/values.c b/gdb/values.c index ce0bc45f44..c399f8b69c 100644 --- a/gdb/values.c +++ b/gdb/values.c @@ -1,5 +1,5 @@ -/* Low level packing and unpacking of values for GDB. - Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc. +/* Low level packing and unpacking of values for GDB, the GNU Debugger. + Copyright 1986, 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GDB. @@ -17,19 +17,28 @@ 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. */ -#include -#include #include "defs.h" -#include "param.h" +#include #include "symtab.h" +#include "gdbtypes.h" #include "value.h" #include "gdbcore.h" #include "frame.h" #include "command.h" #include "gdbcmd.h" +#include "target.h" +#include "demangle.h" + +/* Local function prototypes. */ + +static value +value_headof PARAMS ((value, struct type *, struct type *)); + +static void +show_values PARAMS ((char *, int)); -extern char *cplus_demangle (); -extern char *cplus_mangle_opname (); +static void +show_convenience PARAMS ((char *, int)); /* The value-history records all the values printed by print commands during this session. Each chunk @@ -184,7 +193,7 @@ release_value (val) It contains the same contents, for same memory address, but it's a different block of storage. */ -static value +value value_copy (arg) value arg; { @@ -203,9 +212,9 @@ value_copy (arg) VALUE_LAZY (val) = VALUE_LAZY (arg); if (!VALUE_LAZY (val)) { - bcopy (VALUE_CONTENTS_RAW (arg), VALUE_CONTENTS_RAW (val), - TYPE_LENGTH (VALUE_TYPE (arg)) - * (VALUE_REPEATED (arg) ? VALUE_REPETITIONS (arg) : 1)); + memcpy (VALUE_CONTENTS_RAW (val), VALUE_CONTENTS_RAW (arg), + TYPE_LENGTH (VALUE_TYPE (arg)) + * (VALUE_REPEATED (arg) ? VALUE_REPETITIONS (arg) : 1)); } return val; } @@ -225,10 +234,11 @@ record_latest_value (val) /* 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) { - (void) unpack_double (VALUE_TYPE (val), VALUE_CONTENTS (val), &i); - if (i) return -1; /* Indicate value not saved in history */ - } + 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 */ + } /* Here we treat value_history_count as origin-zero and applying to the value being stored now. */ @@ -239,7 +249,7 @@ record_latest_value (val) register struct value_history_chunk *new = (struct value_history_chunk *) xmalloc (sizeof (struct value_history_chunk)); - bzero (new->values, sizeof new->values); + memset (new->values, 0, sizeof new->values); new->next = value_history_chain; value_history_chain = new; } @@ -304,10 +314,10 @@ clear_value_history () while (value_history_chain) { for (i = 0; i < VALUE_HISTORY_CHUNK; i++) - if (val = value_history_chain->values[i]) - free (val); + if ((val = value_history_chain->values[i]) != NULL) + free ((PTR)val); next = value_history_chain->next; - free (value_history_chain); + free ((PTR)value_history_chain); value_history_chain = next; } value_history_count = 0; @@ -381,11 +391,11 @@ lookup_internalvar (name) register struct internalvar *var; for (var = internalvars; var; var = var->next) - if (!strcmp (var->name, name)) + if (STREQ (var->name, name)) return var; var = (struct internalvar *) xmalloc (sizeof (struct internalvar)); - var->name = concat (name, "", ""); + var->name = concat (name, NULL); var->value = allocate_value (builtin_type_void); release_value (var->value); var->next = internalvars; @@ -429,8 +439,7 @@ set_internalvar_component (var, offset, bitpos, bitsize, newval) modify_field (addr, (int) value_as_long (newval), bitpos, bitsize); else - bcopy (VALUE_CONTENTS (newval), addr, - TYPE_LENGTH (VALUE_TYPE (newval))); + memcpy (addr, VALUE_CONTENTS (newval), TYPE_LENGTH (VALUE_TYPE (newval))); } void @@ -443,8 +452,13 @@ set_internalvar (var, val) SET_TRAPPED_INTERNALVAR (var, val, 0, 0, 0); #endif - free (var->value); + free ((PTR)var->value); var->value = value_copy (val); + /* 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 + has changed. */ + if (VALUE_LAZY (var->value)) + value_fetch_lazy (var->value); release_value (var->value); } @@ -467,14 +481,16 @@ clear_internalvars () { var = internalvars; internalvars = var->next; - free (var->name); - free (var->value); - free (var); + free ((PTR)var->name); + free ((PTR)var->value); + free ((PTR)var); } } static void -show_convenience () +show_convenience (ignore, from_tty) + char *ignore; + int from_tty; { register struct internalvar *var; int varseen = 0; @@ -487,15 +503,11 @@ show_convenience () #endif if (!varseen) { -#if 0 - /* Useless noise. */ - printf ("Debugger convenience variables:\n\n"); -#endif varseen = 1; } - printf ("$%s = ", var->name); + printf_filtered ("$%s = ", var->name); value_print (var->value, stdout, 0, Val_pretty_default); - printf ("\n"); + printf_filtered ("\n"); } if (!varseen) printf ("No debugger convenience variables now defined.\n\ @@ -540,7 +552,7 @@ value_as_pointer (val) { /* Assume a CORE_ADDR can fit in a LONGEST (for now). Not sure whether we want this to be true eventually. */ - return value_as_long (val); + return ADDR_BITS_REMOVE(value_as_long (val)); } /* Unpack raw data (copied from debugee, target byte order) at VALADDR @@ -557,6 +569,9 @@ value_as_pointer (val) to member which reaches here is considered to be equivalent to an INT (or some size). After all, it is only an offset. */ +/* FIXME: This should be rewritten as a switch statement for speed and + ease of comprehension. */ + LONGEST unpack_long (type, valaddr) struct type *type; @@ -566,14 +581,14 @@ unpack_long (type, valaddr) register int len = TYPE_LENGTH (type); register int nosign = TYPE_UNSIGNED (type); - if (code == TYPE_CODE_ENUM) + if (code == TYPE_CODE_ENUM || code == TYPE_CODE_BOOL) code = TYPE_CODE_INT; if (code == TYPE_CODE_FLT) { if (len == sizeof (float)) { float retval; - bcopy (valaddr, &retval, sizeof (retval)); + memcpy (&retval, valaddr, sizeof (retval)); SWAP_TARGET_AND_HOST (&retval, sizeof (retval)); return retval; } @@ -581,7 +596,7 @@ unpack_long (type, valaddr) if (len == sizeof (double)) { double retval; - bcopy (valaddr, &retval, sizeof (retval)); + memcpy (&retval, valaddr, sizeof (retval)); SWAP_TARGET_AND_HOST (&retval, sizeof (retval)); return retval; } @@ -602,7 +617,7 @@ unpack_long (type, valaddr) if (len == sizeof (short)) { unsigned short retval; - bcopy (valaddr, &retval, sizeof (retval)); + memcpy (&retval, valaddr, sizeof (retval)); SWAP_TARGET_AND_HOST (&retval, sizeof (retval)); return retval; } @@ -610,7 +625,7 @@ unpack_long (type, valaddr) if (len == sizeof (int)) { unsigned int retval; - bcopy (valaddr, &retval, sizeof (retval)); + memcpy (&retval, valaddr, sizeof (retval)); SWAP_TARGET_AND_HOST (&retval, sizeof (retval)); return retval; } @@ -618,7 +633,7 @@ unpack_long (type, valaddr) if (len == sizeof (long)) { unsigned long retval; - bcopy (valaddr, &retval, sizeof (retval)); + memcpy (&retval, valaddr, sizeof (retval)); SWAP_TARGET_AND_HOST (&retval, sizeof (retval)); return retval; } @@ -626,7 +641,7 @@ unpack_long (type, valaddr) if (len == sizeof (long long)) { unsigned long long retval; - bcopy (valaddr, &retval, sizeof (retval)); + memcpy (&retval, valaddr, sizeof (retval)); SWAP_TARGET_AND_HOST (&retval, sizeof (retval)); return retval; } @@ -640,8 +655,8 @@ unpack_long (type, valaddr) { if (len == sizeof (char)) { - char retval; - bcopy (valaddr, &retval, sizeof (retval)); + SIGNED char retval; /* plain chars might be unsigned on host */ + memcpy (&retval, valaddr, sizeof (retval)); SWAP_TARGET_AND_HOST (&retval, sizeof (retval)); return retval; } @@ -649,7 +664,7 @@ unpack_long (type, valaddr) if (len == sizeof (short)) { short retval; - bcopy (valaddr, &retval, sizeof (retval)); + memcpy (&retval, valaddr, sizeof (retval)); SWAP_TARGET_AND_HOST (&retval, sizeof (retval)); return retval; } @@ -657,7 +672,7 @@ unpack_long (type, valaddr) if (len == sizeof (int)) { int retval; - bcopy (valaddr, &retval, sizeof (retval)); + memcpy (&retval, valaddr, sizeof (retval)); SWAP_TARGET_AND_HOST (&retval, sizeof (retval)); return retval; } @@ -665,7 +680,7 @@ unpack_long (type, valaddr) if (len == sizeof (long)) { long retval; - bcopy (valaddr, &retval, sizeof (retval)); + memcpy (&retval, valaddr, sizeof (retval)); SWAP_TARGET_AND_HOST (&retval, sizeof (retval)); return retval; } @@ -674,7 +689,7 @@ unpack_long (type, valaddr) if (len == sizeof (long long)) { long long retval; - bcopy (valaddr, &retval, sizeof (retval)); + memcpy (&retval, valaddr, sizeof (retval)); SWAP_TARGET_AND_HOST (&retval, sizeof (retval)); return retval; } @@ -686,19 +701,27 @@ unpack_long (type, valaddr) } /* Assume a CORE_ADDR can fit in a LONGEST (for now). Not sure whether we want this to be true eventually. */ - else if (code == TYPE_CODE_PTR - || code == TYPE_CODE_REF) + else if (code == TYPE_CODE_PTR || code == TYPE_CODE_REF) { - if (len == sizeof (CORE_ADDR)) - { - CORE_ADDR retval; - bcopy (valaddr, &retval, sizeof (retval)); - SWAP_TARGET_AND_HOST (&retval, sizeof (retval)); - return retval; - } + if (len == sizeof(long)) + { + unsigned long retval; + memcpy (&retval, valaddr, sizeof(retval)); + SWAP_TARGET_AND_HOST (&retval, sizeof(retval)); + return retval; + } + else if (len == sizeof(short)) + { + unsigned short retval; + memcpy (&retval, valaddr, len); + SWAP_TARGET_AND_HOST (&retval, len); + return retval; + } } else if (code == TYPE_CODE_MEMBER) error ("not implemented: member types in unpack_long"); + else if (code == TYPE_CODE_CHAR) + return *(unsigned char *)valaddr; error ("Value not integer or pointer."); return 0; /* For lint -- never reached */ @@ -732,7 +755,7 @@ unpack_double (type, valaddr, invp) if (len == sizeof (float)) { float retval; - bcopy (valaddr, &retval, sizeof (retval)); + memcpy (&retval, valaddr, sizeof (retval)); SWAP_TARGET_AND_HOST (&retval, sizeof (retval)); return retval; } @@ -740,7 +763,7 @@ unpack_double (type, valaddr, invp) if (len == sizeof (double)) { double retval; - bcopy (valaddr, &retval, sizeof (retval)); + memcpy (&retval, valaddr, sizeof (retval)); SWAP_TARGET_AND_HOST (&retval, sizeof (retval)); return retval; } @@ -793,7 +816,7 @@ unpack_pointer (type, valaddr) if (len == sizeof (CORE_ADDR)) { CORE_ADDR retval; - bcopy (valaddr, &retval, sizeof (retval)); + memcpy (&retval, valaddr, sizeof (retval)); SWAP_TARGET_AND_HOST (&retval, sizeof (retval)); return retval; } @@ -849,9 +872,8 @@ value_primitive_field (arg1, offset, fieldno, arg_type) if (VALUE_LAZY (arg1)) VALUE_LAZY (v) = 1; else - bcopy (VALUE_CONTENTS_RAW (arg1) + offset, - VALUE_CONTENTS_RAW (v), - TYPE_LENGTH (type)); + memcpy (VALUE_CONTENTS_RAW (v), VALUE_CONTENTS_RAW (arg1) + offset, + TYPE_LENGTH (type)); } VALUE_LVAL (v) = VALUE_LVAL (arg1); if (VALUE_LVAL (arg1) == lval_internalvar) @@ -875,43 +897,61 @@ value_field (arg1, fieldno) return value_primitive_field (arg1, 0, fieldno, VALUE_TYPE (arg1)); } +/* Return a non-virtual function as a value. + F is the list of member functions which contains the desired method. + J is an index into F which provides the desired method. */ + value -value_fn_field (arg1, fieldno, subfieldno) - register value arg1; - register int fieldno; - int subfieldno; +value_fn_field (arg1p, f, j, type, offset) + value *arg1p; + struct fn_field *f; + int j; + struct type *type; + int offset; { register value v; - struct fn_field *f = TYPE_FN_FIELDLIST1 (VALUE_TYPE (arg1), fieldno); - register struct type *type = TYPE_FN_FIELD_TYPE (f, subfieldno); + register struct type *ftype = TYPE_FN_FIELD_TYPE (f, j); struct symbol *sym; - sym = lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, subfieldno), + sym = lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, j), 0, VAR_NAMESPACE, 0, NULL); if (! sym) error ("Internal error: could not find physical method named %s", - TYPE_FN_FIELD_PHYSNAME (f, subfieldno)); + TYPE_FN_FIELD_PHYSNAME (f, j)); - v = allocate_value (type); + v = allocate_value (ftype); VALUE_ADDRESS (v) = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)); - VALUE_TYPE (v) = type; + VALUE_TYPE (v) = ftype; + + if (arg1p) + { + if (type != VALUE_TYPE (*arg1p)) + *arg1p = value_ind (value_cast (lookup_pointer_type (type), + value_addr (*arg1p))); + + /* Move the `this' pointer according to the offset. */ + VALUE_OFFSET (*arg1p) += offset; + } + return v; } /* Return a virtual function as a value. ARG1 is the object which provides the virtual function - table pointer. ARG1 is side-effected in calling this function. + table pointer. *ARG1P is side-effected in calling this function. F is the list of member functions which contains the desired virtual function. J is an index into F which provides the desired virtual function. TYPE is the type in which F is located. */ value -value_virtual_fn_field (arg1, f, j, type) - value arg1; +value_virtual_fn_field (arg1p, f, j, type, offset) + value *arg1p; struct fn_field *f; int j; struct type *type; + int offset; { + value 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 @@ -943,7 +983,9 @@ value_virtual_fn_field (arg1, f, j, type) /* The virtual function table is now an array of structures which have the form { int16 offset, delta; void *pfn; }. */ - vtbl = value_ind (value_field (arg1, TYPE_VPTR_FIELDNO (context))); + 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 @@ -952,7 +994,7 @@ value_virtual_fn_field (arg1, f, j, type) entry = value_subscript (vtbl, vi); /* Move the `this' pointer according to the virtual function table. */ - VALUE_OFFSET (arg1) += value_as_long (value_field (entry, 0)); + VALUE_OFFSET (arg1) += value_as_long (value_field (entry, 0)) + offset; if (! VALUE_LAZY (arg1)) { VALUE_LAZY (arg1) = 1; @@ -963,6 +1005,7 @@ value_virtual_fn_field (arg1, f, j, 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; } @@ -983,13 +1026,12 @@ value_headof (arg, btype, dtype) /* First collect the vtables we must look at for this object. */ /* FIXME-tiemann: right now, just look at top-most vtable. */ value vtbl, entry, best_entry = 0; - /* FIXME: entry_type is never used. */ - struct type *entry_type; int i, nelems; int offset, best_offset = 0; struct symbol *sym; CORE_ADDR pc_for_sym; char *demangled_name; + struct minimal_symbol *msymbol; btype = TYPE_VPTR_BASETYPE (dtype); check_stub_type (btype); @@ -1000,14 +1042,15 @@ value_headof (arg, btype, dtype) vtbl = value_ind (value_field (value_ind (vtbl), TYPE_VPTR_FIELDNO (btype))); /* Check that VTBL looks like it points to a virtual function table. */ - i = find_pc_misc_function (VALUE_ADDRESS (vtbl)); - if (i < 0 || ! VTBL_PREFIX_P (misc_function_vector[i].name)) + msymbol = lookup_minimal_symbol_by_pc (VALUE_ADDRESS (vtbl)); + if (msymbol == NULL + || !VTBL_PREFIX_P (demangled_name = SYMBOL_NAME (msymbol))) { /* If we expected to find a vtable, but did not, let the user know that we aren't happy, but don't throw an error. FIXME: there has to be a better way to do this. */ struct type *error_type = (struct type *)xmalloc (sizeof (struct type)); - bcopy (VALUE_TYPE (arg), error_type, sizeof (struct type)); + memcpy (error_type, VALUE_TYPE (arg), sizeof (struct type)); TYPE_NAME (error_type) = savestring ("suspicious *", sizeof ("suspicious *")); VALUE_TYPE (arg) = error_type; return arg; @@ -1021,27 +1064,40 @@ value_headof (arg, btype, dtype) entry = value_subscript (vtbl, value_from_longest (builtin_type_int, (LONGEST) i)); offset = longest_to_int (value_as_long (value_field (entry, 0))); - if (offset < best_offset) + /* If we use '<=' we can handle single inheritance + * where all offsets are zero - just use the first entry found. */ + if (offset <= best_offset) { best_offset = offset; best_entry = entry; } } - if (best_entry == 0) - return arg; - /* Move the pointer according to BEST_ENTRY's offset, and figure out what type we should return as the new pointer. */ - pc_for_sym = value_as_pointer (value_field (best_entry, 2)); - sym = find_pc_function (pc_for_sym); - demangled_name = cplus_demangle (SYMBOL_NAME (sym), -1); - *(strchr (demangled_name, ':')) = '\0'; + if (best_entry == 0) + { + /* An alternative method (which should no longer be necessary). + * But we leave it in for future use, when we will hopefully + * have optimizes the vtable to use thunks instead of offsets. */ + /* Use the name of vtable itself to extract a base type. */ + demangled_name += 4; /* Skip _vt$ prefix. */ + } + else + { + pc_for_sym = value_as_pointer (value_field (best_entry, 2)); + sym = find_pc_function (pc_for_sym); + demangled_name = cplus_demangle (SYMBOL_NAME (sym), DMGL_ANSI); + *(strchr (demangled_name, ':')) = '\0'; + } sym = lookup_symbol (demangled_name, 0, VAR_NAMESPACE, 0, 0); - if (sym == 0) - error ("could not find type declaration for `%s'", SYMBOL_NAME (sym)); - free (demangled_name); - arg = value_add (value_cast (builtin_type_int, arg), - value_field (best_entry, 0)); + if (sym == NULL) + error ("could not find type declaration for `%s'", demangled_name); + if (best_entry) + { + free (demangled_name); + arg = value_add (value_cast (builtin_type_int, arg), + value_field (best_entry, 0)); + } VALUE_TYPE (arg) = lookup_pointer_type (SYMBOL_TYPE (sym)); return arg; } @@ -1065,72 +1121,69 @@ value_from_vtable_info (arg, type) return value_headof (arg, 0, type); } -/* The value of a static class member does not depend - on its instance, only on its type. If FIELDNO >= 0, - then fieldno is a valid field number and is used directly. - Otherwise, FIELDNAME is the name of the field we are - searching for. If it is not a static field name, an - error is signaled. TYPE is the type in which we look for the - static field member. +/* 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 + to (the address of)(ARG) + OFFSET. - Return zero if we couldn't find anything; the caller may signal - an error in that case. */ + -1 is returned on error. */ -value -value_static_field (type, fieldname, fieldno) - register struct type *type; - char *fieldname; - register int fieldno; +int +baseclass_offset (type, index, arg, offset) + struct type *type; + int index; + value arg; + int offset; { - register value v; - struct symbol *sym; - char *phys_name; + struct type *basetype = TYPE_BASECLASS (type, index); - if (fieldno < 0) + if (BASETYPE_VIA_VIRTUAL (type, index)) { - /* Look for static field. */ - int i; - for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--) - if (! strcmp (TYPE_FIELD_NAME (type, i), fieldname)) - { - if (TYPE_FIELD_STATIC (type, i)) - { - fieldno = i; - goto found; - } - else - error ("field `%s' is not static", fieldname); - } - for (; i > 0; i--) + /* Must hunt for the pointer to this virtual baseclass. */ + register int i, len = TYPE_NFIELDS (type); + register int n_baseclasses = TYPE_N_BASECLASSES (type); + char *vbase_name, *type_name = type_name_no_tag (basetype); + + vbase_name = (char *)alloca (strlen (type_name) + 8); + sprintf (vbase_name, "_vb%c%s", CPLUS_MARKER, type_name); + /* First look for the virtual baseclass pointer + in the fields. */ + for (i = n_baseclasses; i < len; i++) { - v = value_static_field (TYPE_BASECLASS (type, i), fieldname, -1); - if (v != 0) - return v; - } + if (STREQ (vbase_name, TYPE_FIELD_NAME (type, i))) + { + CORE_ADDR addr + = unpack_pointer (TYPE_FIELD_TYPE (type, i), + VALUE_CONTENTS (arg) + VALUE_OFFSET (arg) + + offset + + (TYPE_FIELD_BITPOS (type, i) / 8)); - if (destructor_name_p (fieldname, type)) - error ("Cannot get value of destructor"); + if (VALUE_LVAL (arg) != lval_memory) + return -1; - for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; i--) + return addr - + (LONGEST) (VALUE_ADDRESS (arg) + VALUE_OFFSET (arg) + offset); + } + } + /* Not in the fields, so try looking through the baseclasses. */ + for (i = index+1; i < n_baseclasses; i++) { - if (! strcmp (TYPE_FN_FIELDLIST_NAME (type, i), fieldname)) - error ("Cannot get value of method \"%s\"", fieldname); + int boffset = + baseclass_offset (type, i, arg, offset); + if (boffset) + return boffset; } - error("there is no field named %s", fieldname); + /* Not found. */ + return -1; } - found: - phys_name = TYPE_FIELD_STATIC_PHYSNAME (type, fieldno); - sym = lookup_symbol (phys_name, 0, VAR_NAMESPACE, 0, NULL); - if (! sym) error ("Internal error: could not find physical static variable named %s", phys_name); - - type = TYPE_FIELD_TYPE (type, fieldno); - v = value_at (type, (CORE_ADDR)SYMBOL_BLOCK_VALUE (sym)); - return v; + /* Baseclass is easily computed. */ + return TYPE_BASECLASS_BITPOS (type, index) / 8; } /* Compute the address of the baseclass which is - the INDEXth baseclass of TYPE. The TYPE base + 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, @@ -1138,6 +1191,8 @@ value_static_field (type, fieldname, fieldno) 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; @@ -1158,16 +1213,13 @@ baseclass_addr (type, index, valaddr, valuep, errp) register int n_baseclasses = TYPE_N_BASECLASSES (type); char *vbase_name, *type_name = type_name_no_tag (basetype); - if (TYPE_MAIN_VARIANT (basetype)) - basetype = TYPE_MAIN_VARIANT (basetype); - vbase_name = (char *)alloca (strlen (type_name) + 8); - sprintf (vbase_name, "_vb$%s", type_name); + sprintf (vbase_name, "_vb%c%s", CPLUS_MARKER, type_name); /* First look for the virtual baseclass pointer in the fields. */ for (i = n_baseclasses; i < len; i++) { - if (! strcmp (vbase_name, TYPE_FIELD_NAME (type, i))) + if (STREQ (vbase_name, TYPE_FIELD_NAME (type, i))) { value val = allocate_value (basetype); CORE_ADDR addr; @@ -1221,140 +1273,61 @@ baseclass_addr (type, index, valaddr, valuep, errp) *valuep = 0; return valaddr + TYPE_BASECLASS_BITPOS (type, index) / 8; } + +/* Unpack a field FIELDNO of the specified TYPE, from the anonymous object at + VALADDR. -/* Ugly hack to convert method stubs into method types. - - He ain't kiddin'. This demangles the name of the method into a string - including argument types, parses out each argument type, generates - a string casting a zero to that type, evaluates the string, and stuffs - the resulting type into an argtype vector!!! Then it knows the type - of the whole function (including argument types for overloading), - which info used to be in the stab's but was removed to hack back - the space required for them. */ -void -check_stub_method (type, i, j) - struct type *type; - int i, j; -{ - extern char *gdb_mangle_typename (), *strchr (); - struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i); - char *field_name = TYPE_FN_FIELDLIST_NAME (type, i); - char *inner_name = gdb_mangle_typename (type); - int mangled_name_len = (strlen (field_name) - + strlen (inner_name) - + strlen (TYPE_FN_FIELD_PHYSNAME (f, j)) - + 1); - char *mangled_name; - char *demangled_name; - char *argtypetext, *p; - int depth = 0, argcount = 1; - struct type **argtypes; - - if (OPNAME_PREFIX_P (field_name)) - { - char *opname = cplus_mangle_opname (field_name + 3); - if (opname == NULL) - error ("No mangling for \"%s\"", field_name); - mangled_name_len += strlen (opname); - mangled_name = (char *)xmalloc (mangled_name_len); - - strncpy (mangled_name, field_name, 3); - mangled_name[3] = '\0'; - strcat (mangled_name, opname); - } - else - { - mangled_name = (char *)xmalloc (mangled_name_len); - strcpy (mangled_name, TYPE_FN_FIELDLIST_NAME (type, i)); - } - strcat (mangled_name, inner_name); - strcat (mangled_name, TYPE_FN_FIELD_PHYSNAME (f, j)); - demangled_name = cplus_demangle (mangled_name, 0); - - /* Now, read in the parameters that define this type. */ - argtypetext = strchr (demangled_name, '(') + 1; - p = argtypetext; - while (*p) - { - if (*p == '(') - depth += 1; - else if (*p == ')') - depth -= 1; - else if (*p == ',' && depth == 0) - argcount += 1; - - p += 1; - } - /* We need one more slot for the void [...] or NULL [end of arglist] */ - argtypes = (struct type **)xmalloc ((argcount+1) * sizeof (struct type *)); - p = argtypetext; - argtypes[0] = lookup_pointer_type (type); - argcount = 1; - - if (*p != ')') /* () means no args, skip while */ - { - while (*p) - { - if (*p == '(') - depth += 1; - else if (*p == ')') - depth -= 1; - - if (depth <= 0 && (*p == ',' || *p == ')')) - { - char *tmp = (char *)alloca (p - argtypetext + 4); - value val; - tmp[0] = '('; - bcopy (argtypetext, tmp+1, p - argtypetext); - tmp[p-argtypetext+1] = ')'; - tmp[p-argtypetext+2] = '0'; - tmp[p-argtypetext+3] = '\0'; - val = parse_and_eval (tmp); - argtypes[argcount] = VALUE_TYPE (val); - argcount += 1; - argtypetext = p + 1; - } - p += 1; - } - } - - if (p[-2] != '.') /* ... */ - argtypes[argcount] = builtin_type_void; /* Ellist terminator */ - else - argtypes[argcount] = NULL; /* List terminator */ + Extracting bits depends on endianness of the machine. Compute the + number of least significant bits to discard. For big endian machines, + we compute the total number of bits in the anonymous object, subtract + off the bit count from the MSB of the object to the MSB of the + bitfield, then the size of the bitfield, which leaves the LSB discard + count. For little endian machines, the discard count is simply the + number of bits from the LSB of the anonymous object to the LSB of the + bitfield. - free (demangled_name); + If the field is signed, we also do sign extension. */ - type = lookup_method_type (type, TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)), argtypes); - /* Free the stub type...it's no longer needed. */ - free (TYPE_FN_FIELD_TYPE (f, j)); - TYPE_FN_FIELD_PHYSNAME (f, j) = mangled_name; - TYPE_FN_FIELD_TYPE (f, j) = type; -} - -long +LONGEST unpack_field_as_long (type, valaddr, fieldno) struct type *type; char *valaddr; int fieldno; { - long val; + unsigned LONGEST val; + unsigned LONGEST valmask; int bitpos = TYPE_FIELD_BITPOS (type, fieldno); int bitsize = TYPE_FIELD_BITSIZE (type, fieldno); + int lsbcount; + + memcpy (&val, valaddr + bitpos / 8, sizeof (val)); + SWAP_TARGET_AND_HOST (&val, sizeof (val)); - bcopy (valaddr + bitpos / 8, &val, sizeof val); - SWAP_TARGET_AND_HOST (&val, sizeof val); + /* Extract bits. See comment above. */ - /* Extracting bits depends on endianness of the machine. */ #if BITS_BIG_ENDIAN - val = val >> (sizeof val * 8 - bitpos % 8 - bitsize); + lsbcount = (sizeof val * 8 - bitpos % 8 - bitsize); #else - val = val >> (bitpos % 8); + lsbcount = (bitpos % 8); #endif + val >>= lsbcount; - if (bitsize < 8 * sizeof (val)) - val &= (((unsigned long)1) << bitsize) - 1; - return val; + /* 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))) + { + valmask = (((unsigned LONGEST) 1) << bitsize) - 1; + val &= valmask; + if (!TYPE_UNSIGNED (TYPE_FIELD_TYPE (type, fieldno))) + { + if (val & (valmask ^ (valmask >> 1))) + { + val |= ~valmask; + } + } + } + return (val); } /* Modify the value of a bitfield. ADDR points to a block of memory in @@ -1376,7 +1349,7 @@ modify_field (addr, fieldval, bitpos, bitsize) && 0 != (fieldval & ~((1<