1 // 2 // internal_shared.h 3 // 4 // Copyright (c) 2024 Timo Kreuzer 5 // 6 // Header for definitions shared between vcruntime and UCRT. 7 // 8 // SPDX-License-Identifier: MIT 9 // 10 11 #pragma once 12 13 #include <suppress.h> 14 #include <intrin.h> 15 #include <corecrt_startup.h> 16 #include <crtdbg.h> 17 #include <windows.h> // for HMODULE 18 #include <malloc.h> 19 20 #ifdef __cplusplus 21 extern "C" { 22 #endif // __cplusplus 23 24 #if defined(_MSC_VER) 25 #define _CRTALLOC(x) __declspec(allocate(x)) 26 #else 27 #define _CRTALLOC(x) __attribute__((section(x))) 28 #endif 29 30 #pragma section(".CRT$XIC", long, read) 31 #pragma section(".CRT$XPX", long, read) 32 #pragma section(".CRT$XPXA", long, read) 33 34 #pragma section(".CRT$XIA", long, read) 35 #pragma section(".CRT$XIZ", long, read) 36 #pragma section(".CRT$XCA", long, read) 37 #pragma section(".CRT$XCZ", long, read) 38 #pragma section(".CRT$XPA", long, read) 39 #pragma section(".CRT$XPZ", long, read) 40 #pragma section(".CRT$XTA", long, read) 41 #pragma section(".CRT$XTZ", long, read) 42 43 extern _PIFV __xi_a[]; 44 extern _PIFV __xi_z[]; 45 extern _PVFV __xc_a[]; 46 extern _PVFV __xc_z[]; 47 extern _PVFV __xp_a[]; 48 extern _PVFV __xp_z[]; 49 extern _PVFV __xt_a[]; 50 extern _PVFV __xt_z[]; 51 52 extern char __ImageBase; 53 54 #define CRT_WARNING_DISABLE_PUSH(wn, message) \ 55 __pragma(warning(push)) \ 56 __pragma(warning(disable: wn)) 57 58 #define CRT_WARNING_POP \ 59 __pragma(warning(pop)) 60 61 #define _BEGIN_SECURE_CRT_DEPRECATION_DISABLE \ 62 __pragma(warning(push)) \ 63 __pragma(warning(disable: 4996)) 64 65 #define _END_SECURE_CRT_DEPRECATION_DISABLE \ 66 __pragma(warning(pop)) 67 68 #define _CRT_DEBUGGER_IGNORE -1 69 #define _CRT_DEBUGGER_GSFAILURE 1 70 #define _CRT_DEBUGGER_INVALIDPARAMETER 2 71 #define _CRT_DEBUGGER_ABORT 3 72 73 #define _CRT_DEBUGGER_HOOK(x) 74 75 #define _CRT_SECURITYCRITICAL_ATTRIBUTE 76 #define _CRT_SECURITYSAFECRITICAL_ATTRIBUTE 77 78 #define _VALIDATE_RETURN(expr, errorcode, retexpr) \ 79 if (!(expr)) return (retexpr); 80 81 #define _VALIDATE_RETURN_VOID(expr, errorcode) \ 82 if (!(expr)) return; 83 84 #define _VALIDATE_RETURN_NOERRNO(expr, retexpr) \ 85 if (!(expr)) return (retexpr); 86 87 #define _VALIDATE_RETURN_ERRCODE(expr, errorcode) \ 88 if (!(expr)) return (errorcode); 89 90 #define _VALIDATE_CLEAR_OSSERR_RETURN(expr, errorcode, retexpr) \ 91 if (!(expr)) return (retexpr); 92 93 #define _VALIDATE_CLEAR_OSSERR_RETURN_ERRCODE(expr, errorcode) \ 94 if (!(expr)) return (errorcode); 95 96 #define _VALIDATE_RETURN_NOEXC(expr, errorcode, retexpr) \ 97 if (!(expr)) return (retexpr); 98 99 #define _VALIDATE_RETURN_ERRCODE_NOEXC(expr, errorcode) \ 100 if (!(expr)) return (errorcode); 101 102 #define _malloc_crt malloc 103 #define _free_crt free 104 #define _calloc_crt calloc 105 #define _recalloc_crt _recalloc 106 #define _malloca_crt _malloca 107 #define _freea_crt _freea 108 109 #ifdef __cplusplus 110 } // extern "C" 111 112 template<typename T> 113 __forceinline 114 T __crt_fast_encode_pointer(T Ptr) 115 { 116 // FIXME: use cookie 117 return Ptr; 118 } 119 120 template<typename T> 121 __forceinline 122 T __crt_fast_decode_pointer(T Ptr) 123 { 124 // FIXME: use cookie 125 return Ptr; 126 } 127 128 template<typename T> 129 T __crt_interlocked_read(const T volatile* ptr) 130 { 131 return *ptr; 132 } 133 134 template<typename T> 135 T __crt_interlocked_read_pointer(const T volatile* ptr) 136 { 137 return *ptr; 138 } 139 140 template<typename T> 141 T __crt_interlocked_exchange_pointer(T *ptr, void* value) 142 { 143 return (T)_InterlockedExchangePointer((void* volatile*)ptr, value); 144 } 145 146 template<typename T> 147 struct __crt_seh_guarded_call 148 { 149 template<typename Init, typename Action, typename Cleanup> 150 T operator()(Init init, Action action, Cleanup cleanup) 151 { 152 init(); 153 __try 154 { 155 return action(); 156 } 157 __finally 158 { 159 cleanup(); 160 } 161 __endtry 162 } 163 }; 164 165 template<typename FuncPtr> 166 FuncPtr __crt_get_proc_address(HMODULE module, const char* name) 167 { 168 return (FuncPtr)GetProcAddress(module, name); 169 } 170 171 template<typename Action, typename Cleanup> 172 void __crt_call_and_cleanup(Action action, Cleanup cleanup) 173 { 174 action(); 175 cleanup(); 176 } 177 178 struct __crt_malloc_free_policy 179 { 180 template<typename T> 181 void operator()(T* const ptr) throw() 182 { 183 _free_crt((void*)ptr); 184 } 185 }; 186 187 struct __crt_public_free_policy 188 { 189 template<typename T> 190 void operator()(T* const ptr) throw() 191 { 192 _free_crt((void*)ptr); 193 } 194 }; 195 196 struct __crt_malloca_free_policy 197 { 198 void operator()(void* const ptr) throw() 199 { 200 _freea_crt(ptr); 201 } 202 }; 203 204 template <typename T, typename FreePolicy = __crt_malloc_free_policy> 205 class __crt_unique_heap_ptr 206 { 207 T* _ptr; 208 public: 209 __crt_unique_heap_ptr() : _ptr(nullptr) {} 210 __crt_unique_heap_ptr(T* ptr) : _ptr(ptr) {} 211 __crt_unique_heap_ptr(__crt_unique_heap_ptr&& from) : _ptr(from._ptr) { from._ptr = nullptr; } 212 ~__crt_unique_heap_ptr() { FreePolicy()(_ptr); } 213 void attach(T* ptr) { FreePolicy()(_ptr); _ptr = ptr; } 214 T* detach() { T* ptr = _ptr; _ptr = nullptr; return ptr; } 215 operator bool() const { return _ptr != nullptr; } 216 T* get() const { return _ptr; } 217 T** get_address_of() { return &_ptr; } 218 219 // Move assignment 220 __crt_unique_heap_ptr& operator=(__crt_unique_heap_ptr&& from) 221 { 222 FreePolicy()(_ptr); 223 _ptr = from._ptr; 224 from._ptr = nullptr; 225 return *this; 226 } 227 }; 228 229 template <typename T> 230 using __crt_scoped_stack_ptr = __crt_unique_heap_ptr<T, __crt_malloca_free_policy>; 231 232 #define _malloc_crt_t(t, n) (__crt_unique_heap_ptr<t>(static_cast<t*>(_malloc_crt((n) * sizeof(t))))) 233 #define _calloc_crt_t(t, n) (__crt_unique_heap_ptr<t>(static_cast<t*>(_calloc_crt((n), sizeof(t))))) 234 #define _recalloc_crt_t(t, p, n) (__crt_unique_heap_ptr<t>(static_cast<t*>(_recalloc_crt(p, (n), sizeof(t))))) 235 #define _malloca_crt_t(t, n) (__crt_scoped_stack_ptr<t>(static_cast<t*>(_malloca_crt((n) * sizeof(t))))) 236 237 #endif // __cplusplus 238