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 Andricstatic 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 AndricExternalFunctions::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