Skip site navigation (1)Skip section navigation (2)
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>