xref: /src/contrib/llvm-project/compiler-rt/lib/fuzzer/FuzzerExtFunctionsWindows.cpp (revision 5ffd83dbcc34f10e07f6d3e968ae6365869615f4)
10646903fSDimitry Andric //=== FuzzerExtWindows.cpp - Interface to external functions --------------===//
20646903fSDimitry Andric //
38f3cadc2SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
48f3cadc2SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
58f3cadc2SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60646903fSDimitry Andric //
70646903fSDimitry Andric //===----------------------------------------------------------------------===//
80646903fSDimitry Andric // Implementation of FuzzerExtFunctions for Windows. Uses alternatename when
90646903fSDimitry Andric // compiled with MSVC. Uses weak aliases when compiled with clang. Unfortunately
100646903fSDimitry Andric // the method each compiler supports is not supported by the other.
110646903fSDimitry Andric //===----------------------------------------------------------------------===//
12cfca06d7SDimitry Andric #include "FuzzerPlatform.h"
130646903fSDimitry Andric #if LIBFUZZER_WINDOWS
140646903fSDimitry Andric 
150646903fSDimitry Andric #include "FuzzerExtFunctions.h"
160646903fSDimitry Andric #include "FuzzerIO.h"
170646903fSDimitry Andric 
180646903fSDimitry Andric using namespace fuzzer;
190646903fSDimitry Andric 
200646903fSDimitry Andric // Intermediate macro to ensure the parameter is expanded before stringified.
210646903fSDimitry Andric #define STRINGIFY_(A) #A
220646903fSDimitry Andric #define STRINGIFY(A) STRINGIFY_(A)
230646903fSDimitry Andric 
240646903fSDimitry Andric #if LIBFUZZER_MSVC
250646903fSDimitry Andric // Copied from compiler-rt/lib/sanitizer_common/sanitizer_win_defs.h
260646903fSDimitry Andric #if defined(_M_IX86) || defined(__i386__)
270646903fSDimitry Andric #define WIN_SYM_PREFIX "_"
280646903fSDimitry Andric #else
290646903fSDimitry Andric #define WIN_SYM_PREFIX
300646903fSDimitry Andric #endif
310646903fSDimitry Andric 
320646903fSDimitry Andric // Declare external functions as having alternativenames, so that we can
330646903fSDimitry Andric // determine if they are not defined.
340646903fSDimitry Andric #define EXTERNAL_FUNC(Name, Default)                                   \
350646903fSDimitry Andric   __pragma(comment(linker, "/alternatename:" WIN_SYM_PREFIX STRINGIFY( \
360646903fSDimitry Andric                                Name) "=" WIN_SYM_PREFIX STRINGIFY(Default)))
370646903fSDimitry Andric #else
380646903fSDimitry Andric // Declare external functions as weak to allow them to default to a specified
390646903fSDimitry Andric // function if not defined explicitly. We must use weak symbols because clang's
400646903fSDimitry Andric // support for alternatename is not 100%, see
410646903fSDimitry Andric // https://bugs.llvm.org/show_bug.cgi?id=40218 for more details.
420646903fSDimitry Andric #define EXTERNAL_FUNC(Name, Default) \
430646903fSDimitry Andric   __attribute__((weak, alias(STRINGIFY(Default))))
440646903fSDimitry Andric #endif  // LIBFUZZER_MSVC
450646903fSDimitry Andric 
460646903fSDimitry Andric extern "C" {
470646903fSDimitry Andric #define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN)         \
480646903fSDimitry Andric   RETURN_TYPE NAME##Def FUNC_SIG {                          \
490646903fSDimitry Andric     Printf("ERROR: Function \"%s\" not defined.\n", #NAME); \
500646903fSDimitry Andric     exit(1);                                                \
510646903fSDimitry Andric   }                                                         \
528f3cadc2SDimitry Andric   EXTERNAL_FUNC(NAME, NAME##Def) RETURN_TYPE NAME FUNC_SIG
530646903fSDimitry Andric 
540646903fSDimitry Andric #include "FuzzerExtFunctions.def"
550646903fSDimitry Andric 
560646903fSDimitry Andric #undef EXT_FUNC
570646903fSDimitry Andric }
580646903fSDimitry Andric 
590646903fSDimitry Andric template <typename T>
GetFnPtr(T * Fun,T * FunDef,const char * FnName,bool WarnIfMissing)600646903fSDimitry Andric static T *GetFnPtr(T *Fun, T *FunDef, const char *FnName, bool WarnIfMissing) {
610646903fSDimitry Andric   if (Fun == FunDef) {
620646903fSDimitry Andric     if (WarnIfMissing)
630646903fSDimitry Andric       Printf("WARNING: Failed to find function \"%s\".\n", FnName);
640646903fSDimitry Andric     return nullptr;
650646903fSDimitry Andric   }
660646903fSDimitry Andric   return Fun;
670646903fSDimitry Andric }
680646903fSDimitry Andric 
690646903fSDimitry Andric namespace fuzzer {
700646903fSDimitry Andric 
ExternalFunctions()710646903fSDimitry Andric ExternalFunctions::ExternalFunctions() {
720646903fSDimitry Andric #define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) \
730646903fSDimitry Andric   this->NAME = GetFnPtr<decltype(::NAME)>(::NAME, ::NAME##Def, #NAME, WARN);
740646903fSDimitry Andric 
750646903fSDimitry Andric #include "FuzzerExtFunctions.def"
760646903fSDimitry Andric 
770646903fSDimitry Andric #undef EXT_FUNC
780646903fSDimitry Andric }
790646903fSDimitry Andric 
800646903fSDimitry Andric }  // namespace fuzzer
810646903fSDimitry Andric 
820646903fSDimitry Andric #endif // LIBFUZZER_WINDOWS
83