mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-24 12:23:31 +08:00
* i386-tdep.c (i386_16_byte_align_p): New.
(i386_push_dummy_call): Determine stack space required for arguments going forwards allowing for 16-byte alignment, then push arguments going forwards.
This commit is contained in:
@ -1,3 +1,10 @@
|
|||||||
|
2008-06-27 Joseph Myers <joseph@codesourcery.com>
|
||||||
|
|
||||||
|
* i386-tdep.c (i386_16_byte_align_p): New.
|
||||||
|
(i386_push_dummy_call): Determine stack space required for
|
||||||
|
arguments going forwards allowing for 16-byte alignment, then push
|
||||||
|
arguments going forwards.
|
||||||
|
|
||||||
2008-06-27 Pedro Alves <pedro@codesourcery.com>
|
2008-06-27 Pedro Alves <pedro@codesourcery.com>
|
||||||
|
|
||||||
* infrun.c (start_remote): Don't clear thread list here.
|
* infrun.c (start_remote): Don't clear thread list here.
|
||||||
|
@ -1521,6 +1521,34 @@ i386_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Check whether TYPE must be 16-byte-aligned when passed as a
|
||||||
|
function argument. 16-byte vectors, _Decimal128 and structures or
|
||||||
|
unions containing such types must be 16-byte-aligned; other
|
||||||
|
arguments are 4-byte-aligned. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
i386_16_byte_align_p (struct type *type)
|
||||||
|
{
|
||||||
|
type = check_typedef (type);
|
||||||
|
if ((TYPE_CODE (type) == TYPE_CODE_DECFLOAT
|
||||||
|
|| (TYPE_CODE (type) == TYPE_CODE_ARRAY && TYPE_VECTOR (type)))
|
||||||
|
&& TYPE_LENGTH (type) == 16)
|
||||||
|
return 1;
|
||||||
|
if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
|
||||||
|
return i386_16_byte_align_p (TYPE_TARGET_TYPE (type));
|
||||||
|
if (TYPE_CODE (type) == TYPE_CODE_STRUCT
|
||||||
|
|| TYPE_CODE (type) == TYPE_CODE_UNION)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < TYPE_NFIELDS (type); i++)
|
||||||
|
{
|
||||||
|
if (i386_16_byte_align_p (TYPE_FIELD_TYPE (type, i)))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static CORE_ADDR
|
static CORE_ADDR
|
||||||
i386_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
|
i386_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
|
||||||
struct regcache *regcache, CORE_ADDR bp_addr, int nargs,
|
struct regcache *regcache, CORE_ADDR bp_addr, int nargs,
|
||||||
@ -1529,12 +1557,42 @@ i386_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
|
|||||||
{
|
{
|
||||||
gdb_byte buf[4];
|
gdb_byte buf[4];
|
||||||
int i;
|
int i;
|
||||||
|
int write_pass;
|
||||||
|
int args_space = 0;
|
||||||
|
|
||||||
/* Push arguments in reverse order. */
|
/* Determine the total space required for arguments and struct
|
||||||
for (i = nargs - 1; i >= 0; i--)
|
return address in a first pass (allowing for 16-byte-aligned
|
||||||
|
arguments), then push arguments in a second pass. */
|
||||||
|
|
||||||
|
for (write_pass = 0; write_pass < 2; write_pass++)
|
||||||
|
{
|
||||||
|
int args_space_used = 0;
|
||||||
|
int have_16_byte_aligned_arg = 0;
|
||||||
|
|
||||||
|
if (struct_return)
|
||||||
|
{
|
||||||
|
if (write_pass)
|
||||||
|
{
|
||||||
|
/* Push value address. */
|
||||||
|
store_unsigned_integer (buf, 4, struct_addr);
|
||||||
|
write_memory (sp, buf, 4);
|
||||||
|
args_space_used += 4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
args_space += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < nargs; i++)
|
||||||
{
|
{
|
||||||
int len = TYPE_LENGTH (value_enclosing_type (args[i]));
|
int len = TYPE_LENGTH (value_enclosing_type (args[i]));
|
||||||
|
|
||||||
|
if (write_pass)
|
||||||
|
{
|
||||||
|
if (i386_16_byte_align_p (value_enclosing_type (args[i])))
|
||||||
|
args_space_used = align_up (args_space_used, 16);
|
||||||
|
|
||||||
|
write_memory (sp + args_space_used,
|
||||||
|
value_contents_all (args[i]), len);
|
||||||
/* The System V ABI says that:
|
/* The System V ABI says that:
|
||||||
|
|
||||||
"An argument's size is increased, if necessary, to make it a
|
"An argument's size is increased, if necessary, to make it a
|
||||||
@ -1542,16 +1600,25 @@ i386_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
|
|||||||
depending on the size of the argument."
|
depending on the size of the argument."
|
||||||
|
|
||||||
This makes sure the stack stays word-aligned. */
|
This makes sure the stack stays word-aligned. */
|
||||||
sp -= (len + 3) & ~3;
|
args_space_used += align_up (len, 4);
|
||||||
write_memory (sp, value_contents_all (args[i]), len);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (i386_16_byte_align_p (value_enclosing_type (args[i])))
|
||||||
|
{
|
||||||
|
args_space = align_up (args_space, 16);
|
||||||
|
have_16_byte_aligned_arg = 1;
|
||||||
|
}
|
||||||
|
args_space += align_up (len, 4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Push value address. */
|
if (!write_pass)
|
||||||
if (struct_return)
|
|
||||||
{
|
{
|
||||||
sp -= 4;
|
if (have_16_byte_aligned_arg)
|
||||||
store_unsigned_integer (buf, 4, struct_addr);
|
args_space = align_up (args_space, 16);
|
||||||
write_memory (sp, buf, 4);
|
sp -= args_space;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store return address. */
|
/* Store return address. */
|
||||||
|
Reference in New Issue
Block a user