Index: compiler-rt/lib/fuzzer/CMakeLists.txt =================================================================== --- compiler-rt/lib/fuzzer/CMakeLists.txt +++ compiler-rt/lib/fuzzer/CMakeLists.txt @@ -2,6 +2,7 @@ FuzzerCrossOver.cpp FuzzerDataFlowTrace.cpp FuzzerDriver.cpp + FuzzerExtFunctionsAlternatename.cpp FuzzerExtFunctionsDlsym.cpp FuzzerExtFunctionsWeakAlias.cpp FuzzerExtFunctionsWeak.cpp Index: compiler-rt/lib/fuzzer/FuzzerExtFunctionsAlternatename.cpp =================================================================== --- /dev/null +++ compiler-rt/lib/fuzzer/FuzzerExtFunctionsAlternatename.cpp @@ -0,0 +1,73 @@ +//=== FuzzerExtFunctionsAlternatename.cpp - Interface to external functions ===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Implementation using alternatenames. Works for MSVC on Windows. +// Does not work with clang (see https://bugs.llvm.org/show_bug.cgi?id=40218#c0 +// for more details. +//===----------------------------------------------------------------------===// +#include "FuzzerDefs.h" +#if LIBFUZZER_WINDOWS && LIBFUZZER_MSVC + +#include "FuzzerExtFunctions.h" +#include "FuzzerIO.h" + +using namespace fuzzer; + +extern "C" { +// Declare these symbols as weak to allow them to default to a specified +// function if not defined explicitly. +// Copied from compiler-rt/lib/sanitizer_common/sanitizer_win_defs.h +#if defined(_M_IX86) || defined(__i386__) +#define WIN_SYM_PREFIX "_" +#else +#define WIN_SYM_PREFIX +#endif + +// Intermediate macro to ensure the parameter is expanded before stringified. +#define STRINGIFY_(A) #A +#define STRINGIFY(A) STRINGIFY_(A) + +#define WIN_WEAK_ALIAS(Name, Default) \ + __pragma(comment(linker, "/alternatename:" WIN_SYM_PREFIX STRINGIFY( \ + Name) "=" WIN_SYM_PREFIX STRINGIFY(Default))) + +#define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) \ + RETURN_TYPE NAME##Def FUNC_SIG { \ + Printf("ERROR: Function \"%s\" not defined.\n", #NAME); \ + exit(1); \ + } \ + WIN_WEAK_ALIAS(NAME, NAME##Def) RETURN_TYPE NAME FUNC_SIG; +#include "FuzzerExtFunctions.def" + +#undef EXT_FUNC +} + +template +static T *GetFnPtr(T *Fun, T *FunDef, const char *FnName, bool WarnIfMissing) { + if (Fun == FunDef) { + if (WarnIfMissing) + Printf("WARNING: Failed to find function \"%s\".\n", FnName); + return nullptr; + } + return Fun; +} + +namespace fuzzer { + +ExternalFunctions::ExternalFunctions() { +#define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) \ + this->NAME = GetFnPtr(::NAME, ::NAME##Def, #NAME, WARN); + +#include "FuzzerExtFunctions.def" + +#undef EXT_FUNC +} + +} // namespace fuzzer + +#endif // LIBFUZZER_WINDOWS && LIBFUZZER_MSVC Index: compiler-rt/lib/fuzzer/FuzzerExtFunctionsWeakAlias.cpp =================================================================== --- compiler-rt/lib/fuzzer/FuzzerExtFunctionsWeakAlias.cpp +++ compiler-rt/lib/fuzzer/FuzzerExtFunctionsWeakAlias.cpp @@ -6,10 +6,10 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// Implementation using weak aliases. Works for Windows. +// Implementation using weak aliases. Works for clang on Windows. //===----------------------------------------------------------------------===// #include "FuzzerDefs.h" -#if LIBFUZZER_WINDOWS +#if LIBFUZZER_WINDOWS && !LIBFUZZER_MSVC #include "FuzzerExtFunctions.h" #include "FuzzerIO.h" @@ -53,4 +53,4 @@ } // namespace fuzzer -#endif // LIBFUZZER_WINDOWS +#endif // LIBFUZZER_WINDOWS && !LIBFUZZER_MSVC