From 236d0f5e3db04e52ffd865de98ad80c6766707d3 Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Sun, 21 May 2023 14:23:11 +0200 Subject: Fix compilation with old MSVC compiler Old pre-4.0 MSVC does not support _ReturnAddress() intrinsic. Provide for it simple implementation via inline assembly. --- src/dlfcn.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) 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; #endif #ifdef _MSC_VER +#if _MSC_VER >= 1000 /* https://docs.microsoft.com/en-us/cpp/intrinsics/returnaddress */ #pragma intrinsic( _ReturnAddress ) #else +/* On older version read return address from the value on stack pointer + 4 of + * the caller. Caller stack pointer is stored in EBP register but only when + * the EBP register is not optimized out. Usage of _alloca() function prevent + * EBP register optimization. Read value of EBP + 4 via inline assembly. And + * because inline assembly does not have a return value, put it into naked + * function which does not have prologue and epilogue and preserve registers. + */ +__declspec( naked ) static void *_ReturnAddress( void ) { __asm mov eax, [ebp+4] __asm ret } +#define _ReturnAddress( ) ( _alloca(1), _ReturnAddress( ) ) +#endif +#else /* https://gcc.gnu.org/onlinedocs/gcc/Return-Address.html */ #ifndef _ReturnAddress #define _ReturnAddress( ) ( __builtin_extract_return_addr( __builtin_return_address( 0 ) ) ) -- cgit v1.2.3-55-g6feb