Date: Wed, 25 Sep 2002 13:50:09 -0700 (PDT) From: NIIMI Satoshi <sa2c@sa2c.net> To: freebsd-bugs@FreeBSD.org Subject: Re: i386/41528: better stack alignment patch for lib/csu/i386-elf/ Message-ID: <200209252050.g8PKo9Td022452@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR i386/41528; it has been noted by GNATS.
From: NIIMI Satoshi <sa2c@sa2c.net>
To: Bruce Evans <bde@zeta.org.au>
Cc: FreeBSD-gnats-submit@FreeBSD.ORG
Subject: Re: i386/41528: better stack alignment patch for lib/csu/i386-elf/
Date: 26 Sep 2002 05:48:56 +0900
Bruce Evans <bde@zeta.org.au> writes:
> I just got around to preparing this for commit (hopefully just before 4.7),
> and found a small problem. There seems to be an off-by-8 error.
I confirm the problem.
> I am now testing the following patch:
>
> %%%
> Index: crt1.c
> ===================================================================
> RCS file: /home/ncvs/src/lib/csu/i386-elf/crt1.c,v
> retrieving revision 1.9
> diff -u -2 -r1.9 crt1.c
> --- crt1.c 16 Jul 2002 12:28:49 -0000 1.9
> +++ crt1.c 25 Sep 2002 14:23:24 -0000
> @@ -101,5 +101,34 @@
> #endif
> _init();
> +#ifndef __GNUC__
> exit( main(argc, argv, env) );
> +#else
> + /*
> + * gcc-2 expects the stack frame to be aligned as follows after it
> + * is set up in main():
> + *
> + * +--------------+ <--- aligned by PREFERRED_STACK_BOUNDARY
> + * +%ebp (if any) +
> + * +--------------+
> + * |return address|
> + * +--------------+
> + * | arguments |
> + * | : |
> + * | : |
> + * +--------------+
> + *
> + * The call must be written in assembler to implement this.
> + */
> + __asm__("
> + andl $~0xf, %%esp # align stack to 16-byte boundary
> + subl $12+12, %%esp # space for args and padding
> + movl %0, 0(%%esp)
> + movl %1, 4(%%esp)
> + movl %2, 8(%%esp)
> + call main
> + movl %%eax, 0(%%esp)
> + call exit
> + " : : "r" (argc), "r" (argv), "r" (env) : "ax", "cx", "dx", "memory");
> +#endif
> }
>
> %%%
I tested your patch with the following code.
Test code:
#include <stdio.h>
struct foo
{
int a;
} __attribute__((aligned(16)));
int
main(int argc, char **argv, char *envp)
{
struct foo x;
struct foo y;
printf("%p %p\n", &x, &y);
}
Produced assembly (with cc -O):
main:
pushl %ebp
movl %esp,%ebp
subl $40,%esp
addl $-4,%esp
leal -32(%ebp),%eax #A
pushl %eax
leal -16(%ebp),%eax #B
pushl %eax
pushl $.LC0
call printf
leave
ret
At #A and #B, GCC expects %ebp as aligned by PREFERRED_STACK_BOUNDARY.
(This is what your diagram shows.)
But with 'cc -O -fomit-frame-pointer', the expected alignment is different.
Produced assembly (with cc -O -fomit-frame-pointer):
main:
subl $44,%esp
addl $-4,%esp
leal 4(%esp),%eax #A
pushl %eax
leal 24(%esp),%eax #B
pushl %eax
pushl $.LC0
call printf
addl $16,%esp
addl $44,%esp
ret
#A points to original %esp - 44. #B points to original %esp - 28.
In this case, GCC expects argument address as aligned by
PREFERRED_STACK_BOUNDARY. (This is what my diagram shows.)
And there is an off-by-8 error with your patch.
This means that there are no way to remove an off-by-8 error.
Because '-fomit-frame-pointer' is not used in the default setting of
FreeBSD, I think your patch is preferable.
BTW, why did you substruct 12+12 from %esp? I think 12+4 is
sufficient.
--
NIIMI Satoshi
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200209252050.g8PKo9Td022452>
