* defs.h (enum return_value_convention): Add
RETURN_VALUE_ABI_RETURNS_ADDRESS and RETURN_VALUE_ABI_PRESERVES_ADDRESS. * infcmd.c (legacy_return_value): New function. (print_return_value): Rwerite to implement RETURN_VALUE_ABI_RETURNS_ADDRESS. * values.c (using_struct_return): Check for inequality to RETURN_VALUE_REGISTER_CONVENTION instead of equality to RETURN_VALUE_STRUCT_CONVENTION. * i386-tdep.c (i386_return_value): Implement RETURN_VALUE_ABI_RETURNS_ADDRESS.
This commit is contained in:
parent
0543f3876c
commit
31db7b6c38
@ -1,5 +1,17 @@
|
||||
2004-05-09 Mark Kettenis <kettenis@gnu.org>
|
||||
|
||||
* defs.h (enum return_value_convention): Add
|
||||
RETURN_VALUE_ABI_RETURNS_ADDRESS and
|
||||
RETURN_VALUE_ABI_PRESERVES_ADDRESS.
|
||||
* infcmd.c (legacy_return_value): New function.
|
||||
(print_return_value): Rwerite to implement
|
||||
RETURN_VALUE_ABI_RETURNS_ADDRESS.
|
||||
* values.c (using_struct_return): Check for inequality to
|
||||
RETURN_VALUE_REGISTER_CONVENTION instead of equality to
|
||||
RETURN_VALUE_STRUCT_CONVENTION.
|
||||
* i386-tdep.c (i386_return_value): Implement
|
||||
RETURN_VALUE_ABI_RETURNS_ADDRESS.
|
||||
|
||||
* vax-tdep.c: Tweak comments. Reorder include files. Don't
|
||||
include "symtab.h", "opcode/vax.h" and "inferior.h".
|
||||
(vax_skip_prologue): Replace calls to read_memory_integer by calls
|
||||
|
14
gdb/defs.h
14
gdb/defs.h
@ -250,7 +250,19 @@ enum return_value_convention
|
||||
should be stored. While typically, and historically, used for
|
||||
large structs, this is convention is applied to values of many
|
||||
different types. */
|
||||
RETURN_VALUE_STRUCT_CONVENTION
|
||||
RETURN_VALUE_STRUCT_CONVENTION,
|
||||
/* Like the "struct return convention" above, but where the ABI
|
||||
guarantees that the called function stores the address at which
|
||||
the value being returned is stored in a well-defined location,
|
||||
such as a register or memory slot in the stack frame. Don't use
|
||||
this if the ABI doesn't explicitly guarantees this. */
|
||||
RETURN_VALUE_ABI_RETURNS_ADDRESS,
|
||||
/* Like the "struct return convention" above, but where the ABI
|
||||
guarantees that the address at which the value being returned is
|
||||
stored will be available in a well-defined location, such as a
|
||||
register or memory slot in the stack frame. Don't use this if
|
||||
the ABI doesn't explicitly guarantees this. */
|
||||
RETURN_VALUE_ABI_PRESERVES_ADDRESS,
|
||||
};
|
||||
|
||||
/* the cleanup list records things that have to be undone
|
||||
|
@ -1352,7 +1352,28 @@ i386_return_value (struct gdbarch *gdbarch, struct type *type,
|
||||
|
||||
if ((code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION)
|
||||
&& !i386_reg_struct_return_p (gdbarch, type))
|
||||
return RETURN_VALUE_STRUCT_CONVENTION;
|
||||
{
|
||||
/* The System V ABI says that:
|
||||
|
||||
"A function that returns a structure or union also sets %eax
|
||||
to the value of the original address of the caller's area
|
||||
before it returns. Thus when the caller receives control
|
||||
again, the address of the returned object resides in register
|
||||
%eax and can be used to access the object."
|
||||
|
||||
So the ABI guarantees that we can always find the return
|
||||
value just after the function has returned. */
|
||||
|
||||
if (readbuf)
|
||||
{
|
||||
ULONGEST addr;
|
||||
|
||||
regcache_raw_read_unsigned (regcache, I386_EAX_REGNUM, &addr);
|
||||
read_memory (addr, readbuf, TYPE_LENGTH (type));
|
||||
}
|
||||
|
||||
return RETURN_VALUE_ABI_RETURNS_ADDRESS;
|
||||
}
|
||||
|
||||
/* This special case is for structures consisting of a single
|
||||
`float' or `double' member. These structures are returned in
|
||||
|
126
gdb/infcmd.c
126
gdb/infcmd.c
@ -1047,79 +1047,97 @@ advance_command (char *arg, int from_tty)
|
||||
}
|
||||
|
||||
|
||||
/* Print the result of a function at the end of a 'finish' command. */
|
||||
|
||||
static void
|
||||
print_return_value (int struct_return, struct type *value_type)
|
||||
static struct value *
|
||||
legacy_return_value (int struct_return, struct type *value_type)
|
||||
{
|
||||
struct cleanup *old_chain;
|
||||
struct ui_stream *stb;
|
||||
struct value *value;
|
||||
|
||||
if (!struct_return)
|
||||
{
|
||||
/* The return value can be found in the inferior's registers. */
|
||||
value = register_value_being_returned (value_type, stop_registers);
|
||||
return register_value_being_returned (value_type, stop_registers);
|
||||
}
|
||||
/* FIXME: cagney/2004-01-17: When both return_value and
|
||||
extract_returned_value_address are available, should use that to
|
||||
find the address of and then extract the returned value. */
|
||||
|
||||
if (DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS_P ())
|
||||
{
|
||||
CORE_ADDR addr;
|
||||
|
||||
addr = DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS (stop_registers);
|
||||
if (!addr)
|
||||
error ("Function return value unknown.");
|
||||
return value_at (value_type, addr, NULL);
|
||||
}
|
||||
|
||||
/* It is "struct return" yet the value is being extracted,
|
||||
presumably from registers, using EXTRACT_RETURN_VALUE. This
|
||||
doesn't make sense. Unfortunately, the legacy interfaces allowed
|
||||
this behavior. Sigh! */
|
||||
value = allocate_value (value_type);
|
||||
CHECK_TYPEDEF (value_type);
|
||||
/* If the function returns void, don't bother fetching the return
|
||||
value. */
|
||||
EXTRACT_RETURN_VALUE (value_type, stop_registers,
|
||||
VALUE_CONTENTS_RAW (value));
|
||||
return value;
|
||||
}
|
||||
|
||||
/* Print the result of a function at the end of a 'finish' command. */
|
||||
|
||||
static void
|
||||
print_return_value (int struct_return, struct type *value_type)
|
||||
{
|
||||
struct gdbarch *gdbarch = current_gdbarch;
|
||||
struct cleanup *old_chain;
|
||||
struct ui_stream *stb;
|
||||
struct value *value = NULL;
|
||||
|
||||
/* FIXME: 2003-09-27: When returning from a nested inferior function
|
||||
call, it's possible (with no help from the architecture vector)
|
||||
to locate and return/print a "struct return" value. This is just
|
||||
a more complicated case of what is already being done in in the
|
||||
inferior function call code. In fact, when inferior function
|
||||
calls are made async, this will likely be made the norm. */
|
||||
else if (gdbarch_return_value_p (current_gdbarch))
|
||||
/* We cannot determine the contents of the structure because it is
|
||||
on the stack, and we don't know where, since we did not
|
||||
initiate the call, as opposed to the call_function_by_hand
|
||||
case. */
|
||||
|
||||
if (gdbarch_return_value_p (gdbarch))
|
||||
{
|
||||
switch (gdbarch_return_value (gdbarch, value_type, NULL, NULL, NULL))
|
||||
{
|
||||
case RETURN_VALUE_REGISTER_CONVENTION:
|
||||
case RETURN_VALUE_ABI_RETURNS_ADDRESS:
|
||||
value = allocate_value (value_type);
|
||||
CHECK_TYPEDEF (value_type);
|
||||
gdbarch_return_value (current_gdbarch, value_type, stop_registers,
|
||||
VALUE_CONTENTS_RAW (value), NULL);
|
||||
break;
|
||||
|
||||
case RETURN_VALUE_STRUCT_CONVENTION:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
value = legacy_return_value (struct_return, value_type);
|
||||
|
||||
if (value)
|
||||
{
|
||||
/* Print it. */
|
||||
stb = ui_out_stream_new (uiout);
|
||||
old_chain = make_cleanup_ui_out_stream_delete (stb);
|
||||
ui_out_text (uiout, "Value returned is ");
|
||||
ui_out_field_fmt (uiout, "gdb-result-var", "$%d",
|
||||
record_latest_value (value));
|
||||
ui_out_text (uiout, " = ");
|
||||
value_print (value, stb->stream, 0, Val_no_prettyprint);
|
||||
ui_out_field_stream (uiout, "return-value", stb);
|
||||
ui_out_text (uiout, "\n");
|
||||
do_cleanups (old_chain);
|
||||
}
|
||||
else
|
||||
{
|
||||
gdb_assert (gdbarch_return_value (current_gdbarch, value_type,
|
||||
NULL, NULL, NULL)
|
||||
== RETURN_VALUE_STRUCT_CONVENTION);
|
||||
ui_out_text (uiout, "Value returned has type: ");
|
||||
ui_out_field_string (uiout, "return-type", TYPE_NAME (value_type));
|
||||
ui_out_text (uiout, ".");
|
||||
ui_out_text (uiout, " Cannot determine contents\n");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS_P ())
|
||||
{
|
||||
CORE_ADDR addr = DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS (stop_registers);
|
||||
if (!addr)
|
||||
error ("Function return value unknown.");
|
||||
value = value_at (value_type, addr, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* It is "struct return" yet the value is being extracted,
|
||||
presumably from registers, using EXTRACT_RETURN_VALUE.
|
||||
This doesn't make sense. Unfortunately, the legacy
|
||||
interfaces allowed this behavior. Sigh! */
|
||||
value = allocate_value (value_type);
|
||||
CHECK_TYPEDEF (value_type);
|
||||
/* If the function returns void, don't bother fetching the
|
||||
return value. */
|
||||
EXTRACT_RETURN_VALUE (value_type, stop_registers,
|
||||
VALUE_CONTENTS_RAW (value));
|
||||
}
|
||||
}
|
||||
|
||||
/* Print it. */
|
||||
stb = ui_out_stream_new (uiout);
|
||||
old_chain = make_cleanup_ui_out_stream_delete (stb);
|
||||
ui_out_text (uiout, "Value returned is ");
|
||||
ui_out_field_fmt (uiout, "gdb-result-var", "$%d",
|
||||
record_latest_value (value));
|
||||
ui_out_text (uiout, " = ");
|
||||
value_print (value, stb->stream, 0, Val_no_prettyprint);
|
||||
ui_out_field_stream (uiout, "return-value", stb);
|
||||
ui_out_text (uiout, "\n");
|
||||
do_cleanups (old_chain);
|
||||
}
|
||||
|
||||
/* Stuff that needs to be done by the finish command after the target
|
||||
|
@ -1308,7 +1308,7 @@ using_struct_return (struct type *value_type, int gcc_p)
|
||||
/* Probe the architecture for the return-value convention. */
|
||||
return (gdbarch_return_value (current_gdbarch, value_type,
|
||||
NULL, NULL, NULL)
|
||||
== RETURN_VALUE_STRUCT_CONVENTION);
|
||||
!= RETURN_VALUE_REGISTER_CONVENTION);
|
||||
}
|
||||
|
||||
void
|
||||
|
Loading…
Reference in New Issue
Block a user