1 //===-- sanitizer_win_defs.h ------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Common definitions for Windows-specific code. 11 // 12 //===----------------------------------------------------------------------===// 13 #ifndef SANITIZER_WIN_DEFS_H 14 #define SANITIZER_WIN_DEFS_H 15 16 #include "sanitizer_platform.h" 17 #if SANITIZER_WINDOWS 18 19 #ifndef WINAPI 20 #if defined(_M_IX86) || defined(__i386__) 21 #define WINAPI __stdcall 22 #else 23 #define WINAPI 24 #endif 25 #endif 26 27 #if defined(_M_IX86) || defined(__i386__) 28 #define WIN_SYM_PREFIX "_" 29 #else 30 #define WIN_SYM_PREFIX 31 #endif 32 33 // For MinGW, the /export: directives contain undecorated symbols, contrary to 34 // link/lld-link. The GNU linker doesn't support /alternatename and /include 35 // though, thus lld-link in MinGW mode interprets them in the same way as 36 // in the default mode. 37 #ifdef __MINGW32__ 38 #define WIN_EXPORT_PREFIX 39 #else 40 #define WIN_EXPORT_PREFIX WIN_SYM_PREFIX 41 #endif 42 43 // Intermediate macro to ensure the parameter is expanded before stringified. 44 #define STRINGIFY_(A) #A 45 #define STRINGIFY(A) STRINGIFY_(A) 46 47 // ----------------- A workaround for the absence of weak symbols -------------- 48 // We don't have a direct equivalent of weak symbols when using MSVC, but we can 49 // use the /alternatename directive to tell the linker to default a specific 50 // symbol to a specific value. 51 // Take into account that this is a pragma directive for the linker, so it will 52 // be ignored by the compiler and the function will be marked as UNDEF in the 53 // symbol table of the resulting object file. The linker won't find the default 54 // implementation until it links with that object file. 55 // So, suppose we provide a default implementation "fundef" for "fun", and this 56 // is compiled into the object file "test.obj" including the pragma directive. 57 // If we have some code with references to "fun" and we link that code with 58 // "test.obj", it will work because the linker always link object files. 59 // But, if "test.obj" is included in a static library, like "test.lib", then the 60 // liker will only link to "test.obj" if necessary. If we only included the 61 // definition of "fun", it won't link to "test.obj" (from test.lib) because 62 // "fun" appears as UNDEF, so it doesn't resolve the symbol "fun", and will 63 // result in a link error (the linker doesn't find the pragma directive). 64 // So, a workaround is to force linkage with the modules that include weak 65 // definitions, with the following macro: WIN_FORCE_LINK() 66 67 #define WIN_WEAK_ALIAS(Name, Default) \ 68 __pragma(comment(linker, "/alternatename:" WIN_SYM_PREFIX STRINGIFY(Name) "="\ 69 WIN_SYM_PREFIX STRINGIFY(Default))) 70 71 #define WIN_FORCE_LINK(Name) \ 72 __pragma(comment(linker, "/include:" WIN_SYM_PREFIX STRINGIFY(Name))) 73 74 #define WIN_EXPORT(ExportedName, Name) \ 75 __pragma(comment(linker, "/export:" WIN_EXPORT_PREFIX STRINGIFY(ExportedName)\ 76 "=" WIN_EXPORT_PREFIX STRINGIFY(Name))) 77 78 // We cannot define weak functions on Windows, but we can use WIN_WEAK_ALIAS() 79 // which defines an alias to a default implementation, and only works when 80 // linking statically. 81 // So, to define a weak function "fun", we define a default implementation with 82 // a different name "fun__def" and we create a "weak alias" fun = fun__def. 83 // Then, users can override it just defining "fun". 84 // We impose "extern "C"" because otherwise WIN_WEAK_ALIAS() will fail because 85 // of name mangling. 86 87 // Dummy name for default implementation of weak function. 88 # define WEAK_DEFAULT_NAME(Name) Name##__def 89 // Name for exported implementation of weak function. 90 # define WEAK_EXPORT_NAME(Name) Name##__dll 91 92 // Use this macro when you need to define and export a weak function from a 93 // library. For example: 94 // WIN_WEAK_EXPORT_DEF(bool, compare, int a, int b) { return a > b; } 95 # define WIN_WEAK_EXPORT_DEF(ReturnType, Name, ...) \ 96 WIN_WEAK_ALIAS(Name, WEAK_DEFAULT_NAME(Name)) \ 97 WIN_EXPORT(WEAK_EXPORT_NAME(Name), Name) \ 98 extern "C" ReturnType Name(__VA_ARGS__); \ 99 extern "C" ReturnType WEAK_DEFAULT_NAME(Name)(__VA_ARGS__) 100 101 // Use this macro when you need to import a weak function from a library. It 102 // defines a weak alias to the imported function from the dll. For example: 103 // WIN_WEAK_IMPORT_DEF(compare) 104 # define WIN_WEAK_IMPORT_DEF(Name) \ 105 WIN_WEAK_ALIAS(Name, WEAK_EXPORT_NAME(Name)) 106 107 // So, for Windows we provide something similar to weak symbols in Linux, with 108 // some differences: 109 // + A default implementation must always be provided. 110 // 111 // + When linking statically it works quite similarly. For example: 112 // 113 // // libExample.cc 114 // WIN_WEAK_EXPORT_DEF(bool, compare, int a, int b) { return a > b; } 115 // 116 // // client.cc 117 // // We can use the default implementation from the library: 118 // compare(1, 2); 119 // // Or we can override it: 120 // extern "C" bool compare (int a, int b) { return a >= b; } 121 // 122 // And it will work fine. If we don't override the function, we need to ensure 123 // that the linker includes the object file with the default implementation. 124 // We can do so with the linker option "-wholearchive:". 125 // 126 // + When linking dynamically with a library (dll), weak functions are exported 127 // with "__dll" suffix. Clients can use the macro WIN_WEAK_IMPORT_DEF(fun) 128 // which defines a "weak alias" fun = fun__dll. 129 // 130 // // libExample.cc 131 // WIN_WEAK_EXPORT_DEF(bool, compare, int a, int b) { return a > b; } 132 // 133 // // client.cc 134 // WIN_WEAK_IMPORT_DEF(compare) 135 // // We can use the default implementation from the library: 136 // compare(1, 2); 137 // // Or we can override it: 138 // extern "C" bool compare (int a, int b) { return a >= b; } 139 // 140 // But if we override the function, the dlls don't have access to it (which 141 // is different in linux). If that is desired, the strong definition must be 142 // exported and interception can be used from the rest of the dlls. 143 // 144 // // libExample.cc 145 // WIN_WEAK_EXPORT_DEF(bool, compare, int a, int b) { return a > b; } 146 // // When initialized, check if the main executable defined "compare". 147 // int libExample_init() { 148 // uptr fnptr = __interception::InternalGetProcAddress( 149 // (void *)GetModuleHandleA(0), "compare"); 150 // if (fnptr && !__interception::OverrideFunction((uptr)compare, fnptr, 0)) 151 // abort(); 152 // return 0; 153 // } 154 // 155 // // client.cc 156 // WIN_WEAK_IMPORT_DEF(compare) 157 // // We override and export compare: 158 // extern "C" __declspec(dllexport) bool compare (int a, int b) { 159 // return a >= b; 160 // } 161 // 162 #endif // SANITIZER_WINDOWS 163 #endif // SANITIZER_WIN_DEFS_H 164