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>