1*4ba319b5SDimitry Andric //===- FuzzerExtFunctionsDlsym.cpp - Interface to external functions ------===//
2*4ba319b5SDimitry Andric //
3*4ba319b5SDimitry Andric //                     The LLVM Compiler Infrastructure
4*4ba319b5SDimitry Andric //
5*4ba319b5SDimitry Andric // This file is distributed under the University of Illinois Open Source
6*4ba319b5SDimitry Andric // License. See LICENSE.TXT for details.
7*4ba319b5SDimitry Andric //
8*4ba319b5SDimitry Andric //===----------------------------------------------------------------------===//
9*4ba319b5SDimitry Andric // Implementation for operating systems that support dlsym(). We only use it on
10*4ba319b5SDimitry Andric // Apple platforms for now. We don't use this approach on Linux because it
11*4ba319b5SDimitry Andric // requires that clients of LibFuzzer pass ``--export-dynamic`` to the linker.
12*4ba319b5SDimitry Andric // That is a complication we don't wish to expose to clients right now.
13*4ba319b5SDimitry Andric //===----------------------------------------------------------------------===//
14*4ba319b5SDimitry Andric #include "FuzzerDefs.h"
15*4ba319b5SDimitry Andric #if LIBFUZZER_APPLE
16*4ba319b5SDimitry Andric 
17*4ba319b5SDimitry Andric #include "FuzzerExtFunctions.h"
18*4ba319b5SDimitry Andric #include "FuzzerIO.h"
19*4ba319b5SDimitry Andric #include <dlfcn.h>
20*4ba319b5SDimitry Andric 
21*4ba319b5SDimitry Andric using namespace fuzzer;
22*4ba319b5SDimitry Andric 
23*4ba319b5SDimitry Andric template <typename T>
GetFnPtr(const char * FnName,bool WarnIfMissing)24*4ba319b5SDimitry Andric static T GetFnPtr(const char *FnName, bool WarnIfMissing) {
25*4ba319b5SDimitry Andric   dlerror(); // Clear any previous errors.
26*4ba319b5SDimitry Andric   void *Fn = dlsym(RTLD_DEFAULT, FnName);
27*4ba319b5SDimitry Andric   if (Fn == nullptr) {
28*4ba319b5SDimitry Andric     if (WarnIfMissing) {
29*4ba319b5SDimitry Andric       const char *ErrorMsg = dlerror();
30*4ba319b5SDimitry Andric       Printf("WARNING: Failed to find function \"%s\".", FnName);
31*4ba319b5SDimitry Andric       if (ErrorMsg)
32*4ba319b5SDimitry Andric         Printf(" Reason %s.", ErrorMsg);
33*4ba319b5SDimitry Andric       Printf("\n");
34*4ba319b5SDimitry Andric     }
35*4ba319b5SDimitry Andric   }
36*4ba319b5SDimitry Andric   return reinterpret_cast<T>(Fn);
37*4ba319b5SDimitry Andric }
38*4ba319b5SDimitry Andric 
39*4ba319b5SDimitry Andric namespace fuzzer {
40*4ba319b5SDimitry Andric 
ExternalFunctions()41*4ba319b5SDimitry Andric ExternalFunctions::ExternalFunctions() {
42*4ba319b5SDimitry Andric #define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN)                            \
43*4ba319b5SDimitry Andric   this->NAME = GetFnPtr<decltype(ExternalFunctions::NAME)>(#NAME, WARN)
44*4ba319b5SDimitry Andric 
45*4ba319b5SDimitry Andric #include "FuzzerExtFunctions.def"
46*4ba319b5SDimitry Andric 
47*4ba319b5SDimitry Andric #undef EXT_FUNC
48*4ba319b5SDimitry Andric }
49*4ba319b5SDimitry Andric 
50*4ba319b5SDimitry Andric } // namespace fuzzer
51*4ba319b5SDimitry Andric 
52*4ba319b5SDimitry Andric #endif // LIBFUZZER_APPLE
53