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