synkro
0xdeadbeef
I need the Stack Pointer and the Stack Base Pointer. To get the Stack Pointer I just dereferenciate the last local variable. This should work on all machines (as I want to run my code on GP2X and my PC as most GP2X devs do....) Is there a ARM specific (faster) way? R13 maybe?
To get the Stack Base Pointer I increment the Stack Pointer (as the stack grows down toward the heap) till I get a SIGSEGV or SIGBUSS. This happens when I derefernenciate the mem location right after the Stack Base Addr.
On my PC I get on every run differrent address as I have stuff running in the background using the stack, so this should be alright. But on the GP2X I get 0xbffffffc as Stack Base Pointer. That seems to be WAAAY to far...
What am I doing wrong? Are there better (more elegant) ways to get those pointers (on my Linux PC _and_ GP2X) ?
Source with syntax highlightning
To get the Stack Base Pointer I increment the Stack Pointer (as the stack grows down toward the heap) till I get a SIGSEGV or SIGBUSS. This happens when I derefernenciate the mem location right after the Stack Base Addr.
On my PC I get on every run differrent address as I have stuff running in the background using the stack, so this should be alright. But on the GP2X I get 0xbffffffc as Stack Base Pointer. That seems to be WAAAY to far...
What am I doing wrong? Are there better (more elegant) ways to get those pointers (on my Linux PC _and_ GP2X) ?
Source with syntax highlightning
Code:
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
// non-local jump env
static jmp_buf g_jump_buffer;
// prototypes
void handleSignal(int value);
void *getStackBasePtr(void);
int main(void)
{
printf("stack base pointer: %p\n", getStackBasePtr());
return 1;
}
/*
** gets called when we leave the stack into the limbo
** SIGBUS or SIGSEV
*/
void handleSignal(int value)
{
longjmp(g_jump_buffer, 1);
}
/*
** Returns the stacl base pointer
*/
void *getStackBasePtr(void)
{
int *base_ptr, stack_top, deref;
// get one of the top stack entries
base_ptr = &stack_top;
// non-local exit
if(setjmp(g_jump_buffer)!=0)
{
// we left the stack by one
return base_ptr - 1;
}
// follow the stakc till we leave it
while(1)
{
// move towards the first/oldest element on the stack
base_ptr++;
// if we dereference an invalid pointer, signal will be thrown
deref = *base_ptr;
if( (signal(SIGBUS, handleSignal) == SIG_ERR) || (signal(SIGSEGV, handleSignal) == SIG_ERR) )
{
// error with signal handler
fprintf(stderr,"ERROR! SIGNAL HANDLER FAILED!\n");
exit(1);
}
}
return base_ptr - 1;
}