Varargs issues
James Van Artsdalen
james-freebsd-amd64 at jrv.org
Mon Dec 1 16:11:08 PST 2003
I looked at the example I was suspicious of and realized that I had
overlooked that the caller implicitly allocates 8 bytes in the stack
due to the CALL opcode. It's perfectly reasonable for a function to
start with something like:
doo:
push (64 bit) val
call z
since the return address + the push makes an even 16 bytes.
There are two different pthread_create () functions. The one in
/usr/src/lib/libc_r/uthread/uthread_create.c does this to ensure that
the stack starts off right:
SET_STACK_JB(new_thread->ctx.jb,
(long)new_thread->stack + pattr->stacksize_attr
- sizeof(double));
sizeof (double) isn't really portable - sizeof (&_pthread_create) would
be better - but it clearly leaves the stack with a value that gcc expects,
i.e., an "odd" value in 8-byte units (0xfff8 instead of 0xfff0).
But, in /usr/src/lib/libthr/thread/thr_create.c I see this:
new_thread->ctx.uc_stack.ss_sp = new_thread->stack;
and no evidence anywhere that the return address gcc expects to already
be pushed on the stack is accounted for. Perhaps this should be something
like:
new_thread->ctx.uc_stack.ss_sp = new_thread->stack;
#if !defined(__ia64__)
new_thread->ctx.uc_stack.ss_sp -= sizeof (&_pthread_create);
#endif
(I'm carrying over the assumption that stacks grow towards lower addresses)
> James Van Artsdalen wrote:
> > The trick is that gcc 3.3 doesn't seem to try to keep the stack
> > aligned to 16-bytes, [...]
>
> gcc depends on the stack being correctly aligned at program entry and makes
> sure it is aligned before making other function calls. You'll see this in
> subtle ways, eg: it'll reserve 32 bytes of stack space instead of the 24 that
> it might actually use, etc.
More information about the freebsd-amd64
mailing list