110ab2aceSGeorge Karpenkov //===- FuzzerExtFunctionsDlsym.cpp - Interface to external functions ------===//
210ab2aceSGeorge Karpenkov //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
610ab2aceSGeorge Karpenkov //
710ab2aceSGeorge Karpenkov //===----------------------------------------------------------------------===//
810ab2aceSGeorge Karpenkov // Implementation for operating systems that support dlsym(). We only use it on
910ab2aceSGeorge Karpenkov // Apple platforms for now. We don't use this approach on Linux because it
1010ab2aceSGeorge Karpenkov // requires that clients of LibFuzzer pass ``--export-dynamic`` to the linker.
1110ab2aceSGeorge Karpenkov // That is a complication we don't wish to expose to clients right now.
1210ab2aceSGeorge Karpenkov //===----------------------------------------------------------------------===//
13*226866e1SDokyung Song #include "FuzzerPlatform.h"
1410ab2aceSGeorge Karpenkov #if LIBFUZZER_APPLE
1510ab2aceSGeorge Karpenkov
1610ab2aceSGeorge Karpenkov #include "FuzzerExtFunctions.h"
1710ab2aceSGeorge Karpenkov #include "FuzzerIO.h"
1810ab2aceSGeorge Karpenkov #include <dlfcn.h>
1910ab2aceSGeorge Karpenkov
2010ab2aceSGeorge Karpenkov using namespace fuzzer;
2110ab2aceSGeorge Karpenkov
2210ab2aceSGeorge Karpenkov template <typename T>
GetFnPtr(const char * FnName,bool WarnIfMissing)2310ab2aceSGeorge Karpenkov static T GetFnPtr(const char *FnName, bool WarnIfMissing) {
2410ab2aceSGeorge Karpenkov dlerror(); // Clear any previous errors.
2510ab2aceSGeorge Karpenkov void *Fn = dlsym(RTLD_DEFAULT, FnName);
2610ab2aceSGeorge Karpenkov if (Fn == nullptr) {
2710ab2aceSGeorge Karpenkov if (WarnIfMissing) {
2810ab2aceSGeorge Karpenkov const char *ErrorMsg = dlerror();
2910ab2aceSGeorge Karpenkov Printf("WARNING: Failed to find function \"%s\".", FnName);
3010ab2aceSGeorge Karpenkov if (ErrorMsg)
3110ab2aceSGeorge Karpenkov Printf(" Reason %s.", ErrorMsg);
3210ab2aceSGeorge Karpenkov Printf("\n");
3310ab2aceSGeorge Karpenkov }
3410ab2aceSGeorge Karpenkov }
3510ab2aceSGeorge Karpenkov return reinterpret_cast<T>(Fn);
3610ab2aceSGeorge Karpenkov }
3710ab2aceSGeorge Karpenkov
3810ab2aceSGeorge Karpenkov namespace fuzzer {
3910ab2aceSGeorge Karpenkov
ExternalFunctions()4010ab2aceSGeorge Karpenkov ExternalFunctions::ExternalFunctions() {
4110ab2aceSGeorge Karpenkov #define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) \
4210ab2aceSGeorge Karpenkov this->NAME = GetFnPtr<decltype(ExternalFunctions::NAME)>(#NAME, WARN)
4310ab2aceSGeorge Karpenkov
4410ab2aceSGeorge Karpenkov #include "FuzzerExtFunctions.def"
4510ab2aceSGeorge Karpenkov
4610ab2aceSGeorge Karpenkov #undef EXT_FUNC
4710ab2aceSGeorge Karpenkov }
4810ab2aceSGeorge Karpenkov
4910ab2aceSGeorge Karpenkov } // namespace fuzzer
5010ab2aceSGeorge Karpenkov
5110ab2aceSGeorge Karpenkov #endif // LIBFUZZER_APPLE
52