mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-02-17 13:10:12 +08:00
Allow struct 'return' on 32-bit sparc.
gdb/ * sparc-tdep.c (sparc32_return_value): Handle writing return value when using RETURN_VALUE_ABI_PRESERVES_ADDRESS. * value.c (struct_return_convention): New function. (using_struct_return): Implement in terms of struct_return_convention. * value.h (struct_return_convention): Declare. * stack.c (return_command): Allow successful overriding of the return value when RETURN_VALUE_ABI_PRESERVES_ADDRESS.
This commit is contained in:
parent
bc9abe4a91
commit
bbfdfe1c57
@ -1,3 +1,13 @@
|
||||
2013-02-06 David S. Miller <davem@davemloft.net>
|
||||
|
||||
* sparc-tdep.c (sparc32_return_value): Handle writing return value when
|
||||
using RETURN_VALUE_ABI_PRESERVES_ADDRESS.
|
||||
* value.c (struct_return_convention): New function.
|
||||
(using_struct_return): Implement in terms of struct_return_convention.
|
||||
* value.h (struct_return_convention): Declare.
|
||||
* stack.c (return_command): Allow successful overriding of the return
|
||||
value when RETURN_VALUE_ABI_PRESERVES_ADDRESS.
|
||||
|
||||
2013-02-06 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* python/py-type.c (typy_strip_typedefs): Don't call check_typedef
|
||||
|
@ -1370,15 +1370,21 @@ sparc32_return_value (struct gdbarch *gdbarch, struct value *function,
|
||||
if (sparc_structure_or_union_p (type)
|
||||
|| (sparc_floating_p (type) && TYPE_LENGTH (type) == 16))
|
||||
{
|
||||
ULONGEST sp;
|
||||
CORE_ADDR addr;
|
||||
|
||||
if (readbuf)
|
||||
{
|
||||
ULONGEST sp;
|
||||
CORE_ADDR addr;
|
||||
|
||||
regcache_cooked_read_unsigned (regcache, SPARC_SP_REGNUM, &sp);
|
||||
addr = read_memory_unsigned_integer (sp + 64, 4, byte_order);
|
||||
read_memory (addr, readbuf, TYPE_LENGTH (type));
|
||||
}
|
||||
if (writebuf)
|
||||
{
|
||||
regcache_cooked_read_unsigned (regcache, SPARC_SP_REGNUM, &sp);
|
||||
addr = read_memory_unsigned_integer (sp + 64, 4, byte_order);
|
||||
write_memory (addr, writebuf, TYPE_LENGTH (type));
|
||||
}
|
||||
|
||||
return RETURN_VALUE_ABI_PRESERVES_ADDRESS;
|
||||
}
|
||||
|
25
gdb/stack.c
25
gdb/stack.c
@ -2278,6 +2278,7 @@ down_command (char *count_exp, int from_tty)
|
||||
void
|
||||
return_command (char *retval_exp, int from_tty)
|
||||
{
|
||||
enum return_value_convention rv_conv;
|
||||
struct frame_info *thisframe;
|
||||
struct gdbarch *gdbarch;
|
||||
struct symbol *thisfun;
|
||||
@ -2331,6 +2332,7 @@ return_command (char *retval_exp, int from_tty)
|
||||
if (thisfun != NULL)
|
||||
function = read_var_value (thisfun, thisframe);
|
||||
|
||||
rv_conv = RETURN_VALUE_REGISTER_CONVENTION;
|
||||
if (TYPE_CODE (return_type) == TYPE_CODE_VOID)
|
||||
/* If the return-type is "void", don't try to find the
|
||||
return-value's location. However, do still evaluate the
|
||||
@ -2338,14 +2340,18 @@ return_command (char *retval_exp, int from_tty)
|
||||
is discarded, side effects such as "return i++" still
|
||||
occur. */
|
||||
return_value = NULL;
|
||||
else if (thisfun != NULL
|
||||
&& using_struct_return (gdbarch, function, return_type))
|
||||
else if (thisfun != NULL)
|
||||
{
|
||||
query_prefix = "The location at which to store the "
|
||||
"function's return value is unknown.\n"
|
||||
"If you continue, the return value "
|
||||
"that you specified will be ignored.\n";
|
||||
return_value = NULL;
|
||||
rv_conv = struct_return_convention (gdbarch, function, return_type);
|
||||
if (rv_conv == RETURN_VALUE_STRUCT_CONVENTION
|
||||
|| rv_conv == RETURN_VALUE_ABI_RETURNS_ADDRESS)
|
||||
{
|
||||
query_prefix = "The location at which to store the "
|
||||
"function's return value is unknown.\n"
|
||||
"If you continue, the return value "
|
||||
"that you specified will be ignored.\n";
|
||||
return_value = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2375,9 +2381,8 @@ return_command (char *retval_exp, int from_tty)
|
||||
struct type *return_type = value_type (return_value);
|
||||
struct gdbarch *gdbarch = get_regcache_arch (get_current_regcache ());
|
||||
|
||||
gdb_assert (gdbarch_return_value (gdbarch, function, return_type, NULL,
|
||||
NULL, NULL)
|
||||
== RETURN_VALUE_REGISTER_CONVENTION);
|
||||
gdb_assert (rv_conv != RETURN_VALUE_STRUCT_CONVENTION
|
||||
&& rv_conv != RETURN_VALUE_ABI_RETURNS_ADDRESS);
|
||||
gdbarch_return_value (gdbarch, function, return_type,
|
||||
get_current_regcache (), NULL /*read*/,
|
||||
value_contents (return_value) /*write*/);
|
||||
|
28
gdb/value.c
28
gdb/value.c
@ -3323,6 +3323,23 @@ coerce_array (struct value *arg)
|
||||
}
|
||||
|
||||
|
||||
/* Return the return value convention that will be used for the
|
||||
specified type. */
|
||||
|
||||
enum return_value_convention
|
||||
struct_return_convention (struct gdbarch *gdbarch,
|
||||
struct value *function, struct type *value_type)
|
||||
{
|
||||
enum type_code code = TYPE_CODE (value_type);
|
||||
|
||||
if (code == TYPE_CODE_ERROR)
|
||||
error (_("Function return type unknown."));
|
||||
|
||||
/* Probe the architecture for the return-value convention. */
|
||||
return gdbarch_return_value (gdbarch, function, value_type,
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
/* 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). */
|
||||
@ -3331,19 +3348,12 @@ int
|
||||
using_struct_return (struct gdbarch *gdbarch,
|
||||
struct value *function, struct type *value_type)
|
||||
{
|
||||
enum type_code code = TYPE_CODE (value_type);
|
||||
|
||||
if (code == TYPE_CODE_ERROR)
|
||||
error (_("Function return type unknown."));
|
||||
|
||||
if (code == TYPE_CODE_VOID)
|
||||
if (TYPE_CODE (value_type) == TYPE_CODE_VOID)
|
||||
/* A void return value is never in memory. See also corresponding
|
||||
code in "print_return_value". */
|
||||
return 0;
|
||||
|
||||
/* Probe the architecture for the return-value convention. */
|
||||
return (gdbarch_return_value (gdbarch, function, value_type,
|
||||
NULL, NULL, NULL)
|
||||
return (struct_return_convention (gdbarch, function, value_type)
|
||||
!= RETURN_VALUE_REGISTER_CONVENTION);
|
||||
}
|
||||
|
||||
|
@ -696,6 +696,10 @@ extern int value_in (struct value *element, struct value *set);
|
||||
extern int value_bit_index (struct type *type, const gdb_byte *addr,
|
||||
int index);
|
||||
|
||||
extern enum return_value_convention
|
||||
struct_return_convention (struct gdbarch *gdbarch, struct value *function,
|
||||
struct type *value_type);
|
||||
|
||||
extern int using_struct_return (struct gdbarch *gdbarch,
|
||||
struct value *function,
|
||||
struct type *value_type);
|
||||
|
Loading…
Reference in New Issue
Block a user