forked from llvm-mirror/llvm
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@271491 91177308-0d34-0410-b5e6-96231b3b80d8
- Loading branch information
Showing
9 changed files
with
171 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
//===- FuzzerExtFunctions.def - External functions --------------*- C++ -* ===// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// This file is distributed under the University of Illinois Open Source | ||
// License. See LICENSE.TXT for details. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// This defines the external function pointers that | ||
// ``fuzzer::ExternalFunctions`` should contain and try to initialize. The | ||
// EXT_FUNC macro must be defined at the point of inclusion. The signature of | ||
// the macro is: | ||
// | ||
// EXT_FUNC(<name>, <return_type>, <function_signature>, <warn_if_missing>) | ||
//===----------------------------------------------------------------------===// | ||
|
||
// Optional user functions | ||
EXT_FUNC(LLVMFuzzerInitialize, int, (int *argc, char ***argv), false); | ||
EXT_FUNC(LLVMFuzzerCustomMutator, size_t, | ||
(uint8_t * Data, size_t Size, size_t MaxSize, unsigned int Seed), | ||
false); | ||
|
||
// TODO: Sanitizer functions |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
//===- FuzzerExtFunctions.h - Interface to external functions ---*- C++ -* ===// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// This file is distributed under the University of Illinois Open Source | ||
// License. See LICENSE.TXT for details. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// Defines an interface to (possibly optional) functions. | ||
//===----------------------------------------------------------------------===// | ||
#ifndef LLVM_FUZZER_EXT_FUNCTIONS_H | ||
#define LLVM_FUZZER_EXT_FUNCTIONS_H | ||
|
||
#include <stddef.h> | ||
#include <stdint.h> | ||
|
||
namespace fuzzer { | ||
|
||
struct ExternalFunctions { | ||
// Initialize function pointers. Functions that are not available | ||
// will be set to nullptr. | ||
ExternalFunctions(); | ||
|
||
#define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) \ | ||
RETURN_TYPE(*NAME) FUNC_SIG = nullptr | ||
|
||
#include "FuzzerExtFunctions.def" | ||
|
||
#undef EXT_FUNC | ||
}; | ||
} // namespace fuzzer | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
//===- FuzzerExtFunctionsWeak.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 Linux. This relies on the linker's support for weak | ||
// symbols. We don't use this approach on Apple platforms because it requires | ||
// clients of LibFuzzer to pass ``-U _<symbol_name>`` to the linker to allow | ||
// weak symbols to be undefined. That is a complication we don't want to expose | ||
// to clients right now. | ||
//===----------------------------------------------------------------------===// | ||
#include "FuzzerInternal.h" | ||
#if LIBFUZZER_LINUX | ||
|
||
#include "FuzzerExtFunctions.h" | ||
|
||
extern "C" { | ||
// Declare these symbols as weak to allow them to be optionally defined. | ||
#define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) \ | ||
__attribute__((weak)) RETURN_TYPE NAME FUNC_SIG | ||
|
||
#include "FuzzerExtFunctions.def" | ||
|
||
#undef EXT_FUNC | ||
} | ||
|
||
using namespace fuzzer; | ||
|
||
static void CheckFnPtr(void *FnPtr, const char *FnName, bool WarnIfMissing) { | ||
if (FnPtr == nullptr && WarnIfMissing) { | ||
Printf("WARNING: Failed to find function \"%s\".\n", FnName); | ||
} | ||
} | ||
|
||
namespace fuzzer { | ||
|
||
ExternalFunctions::ExternalFunctions() { | ||
#define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) \ | ||
this->NAME = ::NAME; \ | ||
CheckFnPtr((void *)::NAME, #NAME, WARN); | ||
|
||
#include "FuzzerExtFunctions.def" | ||
|
||
#undef EXT_FUNC | ||
} | ||
} // namespace fuzzer | ||
#endif // LIBFUZZER_LINUX |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters