X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fvalues.c;h=da5c18022d6a5bdd3acee6d6851c08ba9f45ff46;hb=92ad9cd90faf2b59f2434c8f706902df65ee5c2d;hp=0ce7dfdccd6d57054e17854f6c72dc70f267d67a;hpb=e9be73e47f3f6d7b88e4ff14cacc7d9e49b73de3;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/values.c b/gdb/values.c index 0ce7dfdccd..da5c18022d 100644 --- a/gdb/values.c +++ b/gdb/values.c @@ -36,6 +36,7 @@ #include "doublest.h" #include "gdb_assert.h" #include "regcache.h" +#include "block.h" /* Prototypes for exported functions. */ @@ -89,7 +90,7 @@ allocate_value (struct type *type) VALUE_ENCLOSING_TYPE (val) = type; VALUE_LVAL (val) = not_lval; VALUE_ADDRESS (val) = 0; - VALUE_FRAME (val) = 0; + VALUE_FRAME_ID (val) = null_frame_id; VALUE_OFFSET (val) = 0; VALUE_BITPOS (val) = 0; VALUE_BITSIZE (val) = 0; @@ -213,7 +214,7 @@ value_release_to_mark (struct value *mark) struct value * value_copy (struct value *arg) { - register struct type *encl_type = VALUE_ENCLOSING_TYPE (arg); + struct type *encl_type = VALUE_ENCLOSING_TYPE (arg); struct value *val = allocate_value (encl_type); VALUE_TYPE (val) = VALUE_TYPE (arg); VALUE_LVAL (val) = VALUE_LVAL (arg); @@ -221,7 +222,7 @@ value_copy (struct value *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_FRAME_ID (val) = VALUE_FRAME_ID (arg); VALUE_REGNO (val) = VALUE_REGNO (arg); VALUE_LAZY (val) = VALUE_LAZY (arg); VALUE_OPTIMIZED_OUT (val) = VALUE_OPTIMIZED_OUT (arg); @@ -290,8 +291,8 @@ struct value * access_value_history (int num) { struct value_history_chunk *chunk; - register int i; - register int absnum = num; + int i; + int absnum = num; if (absnum <= 0) absnum += value_history_count; @@ -328,7 +329,7 @@ void clear_value_history (void) { struct value_history_chunk *next; - register int i; + int i; struct value *val; while (value_history_chain) @@ -346,7 +347,7 @@ clear_value_history (void) static void show_values (char *num_exp, int from_tty) { - register int i; + int i; struct value *val; static int num = 1; @@ -403,10 +404,10 @@ static struct internalvar *internalvars; struct internalvar * lookup_internalvar (char *name) { - register struct internalvar *var; + struct internalvar *var; for (var = internalvars; var; var = var->next) - if (STREQ (var->name, name)) + if (strcmp (var->name, name) == 0) return var; var = (struct internalvar *) xmalloc (sizeof (struct internalvar)); @@ -435,7 +436,7 @@ void set_internalvar_component (struct internalvar *var, int offset, int bitpos, int bitsize, struct value *newval) { - register char *addr = VALUE_CONTENTS (var->value) + offset; + char *addr = VALUE_CONTENTS (var->value) + offset; if (bitsize) modify_field (addr, value_as_long (newval), @@ -482,7 +483,7 @@ internalvar_name (struct internalvar *var) void clear_internalvars (void) { - register struct internalvar *var; + struct internalvar *var; while (internalvars) { @@ -497,7 +498,7 @@ clear_internalvars (void) static void show_convenience (char *ignore, int from_tty) { - register struct internalvar *var; + struct internalvar *var; int varseen = 0; for (var = internalvars; var; var = var->next) @@ -663,9 +664,9 @@ value_as_address (struct value *val) LONGEST unpack_long (struct type *type, const char *valaddr) { - register enum type_code code = TYPE_CODE (type); - register int len = TYPE_LENGTH (type); - register int nosign = TYPE_UNSIGNED (type); + enum type_code code = TYPE_CODE (type); + int len = TYPE_LENGTH (type); + int nosign = TYPE_UNSIGNED (type); if (current_language->la_language == language_scm && is_scmvalue_type (type)) @@ -738,7 +739,14 @@ unpack_double (struct type *type, const char *valaddr, int *invp) also not defined either. Oops! Hopefully someone will add both the missing floatformat - definitions and floatformat_is_invalid() function. */ + definitions and the new cases for floatformat_is_valid (). */ + + if (!floatformat_is_valid (floatformat_from_type (type), valaddr)) + { + *invp = 1; + return 0.0; + } + return extract_typed_floating (valaddr, type); } else if (nosign) @@ -793,7 +801,7 @@ value_static_field (struct type *type, int fieldno) else { char *phys_name = TYPE_FIELD_STATIC_PHYSNAME (type, fieldno); - struct symbol *sym = lookup_symbol (phys_name, 0, VAR_NAMESPACE, 0, NULL); + struct symbol *sym = lookup_symbol (phys_name, 0, VAR_DOMAIN, 0, NULL); if (sym == NULL) { /* With some compilers, e.g. HP aCC, static data members are reported @@ -875,10 +883,10 @@ value_change_enclosing_type (struct value *val, struct type *new_encl_type) struct value * value_primitive_field (struct value *arg1, int offset, - register int fieldno, register struct type *arg_type) + int fieldno, struct type *arg_type) { struct value *v; - register struct type *type; + struct type *type; CHECK_TYPEDEF (arg_type); type = TYPE_FIELD_TYPE (arg_type, fieldno); @@ -944,7 +952,7 @@ value_primitive_field (struct value *arg1, int offset, FIELDNO says which field. */ struct value * -value_field (struct value *arg1, register int fieldno) +value_field (struct value *arg1, int fieldno) { return value_primitive_field (arg1, 0, fieldno, VALUE_TYPE (arg1)); } @@ -962,12 +970,12 @@ value_fn_field (struct value **arg1p, struct fn_field *f, int j, struct type *ty int offset) { struct value *v; - register struct type *ftype = TYPE_FN_FIELD_TYPE (f, j); + struct type *ftype = TYPE_FN_FIELD_TYPE (f, j); char *physname = TYPE_FN_FIELD_PHYSNAME (f, j); struct symbol *sym; struct minimal_symbol *msym; - sym = lookup_symbol (physname, 0, VAR_NAMESPACE, 0, NULL); + sym = lookup_symbol (physname, 0, VAR_DOMAIN, 0, NULL); if (sym != NULL) { msym = NULL; @@ -1106,11 +1114,11 @@ modify_field (char *addr, LONGEST fieldval, int bitpos, int bitsize) /* Convert C numbers into newly allocated values */ struct value * -value_from_longest (struct type *type, register LONGEST num) +value_from_longest (struct type *type, LONGEST num) { struct value *val = allocate_value (type); - register enum type_code code; - register int len; + enum type_code code; + int len; retry: code = TYPE_CODE (type); len = TYPE_LENGTH (type); @@ -1181,8 +1189,8 @@ value_from_double (struct type *type, DOUBLEST num) { struct value *val = allocate_value (type); struct type *base_type = check_typedef (type); - register enum type_code code = TYPE_CODE (base_type); - register int len = TYPE_LENGTH (base_type); + enum type_code code = TYPE_CODE (base_type); + int len = TYPE_LENGTH (base_type); if (code == TYPE_CODE_FLT) { @@ -1194,53 +1202,48 @@ value_from_double (struct type *type, DOUBLEST num) return val; } -/* Deal with the value that is "about to be returned". */ - -/* Return the value that a function returning now - would be returning to its caller, assuming its type is VALTYPE. - RETBUF is where we look for what ought to be the contents - of the registers (in raw form). This is because it is often - desirable to restore old values to those registers - after saving the contents of interest, and then call - this function using the saved values. - struct_return is non-zero when the function in question is - using the structure return conventions on the machine in question; - 0 when it is using the value returning conventions (this often - means returning pointer to where structure is vs. returning value). */ - -/* ARGSUSED */ +/* Deal with the return-value of a function that has "just returned". + + Extract the return-value (as a "struct value") that a function, + using register convention, has just returned to its caller. Assume + that the type of the function is VALTYPE, and that the "just + returned" register state is found in RETBUF. + + The function has "just returned" because GDB halts a returning + function by setting a breakpoint at the return address (in the + caller), and not the return instruction (in the callee). + + Because, in the case of a return from an inferior function call, + GDB needs to restore the inferiors registers, RETBUF is normally a + copy of the inferior's registers. */ + struct value * -value_being_returned (struct type *valtype, struct regcache *retbuf, - int struct_return) +register_value_being_returned (struct type *valtype, struct regcache *retbuf) { - struct value *val; - CORE_ADDR addr; + struct value *val = allocate_value (valtype); - /* If this is not defined, just use EXTRACT_RETURN_VALUE instead. */ - if (EXTRACT_STRUCT_VALUE_ADDRESS_P ()) - if (struct_return) - { - addr = EXTRACT_STRUCT_VALUE_ADDRESS (retbuf); - if (!addr) - error ("Function return value unknown."); - return value_at (valtype, addr, NULL); - } + /* If the function returns void, don't bother fetching the return + value. */ + if (TYPE_CODE (valtype) == TYPE_CODE_VOID) + return val; - /* If this is not defined, just use EXTRACT_RETURN_VALUE instead. */ - if (DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS_P ()) - if (struct_return) - { - char *buf = deprecated_grub_regcache_for_registers (retbuf); - addr = DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS (buf); - if (!addr) - error ("Function return value unknown."); - return value_at (valtype, addr, NULL); - } - - val = allocate_value (valtype); - CHECK_TYPEDEF (valtype); - EXTRACT_RETURN_VALUE (valtype, retbuf, VALUE_CONTENTS_RAW (val)); + if (!gdbarch_return_value_p (current_gdbarch)) + { + /* NOTE: cagney/2003-10-20: Unlike "gdbarch_return_value", the + EXTRACT_RETURN_VALUE and USE_STRUCT_CONVENTION methods do not + handle the edge case of a function returning a small + structure / union in registers. */ + CHECK_TYPEDEF (valtype); + EXTRACT_RETURN_VALUE (valtype, retbuf, VALUE_CONTENTS_RAW (val)); + return val; + } + /* This function only handles "register convention". */ + gdb_assert (gdbarch_return_value (current_gdbarch, valtype, + NULL, NULL, NULL) + == RETURN_VALUE_REGISTER_CONVENTION); + gdbarch_return_value (current_gdbarch, valtype, retbuf, + NULL, VALUE_CONTENTS_RAW (val)); return val; } @@ -1269,30 +1272,38 @@ generic_use_struct_convention (int gcc_p, struct type *value_type) || TYPE_LENGTH (value_type) == 8)); } -/* Return true if the function specified is using the structure returning - convention on this machine to return arguments, or 0 if it is using - the value returning convention. FUNCTION is the value representing - the function, FUNCADDR is the address of the function, and VALUE_TYPE - is the type returned by the function. GCC_P is nonzero if compiled +/* Return true if the function returning the specified type is using + the convention of returning structures in memory (passing in the + address as a hidden first parameter). GCC_P is nonzero if compiled with GCC. */ -/* ARGSUSED */ int -using_struct_return (struct value *function, CORE_ADDR funcaddr, - struct type *value_type, int gcc_p) +using_struct_return (struct type *value_type, int gcc_p) { - register enum type_code code = TYPE_CODE (value_type); + enum type_code code = TYPE_CODE (value_type); if (code == TYPE_CODE_ERROR) error ("Function return type unknown."); - 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); + if (!gdbarch_return_value_p (current_gdbarch)) + { + /* FIXME: cagney/2003-10-01: The below is dead. Instead an + architecture should implement "gdbarch_return_value". Using + that new function it is possible to exactly specify the ABIs + "struct return" vs "register return" conventions. */ + 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); + else + return 0; + } - return 0; + /* Probe the architecture for the return-value convention. */ + return (gdbarch_return_value (current_gdbarch, value_type, + NULL, NULL, NULL) + == RETURN_VALUE_STRUCT_CONVENTION); } /* Store VAL so it will be returned if a function returns now. @@ -1303,14 +1314,46 @@ void set_return_value (struct value *val) { struct type *type = check_typedef (VALUE_TYPE (val)); - register enum type_code code = TYPE_CODE (type); + enum type_code code = TYPE_CODE (type); if (code == TYPE_CODE_ERROR) error ("Function return type unknown."); + if (gdbarch_return_value_p (current_gdbarch)) + { + switch (gdbarch_return_value (current_gdbarch, type, NULL, NULL, NULL)) + { + case RETURN_VALUE_REGISTER_CONVENTION: + /* Success. The architecture can deal with it, write it to + the regcache. */ + gdbarch_return_value (current_gdbarch, type, current_regcache, + VALUE_CONTENTS (val), NULL); + return; + case RETURN_VALUE_STRUCT_CONVENTION: + /* Failure. For the moment, assume that it is not possible + to find the location, on the stack, at which the "struct + return" value should be stored. Only a warning because + an error aborts the "return" command leaving GDB in a + weird state. */ + warning ("Location of return value unknown"); + return; + } + } + + if (code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION) /* FIXME, implement struct return. */ - error ("GDB does not support specifying a struct or union return value."); + /* FIXME: cagney/2003-10-20: This should be an internal-warning. + The problem is that while GDB's core supports "struct return" + using "register convention", many architectures haven't been + updated to implement the mechanisms needed to make it work. + It's a warning, and not an error, as otherwize it will jump out + of the "return" command leaving both GDB and the user in a very + confused state. */ + { + warning ("This architecture does not support specifying a struct or union return-value."); + return; + } STORE_RETURN_VALUE (type, current_regcache, VALUE_CONTENTS (val)); }