From owner-freebsd-bugs Wed Sep 25 20:10: 8 2002 Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 5C1FF37B401 for ; Wed, 25 Sep 2002 20:10:05 -0700 (PDT) Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 0E93843E65 for ; Wed, 25 Sep 2002 20:10:05 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.12.6/8.12.6) with ESMTP id g8Q3A4Co031348 for ; Wed, 25 Sep 2002 20:10:04 -0700 (PDT) (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.6/8.12.6/Submit) id g8Q3A43r031347; Wed, 25 Sep 2002 20:10:04 -0700 (PDT) Date: Wed, 25 Sep 2002 20:10:04 -0700 (PDT) Message-Id: <200209260310.g8Q3A43r031347@freefall.freebsd.org> To: freebsd-bugs@FreeBSD.org Cc: From: Bruce Evans Subject: Re: i386/41528: better stack alignment patch for lib/csu/i386-elf/ Reply-To: Bruce Evans Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org The following reply was made to PR i386/41528; it has been noted by GNATS. From: Bruce Evans To: NIIMI Satoshi 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 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 > > 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