aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Fuzzer/FuzzerExtFunctionsDlsym.cpp
diff options
context:
space:
mode:
authorDan Liew <dan@su-root.co.uk>2016-06-02 05:48:02 +0000
committerDan Liew <dan@su-root.co.uk>2016-06-02 05:48:02 +0000
commitd3c33116fd1c842d8b8f603eaf04d9ae78fb6e0d (patch)
tree571949acab8a8258bb0d019e3b4da3044bf11117 /llvm/lib/Fuzzer/FuzzerExtFunctionsDlsym.cpp
parent9ded49e8a776ff5a044539f45723e501491f1b4b (diff)
downloadllvm-d3c33116fd1c842d8b8f603eaf04d9ae78fb6e0d.zip
llvm-d3c33116fd1c842d8b8f603eaf04d9ae78fb6e0d.tar.gz
llvm-d3c33116fd1c842d8b8f603eaf04d9ae78fb6e0d.tar.bz2
[LibFuzzer] Reimplement how the optional user functions are called.
The motivation for this change is to fix linking issues on OSX. However this only partially fixes linking issues (the uninstrumented tests and a few others won't succesfully link yet). This change introduces a struct of function pointers (``fuzzer::ExternalFuntions``) which when initialised will point to the optional functions if they are available. Currently these ``LLVMFuzzerInitialize`` and ``LLVMFuzzerCustomMutator`` functions. Two implementations of ``fuzzer::ExternalFunctions`` constructor are provided one for Linux and one for OSX. The OSX implementation uses ``dlsym()`` because the prior implementation using weak symbols does not work unless the additional flags are passed to the linker. The Linux implementation continues to use weak symbols because the ``dlsym()`` approach does not work unless additional flags are passed to the linker. Differential Revision: http://reviews.llvm.org/D20741 llvm-svn: 271491
Diffstat (limited to 'llvm/lib/Fuzzer/FuzzerExtFunctionsDlsym.cpp')
-rw-r--r--llvm/lib/Fuzzer/FuzzerExtFunctionsDlsym.cpp49
1 files changed, 49 insertions, 0 deletions
diff --git a/llvm/lib/Fuzzer/FuzzerExtFunctionsDlsym.cpp b/llvm/lib/Fuzzer/FuzzerExtFunctionsDlsym.cpp
new file mode 100644
index 0000000..7b9681a
--- /dev/null
+++ b/llvm/lib/Fuzzer/FuzzerExtFunctionsDlsym.cpp
@@ -0,0 +1,49 @@
+//===- FuzzerExtFunctionsDlsym.cpp - Interface to external functions ------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Implementation for operating systems that support dlsym(). We only use it on
+// Apple platforms for now. We don't use this approach on Linux because it
+// requires that clients of LibFuzzer pass ``--export-dynamic`` to the linker.
+// That is a complication we don't wish to expose to clients right now.
+//===----------------------------------------------------------------------===//
+#include "FuzzerInternal.h"
+#if LIBFUZZER_APPLE
+
+#include "FuzzerExtFunctions.h"
+#include <dlfcn.h>
+
+using namespace fuzzer;
+
+template <typename T>
+static T GetFnPtr(const char *FnName, bool WarnIfMissing) {
+ dlerror(); // Clear any previous errors.
+ void *Fn = dlsym(RTLD_DEFAULT, FnName);
+ if (Fn == nullptr) {
+ if (WarnIfMissing) {
+ const char *ErrorMsg = dlerror();
+ Printf("WARNING: Failed to find function \"%s\".", FnName);
+ if (ErrorMsg)
+ Printf(" Reason %s.", ErrorMsg);
+ Printf("\n");
+ }
+ }
+ return reinterpret_cast<T>(Fn);
+}
+
+namespace fuzzer {
+
+ExternalFunctions::ExternalFunctions() {
+#define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) \
+ this->NAME = GetFnPtr<decltype(ExternalFunctions::NAME)>(#NAME, WARN)
+
+#include "FuzzerExtFunctions.def"
+
+#undef EXT_FUNC
+}
+} // namespace fuzzer
+#endif // LIBFUZZER_APPLE