NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: lib/39465: threads stack is not aligned properly for gcc on i386



The following reply was made to PR lib/39465; it has been noted by GNATS.

From: Anthony Mallet <anthony.mallet%useless-ficus.net@localhost>
To: gnats-bugs%NetBSD.org@localhost
Cc: lib-bug-people%netbsd.org@localhost,
    gnats-admin%netbsd.org@localhost,
    netbsd-bugs%netbsd.org@localhost
Subject: Re: lib/39465: threads stack is not aligned properly for gcc on i386
Date: Wed, 9 Nov 2011 21:55:34 +0100

 On Saturday, at 13:00, David Holland wrote:
 |   >  I do not remember all the details, but IIRC separating sp-- was
 |   > the way to get it right (i.e. have the test program pass). I agree
 |   > that this seemed/seems bogus to me as well... Couldn't it be
 |   > because gcc assumes that the first variable on the stack is aligned
 |   > on 16 bytes, handling the ret address differently?
 |  
 |  It could be any number of similar things... but it's important to
 |  figure out what, or it'll probably break if something shifts around a
 |  little.
 
 Checking FreeBSD code, I found that they align the stack pointer _after_ the
 "sp -= argc + 1", probably to prepare the stack for the upcoming function
 calls, not for the very next one (that probably doesn't care, although it
 should probably be 4 bytes aligned anyway).
 
 This would be with current NetBSD code (i386) :
         sp  = (unsigned int *)((uintptr_t)ucp->uc_stack.ss_sp +
             ucp->uc_stack.ss_size);
         sp -= argc + 1;                 /* Make room for ret and args. */
         /* Align on 16 bytes boundary. */
         sp  = (unsigned int *)((uintptr_t)sp & ~0xf);
 
 Or, if you're strict:
         sp  = (unsigned int *)((uintptr_t)ucp->uc_stack.ss_sp +
             ucp->uc_stack.ss_size);
         /* Align on word boundary. Required?? */
         sp  = (unsigned int *)((uintptr_t)sp & ~0x3);
         sp -= argc + 1;                 /* Make room for ret and args. */
         /* Align on 16 bytes boundary. */
         sp  = (unsigned int *)((uintptr_t)sp & ~0xf);
 
 Does it make more sense like this? - apart from the fact that the ABI requires
 4 bytes alignment only, of course, but that's another issue -
 
 (I haven't tested).
 


Home | Main Index | Thread Index | Old Index