diff options
-rw-r--r-- | src/dlfcn.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/src/dlfcn.c b/src/dlfcn.c index da9a37a..8dc0359 100644 --- a/src/dlfcn.c +++ b/src/dlfcn.c | |||
@@ -47,9 +47,21 @@ typedef ULONG ULONG_PTR; | |||
47 | #endif | 47 | #endif |
48 | 48 | ||
49 | #ifdef _MSC_VER | 49 | #ifdef _MSC_VER |
50 | #if _MSC_VER >= 1000 | ||
50 | /* https://docs.microsoft.com/en-us/cpp/intrinsics/returnaddress */ | 51 | /* https://docs.microsoft.com/en-us/cpp/intrinsics/returnaddress */ |
51 | #pragma intrinsic( _ReturnAddress ) | 52 | #pragma intrinsic( _ReturnAddress ) |
52 | #else | 53 | #else |
54 | /* On older version read return address from the value on stack pointer + 4 of | ||
55 | * the caller. Caller stack pointer is stored in EBP register but only when | ||
56 | * the EBP register is not optimized out. Usage of _alloca() function prevent | ||
57 | * EBP register optimization. Read value of EBP + 4 via inline assembly. And | ||
58 | * because inline assembly does not have a return value, put it into naked | ||
59 | * function which does not have prologue and epilogue and preserve registers. | ||
60 | */ | ||
61 | __declspec( naked ) static void *_ReturnAddress( void ) { __asm mov eax, [ebp+4] __asm ret } | ||
62 | #define _ReturnAddress( ) ( _alloca(1), _ReturnAddress( ) ) | ||
63 | #endif | ||
64 | #else | ||
53 | /* https://gcc.gnu.org/onlinedocs/gcc/Return-Address.html */ | 65 | /* https://gcc.gnu.org/onlinedocs/gcc/Return-Address.html */ |
54 | #ifndef _ReturnAddress | 66 | #ifndef _ReturnAddress |
55 | #define _ReturnAddress( ) ( __builtin_extract_return_addr( __builtin_return_address( 0 ) ) ) | 67 | #define _ReturnAddress( ) ( __builtin_extract_return_addr( __builtin_return_address( 0 ) ) ) |