[llvm] r271491 - [LibFuzzer] Reimplement how the optional user functions are called.

Eric Christopher via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 7 17:40:54 PDT 2017


Hi Dan,

So this is causing warnings and breaking Werror builds:

/usr/local/google/home/echristo/sources/llvm/lib/Fuzzer/FuzzerExtFunctions.def:29:10:
warning: ISO C++ forbids casting between pointer-to-function and
pointer-to-object [-Wpedantic]
 EXT_FUNC(__lsan_enable, void, (), false);
          ^
/usr/local/google/home/echristo/sources/llvm/lib/Fuzzer/FuzzerExtFunctionsWeak.cpp:44:24:
note: in definition of macro ‘EXT_FUNC’
   CheckFnPtr((void *)::NAME, #NAME, WARN);
                        ^

Feel like fixing? :)

-eric

On Wed, Jun 1, 2016 at 10:54 PM Dan Liew via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

> Author: delcypher
> Date: Thu Jun  2 00:48:02 2016
> New Revision: 271491
>
> URL: http://llvm.org/viewvc/llvm-project?rev=271491&view=rev
> Log:
> [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
>
> Added:
>     llvm/trunk/lib/Fuzzer/FuzzerExtFunctions.def
>     llvm/trunk/lib/Fuzzer/FuzzerExtFunctions.h
>     llvm/trunk/lib/Fuzzer/FuzzerExtFunctionsDlsym.cpp
>     llvm/trunk/lib/Fuzzer/FuzzerExtFunctionsWeak.cpp
> Modified:
>     llvm/trunk/lib/Fuzzer/CMakeLists.txt
>     llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp
>     llvm/trunk/lib/Fuzzer/FuzzerInternal.h
>     llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp
>     llvm/trunk/lib/Fuzzer/FuzzerMain.cpp
>
> Modified: llvm/trunk/lib/Fuzzer/CMakeLists.txt
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/CMakeLists.txt?rev=271491&r1=271490&r2=271491&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Fuzzer/CMakeLists.txt (original)
> +++ llvm/trunk/lib/Fuzzer/CMakeLists.txt Thu Jun  2 00:48:02 2016
> @@ -12,6 +12,8 @@ if( LLVM_USE_SANITIZE_COVERAGE )
>      FuzzerCrossOver.cpp
>      FuzzerTraceState.cpp
>      FuzzerDriver.cpp
> +    FuzzerExtFunctionsDlsym.cpp
> +    FuzzerExtFunctionsWeak.cpp
>      FuzzerIO.cpp
>      FuzzerLoop.cpp
>      FuzzerMutate.cpp
>
> Modified: llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp?rev=271491&r1=271490&r2=271491&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp (original)
> +++ llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp Thu Jun  2 00:48:02 2016
> @@ -266,9 +266,13 @@ static bool AllInputsAreFiles() {
>    return true;
>  }
>
> -static int FuzzerDriver(const std::vector<std::string> &Args,
> -                        UserCallback Callback) {
> +int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
>    using namespace fuzzer;
> +  assert(argc && argv && "Argument pointers cannot be nullptr");
> +  fuzzer::ExternalFunctions EF;
> +  if (EF.LLVMFuzzerInitialize)
> +    EF.LLVMFuzzerInitialize(argc, argv);
> +  const std::vector<std::string> Args(*argv, *argv + *argc);
>    assert(!Args.empty());
>    ProgName = new std::string(Args[0]);
>    ParseFlags(Args);
> @@ -417,10 +421,4 @@ static int FuzzerDriver(const std::vecto
>
>    exit(0);  // Don't let F destroy itself.
>  }
> -
> -int FuzzerDriver(int argc, char **argv, UserCallback Callback) {
> -  std::vector<std::string> Args(argv, argv + argc);
> -  return FuzzerDriver(Args, Callback);
> -}
> -
>  }  // namespace fuzzer
>
> Added: llvm/trunk/lib/Fuzzer/FuzzerExtFunctions.def
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerExtFunctions.def?rev=271491&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Fuzzer/FuzzerExtFunctions.def (added)
> +++ llvm/trunk/lib/Fuzzer/FuzzerExtFunctions.def Thu Jun  2 00:48:02 2016
> @@ -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
>
> Added: llvm/trunk/lib/Fuzzer/FuzzerExtFunctions.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerExtFunctions.h?rev=271491&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Fuzzer/FuzzerExtFunctions.h (added)
> +++ llvm/trunk/lib/Fuzzer/FuzzerExtFunctions.h Thu Jun  2 00:48:02 2016
> @@ -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
>
> Added: llvm/trunk/lib/Fuzzer/FuzzerExtFunctionsDlsym.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerExtFunctionsDlsym.cpp?rev=271491&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Fuzzer/FuzzerExtFunctionsDlsym.cpp (added)
> +++ llvm/trunk/lib/Fuzzer/FuzzerExtFunctionsDlsym.cpp Thu Jun  2 00:48:02
> 2016
> @@ -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
>
> Added: llvm/trunk/lib/Fuzzer/FuzzerExtFunctionsWeak.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerExtFunctionsWeak.cpp?rev=271491&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Fuzzer/FuzzerExtFunctionsWeak.cpp (added)
> +++ llvm/trunk/lib/Fuzzer/FuzzerExtFunctionsWeak.cpp Thu Jun  2 00:48:02
> 2016
> @@ -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
>
> Modified: llvm/trunk/lib/Fuzzer/FuzzerInternal.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerInternal.h?rev=271491&r1=271490&r2=271491&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Fuzzer/FuzzerInternal.h (original)
> +++ llvm/trunk/lib/Fuzzer/FuzzerInternal.h Thu Jun  2 00:48:02 2016
> @@ -25,6 +25,7 @@
>  #include <unordered_set>
>  #include <vector>
>
> +#include "FuzzerExtFunctions.h"
>  #include "FuzzerInterface.h"
>  #include "FuzzerTracePC.h"
>
> @@ -42,7 +43,7 @@
>  namespace fuzzer {
>
>  typedef int (*UserCallback)(const uint8_t *Data, size_t Size);
> -int FuzzerDriver(int argc, char **argv, UserCallback Callback);
> +int FuzzerDriver(int *argc, char ***argv, UserCallback Callback);
>
>  using namespace std::chrono;
>  typedef std::vector<uint8_t> Unit;
> @@ -468,6 +469,9 @@ private:
>
>    // Need to know our own thread.
>    static thread_local bool IsMyThread;
> +
> +  // Interface to functions that may or may not be available.
> +  ExternalFunctions EF;
>  };
>
>  }; // namespace fuzzer
>
> Modified: llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp?rev=271491&r1=271490&r2=271491&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp (original)
> +++ llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp Thu Jun  2 00:48:02 2016
> @@ -47,9 +47,6 @@ __sanitizer_update_counter_bitset_and_cl
>  __attribute__((weak)) uintptr_t
>  __sanitizer_get_coverage_pc_buffer(uintptr_t **data);
>
> -__attribute__((weak)) size_t LLVMFuzzerCustomMutator(uint8_t *Data,
> size_t Size,
> -                                                     size_t MaxSize,
> -                                                     unsigned int Seed);
>  __attribute__((weak)) void __sanitizer_malloc_hook(void *ptr, size_t
> size);
>  __attribute__((weak)) void __sanitizer_free_hook(void *ptr);
>  __attribute__((weak)) void __lsan_enable();
> @@ -695,9 +692,9 @@ void Fuzzer::MutateAndTestOne() {
>
>    for (int i = 0; i < Options.MutateDepth; i++) {
>      size_t NewSize = 0;
> -    if (LLVMFuzzerCustomMutator)
> -      NewSize = LLVMFuzzerCustomMutator(CurrentUnitData, Size,
> -                                        Options.MaxLen,
> MD.GetRand().Rand());
> +    if (EF.LLVMFuzzerCustomMutator)
> +      NewSize = EF.LLVMFuzzerCustomMutator(CurrentUnitData, Size,
> +                                           Options.MaxLen,
> MD.GetRand().Rand());
>      else
>        NewSize = MD.Mutate(CurrentUnitData, Size, Options.MaxLen);
>      assert(NewSize > 0 && "Mutator returned empty unit");
>
> Modified: llvm/trunk/lib/Fuzzer/FuzzerMain.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerMain.cpp?rev=271491&r1=271490&r2=271491&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Fuzzer/FuzzerMain.cpp (original)
> +++ llvm/trunk/lib/Fuzzer/FuzzerMain.cpp Thu Jun  2 00:48:02 2016
> @@ -15,12 +15,8 @@
>  extern "C" {
>  // This function should be defined by the user.
>  int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
> -// This function may optionally be defined by the user.
> -__attribute__((weak)) int LLVMFuzzerInitialize(int *argc, char ***argv);
>  }  // extern "C"
>
>  int main(int argc, char **argv) {
> -  if (LLVMFuzzerInitialize)
> -    LLVMFuzzerInitialize(&argc, &argv);
> -  return fuzzer::FuzzerDriver(argc, argv, LLVMFuzzerTestOneInput);
> +  return fuzzer::FuzzerDriver(&argc, &argv, LLVMFuzzerTestOneInput);
>  }
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170708/ac3349aa/attachment.html>


More information about the llvm-commits mailing list