diff options
Diffstat (limited to 'get_stack_direction.c')
-rw-r--r-- | get_stack_direction.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/get_stack_direction.c b/get_stack_direction.c new file mode 100644 index 0000000..2f639da --- /dev/null +++ b/get_stack_direction.c @@ -0,0 +1,62 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +#ifdef SUPPORTED +# undef SUPPORTED +#endif + + +#if defined(__GNUC__) +# define SUPPORTED + +__attribute__((__noinline__)) +static void * +get_callee_frame_address(void) +{ + return __builtin_frame_address(0); +} + + +__attribute__((__noinline__)) +static int +get_stack_direction(void) +{ + void *callerptr, *calleeptr; + uintptr_t caller, callee; + callerptr = __builtin_frame_address(0); + calleeptr = get_callee_frame_address(); + caller = (uintptr_t)callerptr; + callee = (uintptr_t)calleeptr; + return callee > caller ? +1 : callee < caller ? -1 : 0; +} + +#endif + + +int +libsimple_get_stack_direction(void) +{ +#ifdef SUPPORTED + int r = get_stack_direction(); + if (!r) + errno = ENOTSUP; + return r; +#else + errno = ENOTSUP; + return 0; +#endif +} + + +#else +#include "test.h" + +int +main(void) +{ + return 0; +} + +#endif |