aboutsummaryrefslogtreecommitdiff
path: root/x86_64-gen.c
diff options
context:
space:
mode:
authorMichael Matz <matz@suse.de>2015-03-09 00:19:59 +0100
committerMichael Matz <matz@suse.de>2015-03-09 00:19:59 +0100
commit50899e30abf3cbd71a09ecc03b2e172f6ba5d4f4 (patch)
tree2451264d2ed2950fd232f5d4d4fed8ffe2f6538e /x86_64-gen.c
parentd73b48840115f0adc97d6a9e6fe2aeb88fcbfbdd (diff)
downloadtinycc-50899e30abf3cbd71a09ecc03b2e172f6ba5d4f4.tar.gz
tinycc-50899e30abf3cbd71a09ecc03b2e172f6ba5d4f4.tar.bz2
Fix stack overwrite on structure return
The common code to move a returned structure packed into registers into memory on the caller side didn't take the register size into account when allocating local storage, so sometimes that lead to stack overwrites (e.g. in 73_arm64.c), on x86_64. This fixes it by generally making gfunc_sret also return the register size.
Diffstat (limited to 'x86_64-gen.c')
-rw-r--r--x86_64-gen.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/x86_64-gen.c b/x86_64-gen.c
index 67aaadc..d5ed4f6 100644
--- a/x86_64-gen.c
+++ b/x86_64-gen.c
@@ -662,9 +662,10 @@ void gen_offs_sp(int b, int r, int d)
/* Return the number of registers needed to return the struct, or 0 if
returning via struct pointer. */
-ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align)
+ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize)
{
int size, align;
+ *regsize = 8;
*ret_align = 1; // Never have to re-align return values for x86-64
size = type_size(vt, &align);
ret->ref = NULL;
@@ -1069,10 +1070,11 @@ ST_FUNC int classify_x86_64_va_arg(CType *ty)
/* Return the number of registers needed to return the struct, or 0 if
returning via struct pointer. */
-ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align)
+ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize)
{
int size, align, reg_count;
*ret_align = 1; // Never have to re-align return values for x86-64
+ *regsize = 8;
return (classify_x86_64_arg(vt, ret, &size, &align, &reg_count) != x86_64_mode_memory);
}