diff options
author | Andrew Cagney <cagney@redhat.com> | 2003-10-20 15:38:02 +0000 |
---|---|---|
committer | Andrew Cagney <cagney@redhat.com> | 2003-10-20 15:38:02 +0000 |
commit | 92ad9cd90faf2b59f2434c8f706902df65ee5c2d (patch) | |
tree | e6360c92e84b1728ff0f1a86b0ceaba8468e3c9f /gdb/values.c | |
parent | 198beae2cfaf8ea8bfd554ef8d3d3feeabc33ed7 (diff) | |
download | gdb-92ad9cd90faf2b59f2434c8f706902df65ee5c2d.zip gdb-92ad9cd90faf2b59f2434c8f706902df65ee5c2d.tar.gz gdb-92ad9cd90faf2b59f2434c8f706902df65ee5c2d.tar.bz2 |
2003-10-20 Andrew Cagney <cagney@redhat.com>
* values.c (register_value_being_returned): Update comments. Use
"gdbarch_return_value" when available.
(using_struct_return): Ditto.
(set_return_value): Ditto. Use "gdbarch_return_value" when
available.. Print a warning, and not an error, when an unhandled
return type is encountered.
* infcmd.c: Include "gdb_assert.h".
(print_return_value): When gdbarch_return_value_p, and using
struct return, assume that the value is not available.
* defs.h (return_value_convention): Define.
* gdbarch.sh (gdbarch_return_value): New predicate method.
* gdbarch.h, gdbarch.c: Re-generate
* ppc-sysv-tdep.c (return_value_convention): Delete definition.
Index: doc/ChangeLog
2003-10-20 Andrew Cagney <cagney@redhat.com>
* gdbint.texinfo (Target Architecture Definition): Document
gdbarch_return_value. Add cross references from
USE_STRUCT_CONVENTION, EXTRACT_RETURN_VALUE, and
STORE_RETURN_VALUE, and from/to EXTRACT_STRUCT_VALUE_ADDRESS.
Diffstat (limited to 'gdb/values.c')
-rw-r--r-- | gdb/values.c | 103 |
1 files changed, 85 insertions, 18 deletions
diff --git a/gdb/values.c b/gdb/values.c index 3b1bca8..da5c180 100644 --- a/gdb/values.c +++ b/gdb/values.c @@ -1202,25 +1202,48 @@ value_from_double (struct type *type, DOUBLEST num) return val; } -/* Deal with the value that is "about to be returned". +/* Deal with the return-value of a function that has "just returned". - Return the value that a function, using the register convention, - 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. */ + 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 * register_value_being_returned (struct type *valtype, struct regcache *retbuf) { struct value *val = allocate_value (valtype); - CHECK_TYPEDEF (valtype); + /* If the function returns void, don't bother fetching the return value. */ - if (TYPE_CODE (valtype) != TYPE_CODE_VOID) - EXTRACT_RETURN_VALUE (valtype, retbuf, VALUE_CONTENTS_RAW (val)); + if (TYPE_CODE (valtype) == TYPE_CODE_VOID) + return 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; } @@ -1262,13 +1285,25 @@ using_struct_return (struct type *value_type, int 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 - || 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. @@ -1284,9 +1319,41 @@ set_return_value (struct value *val) 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)); } |