13cab2bb3Spatrick //=== FuzzerExtWindows.cpp - Interface to external functions --------------===//
23cab2bb3Spatrick //
33cab2bb3Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
43cab2bb3Spatrick // See https://llvm.org/LICENSE.txt for license information.
53cab2bb3Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63cab2bb3Spatrick //
73cab2bb3Spatrick //===----------------------------------------------------------------------===//
83cab2bb3Spatrick // Implementation of FuzzerExtFunctions for Windows. Uses alternatename when
93cab2bb3Spatrick // compiled with MSVC. Uses weak aliases when compiled with clang. Unfortunately
103cab2bb3Spatrick // the method each compiler supports is not supported by the other.
113cab2bb3Spatrick //===----------------------------------------------------------------------===//
12*1f9cb04fSpatrick #include "FuzzerPlatform.h"
133cab2bb3Spatrick #if LIBFUZZER_WINDOWS
143cab2bb3Spatrick 
153cab2bb3Spatrick #include "FuzzerExtFunctions.h"
163cab2bb3Spatrick #include "FuzzerIO.h"
173cab2bb3Spatrick 
183cab2bb3Spatrick using namespace fuzzer;
193cab2bb3Spatrick 
203cab2bb3Spatrick // Intermediate macro to ensure the parameter is expanded before stringified.
213cab2bb3Spatrick #define STRINGIFY_(A) #A
223cab2bb3Spatrick #define STRINGIFY(A) STRINGIFY_(A)
233cab2bb3Spatrick 
243cab2bb3Spatrick #if LIBFUZZER_MSVC
253cab2bb3Spatrick // Copied from compiler-rt/lib/sanitizer_common/sanitizer_win_defs.h
263cab2bb3Spatrick #if defined(_M_IX86) || defined(__i386__)
273cab2bb3Spatrick #define WIN_SYM_PREFIX "_"
283cab2bb3Spatrick #else
293cab2bb3Spatrick #define WIN_SYM_PREFIX
303cab2bb3Spatrick #endif
313cab2bb3Spatrick 
323cab2bb3Spatrick // Declare external functions as having alternativenames, so that we can
333cab2bb3Spatrick // determine if they are not defined.
343cab2bb3Spatrick #define EXTERNAL_FUNC(Name, Default)                                   \
353cab2bb3Spatrick   __pragma(comment(linker, "/alternatename:" WIN_SYM_PREFIX STRINGIFY( \
363cab2bb3Spatrick                                Name) "=" WIN_SYM_PREFIX STRINGIFY(Default)))
373cab2bb3Spatrick #else
383cab2bb3Spatrick // Declare external functions as weak to allow them to default to a specified
393cab2bb3Spatrick // function if not defined explicitly. We must use weak symbols because clang's
403cab2bb3Spatrick // support for alternatename is not 100%, see
413cab2bb3Spatrick // https://bugs.llvm.org/show_bug.cgi?id=40218 for more details.
423cab2bb3Spatrick #define EXTERNAL_FUNC(Name, Default) \
433cab2bb3Spatrick   __attribute__((weak, alias(STRINGIFY(Default))))
443cab2bb3Spatrick #endif  // LIBFUZZER_MSVC
453cab2bb3Spatrick 
463cab2bb3Spatrick extern "C" {
473cab2bb3Spatrick #define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN)         \
483cab2bb3Spatrick   RETURN_TYPE NAME##Def FUNC_SIG {                          \
493cab2bb3Spatrick     Printf("ERROR: Function \"%s\" not defined.\n", #NAME); \
503cab2bb3Spatrick     exit(1);                                                \
513cab2bb3Spatrick   }                                                         \
523cab2bb3Spatrick   EXTERNAL_FUNC(NAME, NAME##Def) RETURN_TYPE NAME FUNC_SIG
533cab2bb3Spatrick 
543cab2bb3Spatrick #include "FuzzerExtFunctions.def"
553cab2bb3Spatrick 
563cab2bb3Spatrick #undef EXT_FUNC
573cab2bb3Spatrick }
583cab2bb3Spatrick 
593cab2bb3Spatrick template <typename T>
GetFnPtr(T * Fun,T * FunDef,const char * FnName,bool WarnIfMissing)603cab2bb3Spatrick static T *GetFnPtr(T *Fun, T *FunDef, const char *FnName, bool WarnIfMissing) {
613cab2bb3Spatrick   if (Fun == FunDef) {
623cab2bb3Spatrick     if (WarnIfMissing)
633cab2bb3Spatrick       Printf("WARNING: Failed to find function \"%s\".\n", FnName);
643cab2bb3Spatrick     return nullptr;
653cab2bb3Spatrick   }
663cab2bb3Spatrick   return Fun;
673cab2bb3Spatrick }
683cab2bb3Spatrick 
693cab2bb3Spatrick namespace fuzzer {
703cab2bb3Spatrick 
ExternalFunctions()713cab2bb3Spatrick ExternalFunctions::ExternalFunctions() {
723cab2bb3Spatrick #define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) \
733cab2bb3Spatrick   this->NAME = GetFnPtr<decltype(::NAME)>(::NAME, ::NAME##Def, #NAME, WARN);
743cab2bb3Spatrick 
753cab2bb3Spatrick #include "FuzzerExtFunctions.def"
763cab2bb3Spatrick 
773cab2bb3Spatrick #undef EXT_FUNC
783cab2bb3Spatrick }
793cab2bb3Spatrick 
803cab2bb3Spatrick }  // namespace fuzzer
813cab2bb3Spatrick 
823cab2bb3Spatrick #endif // LIBFUZZER_WINDOWS
83