1a4d569bcSJonathan Metzman //=== FuzzerExtWindows.cpp - Interface to external functions --------------===// 2a4d569bcSJonathan Metzman // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6a4d569bcSJonathan Metzman // 7a4d569bcSJonathan Metzman //===----------------------------------------------------------------------===// 8a4d569bcSJonathan Metzman // Implementation of FuzzerExtFunctions for Windows. Uses alternatename when 9a4d569bcSJonathan Metzman // compiled with MSVC. Uses weak aliases when compiled with clang. Unfortunately 10a4d569bcSJonathan Metzman // the method each compiler supports is not supported by the other. 11a4d569bcSJonathan Metzman //===----------------------------------------------------------------------===// 12226866e1SDokyung Song #include "FuzzerPlatform.h" 13a4d569bcSJonathan Metzman #if LIBFUZZER_WINDOWS 14a4d569bcSJonathan Metzman 15a4d569bcSJonathan Metzman #include "FuzzerExtFunctions.h" 16a4d569bcSJonathan Metzman #include "FuzzerIO.h" 17*a6fdfefbSNico Weber #include <stdlib.h> 18a4d569bcSJonathan Metzman 19a4d569bcSJonathan Metzman using namespace fuzzer; 20a4d569bcSJonathan Metzman 21a4d569bcSJonathan Metzman // Intermediate macro to ensure the parameter is expanded before stringified. 22a4d569bcSJonathan Metzman #define STRINGIFY_(A) #A 23a4d569bcSJonathan Metzman #define STRINGIFY(A) STRINGIFY_(A) 24a4d569bcSJonathan Metzman 25a4d569bcSJonathan Metzman #if LIBFUZZER_MSVC 26d54953efSWu Yingcong #define GET_FUNCTION_ADDRESS(fn) &fn 27d54953efSWu Yingcong #else 28d54953efSWu Yingcong #define GET_FUNCTION_ADDRESS(fn) __builtin_function_start(fn) 29d54953efSWu Yingcong #endif // LIBFUZER_MSVC 30d54953efSWu Yingcong 31a4d569bcSJonathan Metzman // Copied from compiler-rt/lib/sanitizer_common/sanitizer_win_defs.h 32a4d569bcSJonathan Metzman #if defined(_M_IX86) || defined(__i386__) 33a4d569bcSJonathan Metzman #define WIN_SYM_PREFIX "_" 34a4d569bcSJonathan Metzman #else 35a4d569bcSJonathan Metzman #define WIN_SYM_PREFIX 36a4d569bcSJonathan Metzman #endif 37a4d569bcSJonathan Metzman 38a4d569bcSJonathan Metzman // Declare external functions as having alternativenames, so that we can 39a4d569bcSJonathan Metzman // determine if they are not defined. 40a4d569bcSJonathan Metzman #define EXTERNAL_FUNC(Name, Default) \ 41a4d569bcSJonathan Metzman __pragma(comment(linker, "/alternatename:" WIN_SYM_PREFIX STRINGIFY( \ 42a4d569bcSJonathan Metzman Name) "=" WIN_SYM_PREFIX STRINGIFY(Default))) 43a4d569bcSJonathan Metzman 44a4d569bcSJonathan Metzman extern "C" { 45a4d569bcSJonathan Metzman #define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) \ 46a4d569bcSJonathan Metzman RETURN_TYPE NAME##Def FUNC_SIG { \ 47a4d569bcSJonathan Metzman Printf("ERROR: Function \"%s\" not defined.\n", #NAME); \ 48a4d569bcSJonathan Metzman exit(1); \ 49a4d569bcSJonathan Metzman } \ 507821f892SJonathan Metzman EXTERNAL_FUNC(NAME, NAME##Def) RETURN_TYPE NAME FUNC_SIG 51a4d569bcSJonathan Metzman 52a4d569bcSJonathan Metzman #include "FuzzerExtFunctions.def" 53a4d569bcSJonathan Metzman 54a4d569bcSJonathan Metzman #undef EXT_FUNC 55a4d569bcSJonathan Metzman } 56a4d569bcSJonathan Metzman 57a4d569bcSJonathan Metzman template <typename T> 58d54953efSWu Yingcong static T *GetFnPtr(void *Fun, void *FunDef, const char *FnName, 59d54953efSWu Yingcong bool WarnIfMissing) { 60a4d569bcSJonathan Metzman if (Fun == FunDef) { 61a4d569bcSJonathan Metzman if (WarnIfMissing) 62a4d569bcSJonathan Metzman Printf("WARNING: Failed to find function \"%s\".\n", FnName); 63a4d569bcSJonathan Metzman return nullptr; 64a4d569bcSJonathan Metzman } 65d54953efSWu Yingcong return (T *)Fun; 66a4d569bcSJonathan Metzman } 67a4d569bcSJonathan Metzman 68a4d569bcSJonathan Metzman namespace fuzzer { 69a4d569bcSJonathan Metzman 70a4d569bcSJonathan Metzman ExternalFunctions::ExternalFunctions() { 71a4d569bcSJonathan Metzman #define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) \ 72d54953efSWu Yingcong this->NAME = GetFnPtr<decltype(::NAME)>(GET_FUNCTION_ADDRESS(::NAME), \ 73d54953efSWu Yingcong GET_FUNCTION_ADDRESS(::NAME##Def), \ 74d54953efSWu Yingcong #NAME, WARN); 75a4d569bcSJonathan Metzman 76a4d569bcSJonathan Metzman #include "FuzzerExtFunctions.def" 77a4d569bcSJonathan Metzman 78a4d569bcSJonathan Metzman #undef EXT_FUNC 79a4d569bcSJonathan Metzman } 80a4d569bcSJonathan Metzman 81a4d569bcSJonathan Metzman } // namespace fuzzer 82a4d569bcSJonathan Metzman 83a4d569bcSJonathan Metzman #endif // LIBFUZZER_WINDOWS 84