Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 25 Sep 2002 20:10:04 -0700 (PDT)
From:      Bruce Evans <bde@zeta.org.au>
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: i386/41528: better stack alignment patch for lib/csu/i386-elf/
Message-ID:  <200209260310.g8Q3A43r031347@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: Bruce Evans <bde@zeta.org.au>
To: NIIMI Satoshi <sa2c@sa2c.net>
Cc: FreeBSD-gnats-submit@FreeBSD.ORG
Subject: Re: i386/41528: better stack alignment patch for lib/csu/i386-elf/
Date: Thu, 26 Sep 2002 13:15:26 +1000 (EST)

 On 26 Sep 2002, NIIMI Satoshi wrote:
 
 > 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.
 
 Thanks.
 
 > 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.
 
 Urk.
 
 > 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.
 
 Yes, there is no general way, since the alignment required in crt1.c
 depends on at least the compiler version and options.
 
 > 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.
 
 The extra 8 is to fix the off-by-8 error in some cases :-).  When main() is
 compiled by:
 - gcc-2.95.4                           extra 8 aligns stack right
 - gcc-2.95.4 -fomit-frame-pointer      extra 8 gives off-by-8 error
 - gcc-3.2.1                            extra 8 gives off-by-8 error
 - gcc-3.2.1 -fomit-frame-pointer       extra 8 gives off-by-8 error
 
 gcc-3.2.1 does things better but still has 1 bug here: it does the "andl"
 adjustment after allocating space for auto variables in main(), so these
 variables may be misaligned.  But the "andl" realigns the stack for
 functions called by main(), so the off-by-8 error is not very serious.
 
 I tried to align the stack less unportably using alloca(16), but gave up
 after finding just a different morass of bugs and incompatibilities.  I
 learned of the following useful non-bugs:
 - the alignment given by the builtin alloca() is fixed in gcc-3.2.1.  So
   you can now allocate auto variables that need to be strictly aligned
   using "foo_t *fp = alloca(sizeof(foo_t));" even when the function or one
   of its callers is compiled with a non-default -mpreferred-stack-boundary.
   "foo_t f;" is still broken here.
 - variable-sized auto arrays are fixed similarly.
 
 Bruce
 

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?200209260310.g8Q3A43r031347>