dokyungs updated this revision to Diff 277620.
dokyungs added a comment.
Herald added a subscriber: krytarowski.

Addressed Matt's comments.

A major change in this round that needs explanation is introduction of 
FuzzerPlatform.h. Previously I defined `strstr` and `strcasestr` with `extern 
"C++"` to workaround conflicting definition errors resulting from including 
<string.h>. But since including it is not necessary when compiling this 
interceptor module, this patch now separates out platform related macros from 
FuzzerDef.h into FuzzerPlatform.h, and the module includes FuzzerPlatform.h, 
not FuzzerDef.h.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83494/new/

https://reviews.llvm.org/D83494

Files:
  clang/include/clang/Driver/SanitizerArgs.h
  clang/lib/Driver/SanitizerArgs.cpp
  clang/lib/Driver/ToolChains/CommonArgs.cpp
  compiler-rt/lib/fuzzer/CMakeLists.txt
  compiler-rt/lib/fuzzer/FuzzerDefs.h
  compiler-rt/lib/fuzzer/FuzzerInterceptors.cpp
  compiler-rt/lib/fuzzer/FuzzerPlatform.h
  compiler-rt/test/fuzzer/memcmp.test
  compiler-rt/test/fuzzer/strcmp.test
  compiler-rt/test/fuzzer/strncmp.test
  compiler-rt/test/fuzzer/strstr.test

Index: compiler-rt/test/fuzzer/strstr.test
===================================================================
--- compiler-rt/test/fuzzer/strstr.test
+++ compiler-rt/test/fuzzer/strstr.test
@@ -1,5 +1,9 @@
 UNSUPPORTED: freebsd
 RUN: %cpp_compiler %S/StrstrTest.cpp -o %t-StrstrTest
-RUN: not %run %t-StrstrTest               -seed=1 -runs=2000000   2>&1 | FileCheck %s
-CHECK: BINGO
+RUN: not %run %t-StrstrTest               -seed=1 -runs=2000000   2>&1 | FileCheck %s --check-prefix=CHECK1
+CHECK1: BINGO
+
+RUN: %cpp_compiler -fno-sanitize=address -fno-builtin-strstr %S/StrstrTest.cpp -o %t-NoAsanStrstrTest
+RUN: not %run %t-StrstrTest               -seed=1 -runs=2000000   2>&1 | FileCheck %s --check-prefix=CHECK2
+CHECK2: BINGO
 
Index: compiler-rt/test/fuzzer/strncmp.test
===================================================================
--- compiler-rt/test/fuzzer/strncmp.test
+++ compiler-rt/test/fuzzer/strncmp.test
@@ -1,5 +1,9 @@
 UNSUPPORTED: freebsd
 RUN: %cpp_compiler %S/StrncmpTest.cpp -o %t-StrncmpTest
-RUN: not %run %t-StrncmpTest              -seed=2 -runs=10000000   2>&1 | FileCheck %s
-CHECK: BINGO
+RUN: not %run %t-StrncmpTest              -seed=2 -runs=10000000   2>&1 | FileCheck %s --check-prefix=CHECK1
+CHECK1: BINGO
+
+RUN: %cpp_compiler -fno-sanitize=address -fno-builtin-strcmp %S/StrncmpTest.cpp -o %t-NoAsanStrncmpTest
+RUN: not %run %t-StrncmpTest              -seed=2 -runs=10000000   2>&1 | FileCheck %s --check-prefix=CHECK2
+CHECK2: BINGO
 
Index: compiler-rt/test/fuzzer/strcmp.test
===================================================================
--- compiler-rt/test/fuzzer/strcmp.test
+++ compiler-rt/test/fuzzer/strcmp.test
@@ -1,5 +1,8 @@
 UNSUPPORTED: freebsd
 RUN: %cpp_compiler %S/StrcmpTest.cpp -o %t-StrcmpTest
-RUN: not %run %t-StrcmpTest               -seed=1 -runs=2000000   2>&1 | FileCheck %s
-CHECK: BINGO
+RUN: not %run %t-StrcmpTest               -seed=1 -runs=2000000   2>&1 | FileCheck %s --check-prefix=CHECK1
+CHECK1: BINGO
 
+RUN: %cpp_compiler -fno-sanitize=address -fno-builtin-strcmp %S/StrcmpTest.cpp -o %t-StrcmpTest
+RUN: not %run %t-StrcmpTest               -seed=1 -runs=2000000   2>&1 | FileCheck %s --check-prefix=CHECK2
+CHECK2: BINGO
Index: compiler-rt/test/fuzzer/memcmp.test
===================================================================
--- compiler-rt/test/fuzzer/memcmp.test
+++ compiler-rt/test/fuzzer/memcmp.test
@@ -1,4 +1,8 @@
 UNSUPPORTED: freebsd
 RUN: %cpp_compiler %S/MemcmpTest.cpp -o %t-MemcmpTest
-RUN: not %run %t-MemcmpTest               -seed=1 -runs=10000000   2>&1 | FileCheck %s
-CHECK: BINGO
+RUN: not %run %t-MemcmpTest               -seed=1 -runs=10000000   2>&1 | FileCheck %s --check-prefix=CHECK1
+CHECK1: BINGO
+
+RUN: %cpp_compiler -fno-sanitize=address -fno-builtin-memcmp %S/MemcmpTest.cpp -o %t-MemcmpTest
+RUN: not %run %t-MemcmpTest               -seed=1 -runs=10000000   2>&1 | FileCheck %s --check-prefix=CHECK2
+CHECK2: BINGO
Index: compiler-rt/lib/fuzzer/FuzzerPlatform.h
===================================================================
--- compiler-rt/lib/fuzzer/FuzzerPlatform.h
+++ compiler-rt/lib/fuzzer/FuzzerPlatform.h
@@ -1,25 +1,16 @@
-//===- FuzzerDefs.h - Internal header for the Fuzzer ------------*- C++ -* ===//
+//===-- FuzzerInterceptors.cpp --------------------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-// Basic definitions.
+//
+// Common platform macros.
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_FUZZER_DEFS_H
-#define LLVM_FUZZER_DEFS_H
-
-#include <cassert>
-#include <cstddef>
-#include <cstdint>
-#include <cstring>
-#include <memory>
-#include <set>
-#include <string>
-#include <vector>
-
+#ifndef LLVM_FUZZER_PLATFORM_H
+#define LLVM_FUZZER_PLATFORM_H
 
 // Platform detection.
 #ifdef __linux__
@@ -106,7 +97,7 @@
 #endif
 
 #ifndef __has_attribute
-#  define __has_attribute(x) 0
+#define __has_attribute(x) 0
 #endif
 
 #define LIBFUZZER_POSIX                                                        \
@@ -114,26 +105,25 @@
    LIBFUZZER_FREEBSD || LIBFUZZER_OPENBSD || LIBFUZZER_EMSCRIPTEN)
 
 #ifdef __x86_64
-#  if __has_attribute(target)
-#    define ATTRIBUTE_TARGET_POPCNT __attribute__((target("popcnt")))
-#  else
-#    define ATTRIBUTE_TARGET_POPCNT
-#  endif
+#if __has_attribute(target)
+#define ATTRIBUTE_TARGET_POPCNT __attribute__((target("popcnt")))
 #else
-#  define ATTRIBUTE_TARGET_POPCNT
+#define ATTRIBUTE_TARGET_POPCNT
+#endif
+#else
+#define ATTRIBUTE_TARGET_POPCNT
 #endif
 
-
-#ifdef __clang__  // avoid gcc warning.
-#  if __has_attribute(no_sanitize)
-#    define ATTRIBUTE_NO_SANITIZE_MEMORY __attribute__((no_sanitize("memory")))
-#  else
-#    define ATTRIBUTE_NO_SANITIZE_MEMORY
-#  endif
-#  define ALWAYS_INLINE __attribute__((always_inline))
+#ifdef __clang__ // avoid gcc warning.
+#if __has_attribute(no_sanitize)
+#define ATTRIBUTE_NO_SANITIZE_MEMORY __attribute__((no_sanitize("memory")))
 #else
-#  define ATTRIBUTE_NO_SANITIZE_MEMORY
-#  define ALWAYS_INLINE
+#define ATTRIBUTE_NO_SANITIZE_MEMORY
+#endif
+#define ALWAYS_INLINE __attribute__((always_inline))
+#else
+#define ATTRIBUTE_NO_SANITIZE_MEMORY
+#define ALWAYS_INLINE
 #endif // __clang__
 
 #if LIBFUZZER_WINDOWS
@@ -153,73 +143,22 @@
 #else
 #define ATTRIBUTE_ALIGNED(X) __attribute__((aligned(X)))
 #define ATTRIBUTE_INTERFACE __attribute__((visibility("default")))
-#define ATTRIBUTES_INTERFACE_TLS_INITIAL_EXEC \
+#define ATTRIBUTES_INTERFACE_TLS_INITIAL_EXEC                                  \
   ATTRIBUTE_INTERFACE __attribute__((tls_model("initial-exec"))) thread_local
 
 #define ATTRIBUTE_NOINLINE __attribute__((noinline))
 #endif
 
 #if defined(__has_feature)
-#  if __has_feature(address_sanitizer)
-#    define ATTRIBUTE_NO_SANITIZE_ALL ATTRIBUTE_NO_SANITIZE_ADDRESS
-#  elif __has_feature(memory_sanitizer)
-#    define ATTRIBUTE_NO_SANITIZE_ALL ATTRIBUTE_NO_SANITIZE_MEMORY
-#  else
-#    define ATTRIBUTE_NO_SANITIZE_ALL
-#  endif
+#if __has_feature(address_sanitizer)
+#define ATTRIBUTE_NO_SANITIZE_ALL ATTRIBUTE_NO_SANITIZE_ADDRESS
+#elif __has_feature(memory_sanitizer)
+#define ATTRIBUTE_NO_SANITIZE_ALL ATTRIBUTE_NO_SANITIZE_MEMORY
 #else
-#  define ATTRIBUTE_NO_SANITIZE_ALL
+#define ATTRIBUTE_NO_SANITIZE_ALL
+#endif
+#else
+#define ATTRIBUTE_NO_SANITIZE_ALL
 #endif
 
-namespace fuzzer {
-
-template <class T> T Min(T a, T b) { return a < b ? a : b; }
-template <class T> T Max(T a, T b) { return a > b ? a : b; }
-
-class Random;
-class Dictionary;
-class DictionaryEntry;
-class MutationDispatcher;
-struct FuzzingOptions;
-class InputCorpus;
-struct InputInfo;
-struct ExternalFunctions;
-
-// Global interface to functions that may or may not be available.
-extern ExternalFunctions *EF;
-
-// We are using a custom allocator to give a different symbol name to STL
-// containers in order to avoid ODR violations.
-template<typename T>
-  class fuzzer_allocator: public std::allocator<T> {
-    public:
-      fuzzer_allocator() = default;
-
-      template<class U>
-      fuzzer_allocator(const fuzzer_allocator<U>&) {}
-
-      template<class Other>
-      struct rebind { typedef fuzzer_allocator<Other> other;  };
-  };
-
-template<typename T>
-using Vector = std::vector<T, fuzzer_allocator<T>>;
-
-template<typename T>
-using Set = std::set<T, std::less<T>, fuzzer_allocator<T>>;
-
-typedef Vector<uint8_t> Unit;
-typedef Vector<Unit> UnitVector;
-typedef int (*UserCallback)(const uint8_t *Data, size_t Size);
-
-int FuzzerDriver(int *argc, char ***argv, UserCallback Callback);
-
-uint8_t *ExtraCountersBegin();
-uint8_t *ExtraCountersEnd();
-void ClearExtraCounters();
-
-extern bool RunningUserCallback;
-
-}  // namespace fuzzer
-
-#endif  // LLVM_FUZZER_DEFS_H
+#endif // LLVM_FUZZER_PLATFORM_H
Index: compiler-rt/lib/fuzzer/FuzzerInterceptors.cpp
===================================================================
--- /dev/null
+++ compiler-rt/lib/fuzzer/FuzzerInterceptors.cpp
@@ -0,0 +1,163 @@
+//===-- FuzzerInterceptors.cpp --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// Intercept certain libc functions to aid fuzzing.
+// Linked only when other RTs that define their own interceptors are not linked.
+//===----------------------------------------------------------------------===//
+
+#include <cstdint>
+
+#include "FuzzerPlatform.h"
+
+#define GET_CALLER_PC() __builtin_return_address(0)
+
+#if LIBFUZZER_LINUX
+
+#define PTR_TO_REAL(x) real_##x
+#define REAL(x) __interception::PTR_TO_REAL(x)
+#define FUNC_TYPE(x) x##_type
+#define DEFINE_REAL(ret_type, func, ...)                                       \
+  typedef ret_type (*FUNC_TYPE(func))(__VA_ARGS__);                            \
+  namespace __interception {                                                   \
+  FUNC_TYPE(func) PTR_TO_REAL(func);                                           \
+  }
+
+#include <dlfcn.h> // for dlsym()
+
+static void *GetFuncAddr(const char *name, uintptr_t wrapper_addr) {
+  void *addr = dlsym(RTLD_NEXT, name);
+  if (!addr) {
+    // If the lookup using RTLD_NEXT failed, the sanitizer runtime library is
+    // later in the library search order than the DSO that we are trying to
+    // intercept, which means that we cannot intercept this function. We still
+    // want the address of the real definition, though, so look it up using
+    // RTLD_DEFAULT.
+    addr = dlsym(RTLD_DEFAULT, name);
+
+    // In case `name' is not loaded, dlsym ends up finding the actual wrapper.
+    // We don't want to intercept the wrapper and have it point to itself.
+    if (reinterpret_cast<uintptr_t>(addr) == wrapper_addr)
+      addr = nullptr;
+  }
+  return addr;
+}
+
+extern "C" {
+
+// NOLINTNEXTLINE
+void __sanitizer_weak_hook_memcmp(void *, const void *, const void *, size_t,
+                                  int);
+// NOLINTNEXTLINE
+void __sanitizer_weak_hook_strncmp(void *, const char *, const char *, size_t,
+                                   int);
+// NOLINTNEXTLINE
+void __sanitizer_weak_hook_strcmp(void *, const char *, const char *, int);
+// NOLINTNEXTLINE
+void __sanitizer_weak_hook_strncasecmp(void *, const char *, const char *,
+                                       size_t, int);
+// NOLINTNEXTLINE
+void __sanitizer_weak_hook_strcasecmp(void *, const char *, const char *, int);
+// NOLINTNEXTLINE
+void __sanitizer_weak_hook_strstr(void *, const char *, const char *, char *);
+// NOLINTNEXTLINE
+void __sanitizer_weak_hook_strcasestr(void *, const char *, const char *,
+                                      char *);
+// NOLINTNEXTLINE
+void __sanitizer_weak_hook_memmem(void *, const void *, size_t, const void *,
+                                  size_t, void *);
+
+DEFINE_REAL(int, memcmp, const void *, const void *, size_t)
+DEFINE_REAL(int, strncmp, const char *, const char *, size_t)
+DEFINE_REAL(int, strcmp, const char *, const char *)
+DEFINE_REAL(int, strncasecmp, const char *, const char *, size_t)
+DEFINE_REAL(int, strcasecmp, const char *, const char *)
+DEFINE_REAL(char *, strstr, const char *, const char *)
+DEFINE_REAL(char *, strcasestr, const char *, const char *)
+DEFINE_REAL(void *, memmem, const void *, size_t, const void *, size_t)
+
+ATTRIBUTE_INTERFACE int memcmp(const void *s1, const void *s2, size_t n) {
+  int result = REAL(memcmp)(s1, s2, n);
+  __sanitizer_weak_hook_memcmp(GET_CALLER_PC(), s1, s2, n, result);
+
+  return result;
+}
+
+ATTRIBUTE_INTERFACE int strncmp(const char *s1, const char *s2, size_t n) {
+  int result = REAL(strncmp)(s1, s2, n);
+  __sanitizer_weak_hook_strncmp(GET_CALLER_PC(), s1, s2, n, result);
+
+  return result;
+}
+
+ATTRIBUTE_INTERFACE int strcmp(const char *s1, const char *s2) {
+  int result = REAL(strcmp)(s1, s2);
+  __sanitizer_weak_hook_strcmp(GET_CALLER_PC(), s1, s2, result);
+
+  return result;
+}
+
+ATTRIBUTE_INTERFACE int strncasecmp(const char *s1, const char *s2, size_t n) {
+  int result = REAL(strncasecmp)(s1, s2, n);
+  __sanitizer_weak_hook_strncasecmp(GET_CALLER_PC(), s1, s2, n, result);
+
+  return result;
+}
+
+ATTRIBUTE_INTERFACE int strcasecmp(const char *s1, const char *s2) {
+  int result = REAL(strcasecmp)(s1, s2);
+  __sanitizer_weak_hook_strcasecmp(GET_CALLER_PC(), s1, s2, result);
+
+  return result;
+}
+
+ATTRIBUTE_INTERFACE char *strstr(const char *s1, const char *s2) {
+  char *result = REAL(strstr)(s1, s2);
+  __sanitizer_weak_hook_strstr(GET_CALLER_PC(), s1, s2, result);
+
+  return result;
+}
+
+ATTRIBUTE_INTERFACE char *strcasestr(const char *s1, const char *s2) {
+  char *result = REAL(strcasestr)(s1, s2);
+  __sanitizer_weak_hook_strcasestr(GET_CALLER_PC(), s1, s2, result);
+
+  return result;
+}
+
+ATTRIBUTE_INTERFACE
+void *memmem(const void *s1, size_t len1, const void *s2, size_t len2) {
+  void *result = REAL(memmem)(s1, len1, s2, len2);
+  __sanitizer_weak_hook_memmem(GET_CALLER_PC(), s1, len1, s2, len2, result);
+
+  return result;
+}
+
+static void __fuzzer_init() {
+  REAL(memcmp) = reinterpret_cast<memcmp_type>(
+      GetFuncAddr("memcmp", reinterpret_cast<uintptr_t>(&memcmp)));
+  REAL(strncmp) = reinterpret_cast<strncmp_type>(
+      GetFuncAddr("strncmp", reinterpret_cast<uintptr_t>(&strncmp)));
+  REAL(strcmp) = reinterpret_cast<strcmp_type>(
+      GetFuncAddr("strcmp", reinterpret_cast<uintptr_t>(&strcmp)));
+  REAL(strncasecmp) = reinterpret_cast<strncasecmp_type>(
+      GetFuncAddr("strncasecmp", reinterpret_cast<uintptr_t>(&strncasecmp)));
+  REAL(strcasecmp) = reinterpret_cast<strcasecmp_type>(
+      GetFuncAddr("strcasecmp", reinterpret_cast<uintptr_t>(&strcasecmp)));
+  REAL(strstr) = reinterpret_cast<strstr_type>(
+      GetFuncAddr("strstr", reinterpret_cast<uintptr_t>(&strstr)));
+  REAL(strcasestr) = reinterpret_cast<strcasestr_type>(
+      GetFuncAddr("strcasestr", reinterpret_cast<uintptr_t>(&strcasestr)));
+  REAL(memmem) = reinterpret_cast<memmem_type>(
+      GetFuncAddr("memmem", reinterpret_cast<uintptr_t>(&memmem)));
+}
+
+__attribute__((section(".preinit_array"), used)) static void (
+    *__local_fuzzer_preinit)(void) = __fuzzer_init;
+
+} // extern "C"
+
+#endif
Index: compiler-rt/lib/fuzzer/FuzzerDefs.h
===================================================================
--- compiler-rt/lib/fuzzer/FuzzerDefs.h
+++ compiler-rt/lib/fuzzer/FuzzerDefs.h
@@ -20,156 +20,7 @@
 #include <string>
 #include <vector>
 
-
-// Platform detection.
-#ifdef __linux__
-#define LIBFUZZER_APPLE 0
-#define LIBFUZZER_FUCHSIA 0
-#define LIBFUZZER_LINUX 1
-#define LIBFUZZER_NETBSD 0
-#define LIBFUZZER_FREEBSD 0
-#define LIBFUZZER_OPENBSD 0
-#define LIBFUZZER_WINDOWS 0
-#define LIBFUZZER_EMSCRIPTEN 0
-#elif __APPLE__
-#define LIBFUZZER_APPLE 1
-#define LIBFUZZER_FUCHSIA 0
-#define LIBFUZZER_LINUX 0
-#define LIBFUZZER_NETBSD 0
-#define LIBFUZZER_FREEBSD 0
-#define LIBFUZZER_OPENBSD 0
-#define LIBFUZZER_WINDOWS 0
-#define LIBFUZZER_EMSCRIPTEN 0
-#elif __NetBSD__
-#define LIBFUZZER_APPLE 0
-#define LIBFUZZER_FUCHSIA 0
-#define LIBFUZZER_LINUX 0
-#define LIBFUZZER_NETBSD 1
-#define LIBFUZZER_FREEBSD 0
-#define LIBFUZZER_OPENBSD 0
-#define LIBFUZZER_WINDOWS 0
-#define LIBFUZZER_EMSCRIPTEN 0
-#elif __FreeBSD__
-#define LIBFUZZER_APPLE 0
-#define LIBFUZZER_FUCHSIA 0
-#define LIBFUZZER_LINUX 0
-#define LIBFUZZER_NETBSD 0
-#define LIBFUZZER_FREEBSD 1
-#define LIBFUZZER_OPENBSD 0
-#define LIBFUZZER_WINDOWS 0
-#define LIBFUZZER_EMSCRIPTEN 0
-#elif __OpenBSD__
-#define LIBFUZZER_APPLE 0
-#define LIBFUZZER_FUCHSIA 0
-#define LIBFUZZER_LINUX 0
-#define LIBFUZZER_NETBSD 0
-#define LIBFUZZER_FREEBSD 0
-#define LIBFUZZER_OPENBSD 1
-#define LIBFUZZER_WINDOWS 0
-#define LIBFUZZER_EMSCRIPTEN 0
-#elif _WIN32
-#define LIBFUZZER_APPLE 0
-#define LIBFUZZER_FUCHSIA 0
-#define LIBFUZZER_LINUX 0
-#define LIBFUZZER_NETBSD 0
-#define LIBFUZZER_FREEBSD 0
-#define LIBFUZZER_OPENBSD 0
-#define LIBFUZZER_WINDOWS 1
-#define LIBFUZZER_EMSCRIPTEN 0
-#elif __Fuchsia__
-#define LIBFUZZER_APPLE 0
-#define LIBFUZZER_FUCHSIA 1
-#define LIBFUZZER_LINUX 0
-#define LIBFUZZER_NETBSD 0
-#define LIBFUZZER_FREEBSD 0
-#define LIBFUZZER_OPENBSD 0
-#define LIBFUZZER_WINDOWS 0
-#define LIBFUZZER_EMSCRIPTEN 0
-#elif __EMSCRIPTEN__
-#define LIBFUZZER_APPLE 0
-#define LIBFUZZER_FUCHSIA 0
-#define LIBFUZZER_LINUX 0
-#define LIBFUZZER_NETBSD 0
-#define LIBFUZZER_FREEBSD 0
-#define LIBFUZZER_OPENBSD 0
-#define LIBFUZZER_WINDOWS 0
-#define LIBFUZZER_EMSCRIPTEN 1
-#else
-#error "Support for your platform has not been implemented"
-#endif
-
-#if defined(_MSC_VER) && !defined(__clang__)
-// MSVC compiler is being used.
-#define LIBFUZZER_MSVC 1
-#else
-#define LIBFUZZER_MSVC 0
-#endif
-
-#ifndef __has_attribute
-#  define __has_attribute(x) 0
-#endif
-
-#define LIBFUZZER_POSIX                                                        \
-  (LIBFUZZER_APPLE || LIBFUZZER_LINUX || LIBFUZZER_NETBSD ||                   \
-   LIBFUZZER_FREEBSD || LIBFUZZER_OPENBSD || LIBFUZZER_EMSCRIPTEN)
-
-#ifdef __x86_64
-#  if __has_attribute(target)
-#    define ATTRIBUTE_TARGET_POPCNT __attribute__((target("popcnt")))
-#  else
-#    define ATTRIBUTE_TARGET_POPCNT
-#  endif
-#else
-#  define ATTRIBUTE_TARGET_POPCNT
-#endif
-
-
-#ifdef __clang__  // avoid gcc warning.
-#  if __has_attribute(no_sanitize)
-#    define ATTRIBUTE_NO_SANITIZE_MEMORY __attribute__((no_sanitize("memory")))
-#  else
-#    define ATTRIBUTE_NO_SANITIZE_MEMORY
-#  endif
-#  define ALWAYS_INLINE __attribute__((always_inline))
-#else
-#  define ATTRIBUTE_NO_SANITIZE_MEMORY
-#  define ALWAYS_INLINE
-#endif // __clang__
-
-#if LIBFUZZER_WINDOWS
-#define ATTRIBUTE_NO_SANITIZE_ADDRESS
-#else
-#define ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address))
-#endif
-
-#if LIBFUZZER_WINDOWS
-#define ATTRIBUTE_ALIGNED(X) __declspec(align(X))
-#define ATTRIBUTE_INTERFACE __declspec(dllexport)
-// This is used for __sancov_lowest_stack which is needed for
-// -fsanitize-coverage=stack-depth. That feature is not yet available on
-// Windows, so make the symbol static to avoid linking errors.
-#define ATTRIBUTES_INTERFACE_TLS_INITIAL_EXEC static
-#define ATTRIBUTE_NOINLINE __declspec(noinline)
-#else
-#define ATTRIBUTE_ALIGNED(X) __attribute__((aligned(X)))
-#define ATTRIBUTE_INTERFACE __attribute__((visibility("default")))
-#define ATTRIBUTES_INTERFACE_TLS_INITIAL_EXEC \
-  ATTRIBUTE_INTERFACE __attribute__((tls_model("initial-exec"))) thread_local
-
-#define ATTRIBUTE_NOINLINE __attribute__((noinline))
-#endif
-
-#if defined(__has_feature)
-#  if __has_feature(address_sanitizer)
-#    define ATTRIBUTE_NO_SANITIZE_ALL ATTRIBUTE_NO_SANITIZE_ADDRESS
-#  elif __has_feature(memory_sanitizer)
-#    define ATTRIBUTE_NO_SANITIZE_ALL ATTRIBUTE_NO_SANITIZE_MEMORY
-#  else
-#    define ATTRIBUTE_NO_SANITIZE_ALL
-#  endif
-#else
-#  define ATTRIBUTE_NO_SANITIZE_ALL
-#endif
+#include "FuzzerPlatform.h"
 
 namespace fuzzer {
 
Index: compiler-rt/lib/fuzzer/CMakeLists.txt
===================================================================
--- compiler-rt/lib/fuzzer/CMakeLists.txt
+++ compiler-rt/lib/fuzzer/CMakeLists.txt
@@ -99,6 +99,13 @@
   CFLAGS ${LIBFUZZER_CFLAGS}
   DEPS ${LIBFUZZER_DEPS})
 
+add_compiler_rt_object_libraries(RTfuzzer_interceptors
+  OS ${FUZZER_SUPPORTED_OS}
+  ARCHS ${FUZZER_SUPPORTED_ARCH}
+  SOURCES FuzzerInterceptors.cpp
+  CFLAGS ${LIBFUZZER_CFLAGS}
+  DEPS ${LIBFUZZER_DEPS})
+
 add_compiler_rt_runtime(clang_rt.fuzzer
   STATIC
   OS ${FUZZER_SUPPORTED_OS}
@@ -115,6 +122,14 @@
   CFLAGS ${LIBFUZZER_CFLAGS}
   PARENT_TARGET fuzzer)
 
+add_compiler_rt_runtime(clang_rt.fuzzer_interceptors
+  STATIC
+  OS ${FUZZER_SUPPORTED_OS}
+  ARCHS ${FUZZER_SUPPORTED_ARCH}
+  OBJECT_LIBS RTfuzzer_interceptors
+  CFLAGS ${LIBFUZZER_CFLAGS}
+  PARENT_TARGET fuzzer)
+
 if(OS_NAME MATCHES "Linux|Fuchsia" AND
    COMPILER_RT_LIBCXX_PATH AND
    COMPILER_RT_LIBCXXABI_PATH)
@@ -148,7 +163,10 @@
     add_dependencies(RTfuzzer.${arch} libcxx_fuzzer_${arch}-build)
     target_compile_options(RTfuzzer_main.${arch} PRIVATE -isystem ${LIBCXX_${arch}_PREFIX}/include/c++/v1)
     add_dependencies(RTfuzzer_main.${arch} libcxx_fuzzer_${arch}-build)
+    target_compile_options(RTfuzzer_interceptors.${arch} PRIVATE -isystem ${LIBCXX_${arch}_PREFIX}/include/c++/v1)
+    add_dependencies(RTfuzzer_interceptors.${arch} libcxx_fuzzer_${arch}-build)
     partially_link_libcxx(fuzzer_no_main ${LIBCXX_${arch}_PREFIX} ${arch})
+    partially_link_libcxx(fuzzer_interceptors ${LIBCXX_${arch}_PREFIX} ${arch})
     partially_link_libcxx(fuzzer ${LIBCXX_${arch}_PREFIX} ${arch})
   endforeach()
 endif()
Index: clang/lib/Driver/ToolChains/CommonArgs.cpp
===================================================================
--- clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -779,6 +779,9 @@
       !Args.hasArg(options::OPT_shared)) {
 
     addSanitizerRuntime(TC, Args, CmdArgs, "fuzzer", false, true);
+    if (SanArgs.needsFuzzerInterceptors())
+      addSanitizerRuntime(TC, Args, CmdArgs, "fuzzer_interceptors", false,
+                          true);
     if (!Args.hasArg(clang::driver::options::OPT_nostdlibxx))
       TC.AddCXXStdlibLibArgs(Args, CmdArgs);
   }
Index: clang/lib/Driver/SanitizerArgs.cpp
===================================================================
--- clang/lib/Driver/SanitizerArgs.cpp
+++ clang/lib/Driver/SanitizerArgs.cpp
@@ -238,6 +238,11 @@
   return TrappingKinds;
 }
 
+bool SanitizerArgs::needsFuzzerInterceptors() const {
+  return needsFuzzer() && !needsAsanRt() && !needsHwasanRt() &&
+         !needsTsanRt() && !needsMsanRt();
+}
+
 bool SanitizerArgs::needsUbsanRt() const {
   // All of these include ubsan.
   if (needsAsanRt() || needsMsanRt() || needsHwasanRt() || needsTsanRt() ||
Index: clang/include/clang/Driver/SanitizerArgs.h
===================================================================
--- clang/include/clang/Driver/SanitizerArgs.h
+++ clang/include/clang/Driver/SanitizerArgs.h
@@ -74,6 +74,7 @@
            !Sanitizers.has(SanitizerKind::Address) &&
            !Sanitizers.has(SanitizerKind::HWAddress);
   }
+  bool needsFuzzerInterceptors() const;
   bool needsUbsanRt() const;
   bool requiresMinimalRuntime() const { return MinimalRuntime; }
   bool needsDfsanRt() const { return Sanitizers.has(SanitizerKind::DataFlow); }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to