mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-05 06:23:58 +08:00
* i386-tdep.c (i386_extract_return_value,
i386_store_return_value): Add gdbarch argument. Use it instead of determining it from REGCACHE. Remove recursive call for structures with a single member. (i386_use_struct_convention): Remove. (i386_reg_struct_return_p): New function. (i386_return_value): New function. (i386_gdbarch_init): Set return_value, don't set extract_return_value, store_return_value and use_struct_convention. * x86-64-tdep.c (x86_64_init_abi): Set return_value to NULL.
This commit is contained in:
@ -1,3 +1,17 @@
|
|||||||
|
2003-11-20 Mark Kettenis <kettenis@gnu.org>
|
||||||
|
|
||||||
|
* i386-tdep.c (i386_extract_return_value,
|
||||||
|
i386_store_return_value): Add gdbarch argument. Use it instead of
|
||||||
|
determining it from REGCACHE. Remove recursive call for
|
||||||
|
structures with a single member.
|
||||||
|
(i386_use_struct_convention): Remove.
|
||||||
|
(i386_reg_struct_return_p): New function.
|
||||||
|
(i386_return_value): New function.
|
||||||
|
(i386_gdbarch_init): Set return_value, don't set
|
||||||
|
extract_return_value, store_return_value and
|
||||||
|
use_struct_convention.
|
||||||
|
* x86-64-tdep.c (x86_64_init_abi): Set return_value to NULL.
|
||||||
|
|
||||||
2003-11-20 Jim Blandy <jimb@redhat.com>
|
2003-11-20 Jim Blandy <jimb@redhat.com>
|
||||||
|
|
||||||
* osabi.c (_initialize_gdb_osabi): Don't return before registering
|
* osabi.c (_initialize_gdb_osabi): Don't return before registering
|
||||||
|
101
gdb/i386-tdep.c
101
gdb/i386-tdep.c
@ -1151,25 +1151,17 @@ i386_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
|
|||||||
#define LOW_RETURN_REGNUM I386_EAX_REGNUM /* %eax */
|
#define LOW_RETURN_REGNUM I386_EAX_REGNUM /* %eax */
|
||||||
#define HIGH_RETURN_REGNUM I386_EDX_REGNUM /* %edx */
|
#define HIGH_RETURN_REGNUM I386_EDX_REGNUM /* %edx */
|
||||||
|
|
||||||
/* Extract from an array REGBUF containing the (raw) register state, a
|
/* Read, for architecture GDBARCH, a function return value of TYPE
|
||||||
function return value of TYPE, and copy that, in virtual format,
|
from REGCACHE, and copy that into VALBUF. */
|
||||||
into VALBUF. */
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
i386_extract_return_value (struct type *type, struct regcache *regcache,
|
i386_extract_return_value (struct gdbarch *gdbarch, struct type *type,
|
||||||
void *valbuf)
|
struct regcache *regcache, void *valbuf)
|
||||||
{
|
{
|
||||||
struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
|
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||||
int len = TYPE_LENGTH (type);
|
int len = TYPE_LENGTH (type);
|
||||||
char buf[I386_MAX_REGISTER_SIZE];
|
char buf[I386_MAX_REGISTER_SIZE];
|
||||||
|
|
||||||
if (TYPE_CODE (type) == TYPE_CODE_STRUCT
|
|
||||||
&& TYPE_NFIELDS (type) == 1)
|
|
||||||
{
|
|
||||||
i386_extract_return_value (TYPE_FIELD_TYPE (type, 0), regcache, valbuf);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TYPE_CODE (type) == TYPE_CODE_FLT)
|
if (TYPE_CODE (type) == TYPE_CODE_FLT)
|
||||||
{
|
{
|
||||||
if (tdep->st0_regnum < 0)
|
if (tdep->st0_regnum < 0)
|
||||||
@ -1209,27 +1201,20 @@ i386_extract_return_value (struct type *type, struct regcache *regcache,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write into the appropriate registers a function return value stored
|
/* Write, for architecture GDBARCH, a function return value of TYPE
|
||||||
in VALBUF of type TYPE, given in virtual format. */
|
from VALBUF into REGCACHE. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
i386_store_return_value (struct type *type, struct regcache *regcache,
|
i386_store_return_value (struct gdbarch *gdbarch, struct type *type,
|
||||||
const void *valbuf)
|
struct regcache *regcache, const void *valbuf)
|
||||||
{
|
{
|
||||||
struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
|
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||||
int len = TYPE_LENGTH (type);
|
int len = TYPE_LENGTH (type);
|
||||||
|
|
||||||
/* Define I387_ST0_REGNUM such that we use the proper definitions
|
/* Define I387_ST0_REGNUM such that we use the proper definitions
|
||||||
for the architecture. */
|
for the architecture. */
|
||||||
#define I387_ST0_REGNUM I386_ST0_REGNUM
|
#define I387_ST0_REGNUM I386_ST0_REGNUM
|
||||||
|
|
||||||
if (TYPE_CODE (type) == TYPE_CODE_STRUCT
|
|
||||||
&& TYPE_NFIELDS (type) == 1)
|
|
||||||
{
|
|
||||||
i386_store_return_value (TYPE_FIELD_TYPE (type, 0), regcache, valbuf);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TYPE_CODE (type) == TYPE_CODE_FLT)
|
if (TYPE_CODE (type) == TYPE_CODE_FLT)
|
||||||
{
|
{
|
||||||
ULONGEST fstat;
|
ULONGEST fstat;
|
||||||
@ -1314,20 +1299,62 @@ static const char *valid_conventions[] =
|
|||||||
};
|
};
|
||||||
static const char *struct_convention = default_struct_convention;
|
static const char *struct_convention = default_struct_convention;
|
||||||
|
|
||||||
|
/* Return non-zero if TYPE, which is assumed to be a structure or
|
||||||
|
union type, should be returned in registers for architecture
|
||||||
|
GDBARCH. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
i386_use_struct_convention (int gcc_p, struct type *type)
|
i386_reg_struct_return_p (struct gdbarch *gdbarch, struct type *type)
|
||||||
{
|
{
|
||||||
enum struct_return struct_return;
|
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||||
|
enum type_code code = TYPE_CODE (type);
|
||||||
|
int len = TYPE_LENGTH (type);
|
||||||
|
|
||||||
if (struct_convention == default_struct_convention)
|
gdb_assert (code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION);
|
||||||
struct_return = gdbarch_tdep (current_gdbarch)->struct_return;
|
|
||||||
else if (struct_convention == pcc_struct_convention)
|
|
||||||
struct_return = pcc_struct_return;
|
|
||||||
else
|
|
||||||
struct_return = reg_struct_return;
|
|
||||||
|
|
||||||
return generic_use_struct_convention (struct_return == reg_struct_return,
|
if (struct_convention == pcc_struct_convention
|
||||||
type);
|
|| (struct_convention == default_struct_convention
|
||||||
|
&& tdep->struct_return == pcc_struct_return))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return (len == 1 || len == 2 || len == 4 || len == 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Determine, for architecture GDBARCH, how a return value of TYPE
|
||||||
|
should be returned. If it is supposed to be returned in registers,
|
||||||
|
and READBUF is non-zero, read the appropriate value from REGCACHE,
|
||||||
|
and copy it into READBUF. If WRITEBUF is non-zero, write the value
|
||||||
|
from WRITEBUF into REGCACHE. */
|
||||||
|
|
||||||
|
static enum return_value_convention
|
||||||
|
i386_return_value (struct gdbarch *gdbarch, struct type *type,
|
||||||
|
struct regcache *regcache, void *readbuf,
|
||||||
|
const void *writebuf)
|
||||||
|
{
|
||||||
|
enum type_code code = TYPE_CODE (type);
|
||||||
|
|
||||||
|
if ((code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION)
|
||||||
|
&& !i386_reg_struct_return_p (gdbarch, type))
|
||||||
|
return RETURN_VALUE_STRUCT_CONVENTION;
|
||||||
|
|
||||||
|
/* This special case is for structures consisting of a single
|
||||||
|
`float' or `double' member. These structures are returned in
|
||||||
|
%st(0). For these structures, we call ourselves recursively,
|
||||||
|
changing TYPE into the type of the first member of the structure.
|
||||||
|
Since that should work for all structures that have only one
|
||||||
|
member, we don't bother to check the member's type here. */
|
||||||
|
if (code == TYPE_CODE_STRUCT && TYPE_NFIELDS (type) == 1)
|
||||||
|
{
|
||||||
|
type = check_typedef (TYPE_FIELD_TYPE (type, 0));
|
||||||
|
return i386_return_value (gdbarch, type, regcache, readbuf, writebuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (readbuf)
|
||||||
|
i386_extract_return_value (gdbarch, type, regcache, readbuf);
|
||||||
|
if (writebuf)
|
||||||
|
i386_store_return_value (gdbarch, type, regcache, writebuf);
|
||||||
|
|
||||||
|
return RETURN_VALUE_REGISTER_CONVENTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1963,11 +1990,9 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
|||||||
set_gdbarch_register_to_value (gdbarch, i386_register_to_value);
|
set_gdbarch_register_to_value (gdbarch, i386_register_to_value);
|
||||||
set_gdbarch_value_to_register (gdbarch, i386_value_to_register);
|
set_gdbarch_value_to_register (gdbarch, i386_value_to_register);
|
||||||
|
|
||||||
set_gdbarch_extract_return_value (gdbarch, i386_extract_return_value);
|
set_gdbarch_return_value (gdbarch, i386_return_value);
|
||||||
set_gdbarch_store_return_value (gdbarch, i386_store_return_value);
|
|
||||||
set_gdbarch_extract_struct_value_address (gdbarch,
|
set_gdbarch_extract_struct_value_address (gdbarch,
|
||||||
i386_extract_struct_value_address);
|
i386_extract_struct_value_address);
|
||||||
set_gdbarch_use_struct_convention (gdbarch, i386_use_struct_convention);
|
|
||||||
|
|
||||||
set_gdbarch_skip_prologue (gdbarch, i386_skip_prologue);
|
set_gdbarch_skip_prologue (gdbarch, i386_skip_prologue);
|
||||||
|
|
||||||
|
@ -1300,6 +1300,7 @@ x86_64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
|||||||
set_gdbarch_register_to_value (gdbarch, i387_register_to_value);
|
set_gdbarch_register_to_value (gdbarch, i387_register_to_value);
|
||||||
set_gdbarch_value_to_register (gdbarch, i387_value_to_register);
|
set_gdbarch_value_to_register (gdbarch, i387_value_to_register);
|
||||||
|
|
||||||
|
set_gdbarch_return_value (gdbarch, NULL);
|
||||||
set_gdbarch_extract_return_value (gdbarch, x86_64_extract_return_value);
|
set_gdbarch_extract_return_value (gdbarch, x86_64_extract_return_value);
|
||||||
set_gdbarch_store_return_value (gdbarch, x86_64_store_return_value);
|
set_gdbarch_store_return_value (gdbarch, x86_64_store_return_value);
|
||||||
/* Override, since this is handled by x86_64_extract_return_value. */
|
/* Override, since this is handled by x86_64_extract_return_value. */
|
||||||
|
Reference in New Issue
Block a user