Stack issues
Posted: Tue May 01, 2007 3:06 am
I have a working stack setup in my kernel thread generation code, that pushes a return address onto the stack that points to a 'die()' function to delete the process when it returns. The problem is, I can't have anything on the stack between the process entry point and the 'die()' entry point. I wrote this to push the arguments onto the stack:
It works, processes spawned can read the arguments and use them etc...
But they can't return without crashing, because, I think, they are trying to return to an address that is pushed by the above code. The main reason, I think, is that C doesn't pop arguments off the stack when it handles them, that's the job of the caller. In that case, how do I pop the arguments off the stack?
I tried this, to sum up the size of all the arguments and add that value to ESP:
It didn't work.
Code: Select all
// start the va_list
va_list pushargs;
va_start( pushargs, arglist );
// parse it
i = 0;
while( arglist[i] != 0 )
{
if( arglist[i] == '%' )
{
// get each part of it
if( arglist[i+1] == 'd' )
{
// decimal (int)
i += 2;
int val = va_arg( pushargs, int );
*esp-- = val;
}
else if( arglist[i+1] == 'u' )
{
// unsigned (look at next char)
if( arglist[i+2] == 'd' )
{
// unsigned int
i += 3;
unsigned int val = va_arg( pushargs, unsigned int );
*esp-- = val;
}
else
{
i++;
}
}
else if( arglist[i+1] == 's' )
{
// string pointer (always char*)
i += 2;
char* val = va_arg( pushargs, char* );
*esp-- = (unsigned int) val;
}
else
{
// unknown format specifier
i++;
}
}
}
// all done
va_end( pushargs );
But they can't return without crashing, because, I think, they are trying to return to an address that is pushed by the above code. The main reason, I think, is that C doesn't pop arguments off the stack when it handles them, that's the job of the caller. In that case, how do I pop the arguments off the stack?
I tried this, to sum up the size of all the arguments and add that value to ESP:
Code: Select all
unsigned int stacksize = sizeof( arg1 ) + sizeof( arg2 ) + sizeof( unsigned int );
__asm__ __volatile__ ( "addl %0,%%esp" : : "r" (stacksize) );