[compiler-rt] r350766 - [libfuzzer][MSVC] Make calls to builtin functions work with MSVC

Jonathan Metzman via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 9 13:46:09 PST 2019


Author: metzman
Date: Wed Jan  9 13:46:09 2019
New Revision: 350766

URL: http://llvm.org/viewvc/llvm-project?rev=350766&view=rev
Log:
[libfuzzer][MSVC] Make calls to builtin functions work with MSVC

Summary:
Replace calls to builtin functions with macros or functions that call the
Windows-equivalents when targeting windows and call the original
builtin functions everywhere else.
This change makes more parts of libFuzzer buildable with MSVC.

Reviewers: vitalybuka

Reviewed By: vitalybuka

Subscribers: mgorny, rnk, thakis

Differential Revision: https://reviews.llvm.org/D56439

Added:
    compiler-rt/trunk/lib/fuzzer/FuzzerBuiltins.h
    compiler-rt/trunk/lib/fuzzer/FuzzerBuiltinsMsvc.h
Modified:
    compiler-rt/trunk/lib/fuzzer/CMakeLists.txt
    compiler-rt/trunk/lib/fuzzer/FuzzerDefs.h
    compiler-rt/trunk/lib/fuzzer/FuzzerTracePC.cpp
    compiler-rt/trunk/lib/fuzzer/FuzzerUtil.h

Modified: compiler-rt/trunk/lib/fuzzer/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/CMakeLists.txt?rev=350766&r1=350765&r2=350766&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/fuzzer/CMakeLists.txt Wed Jan  9 13:46:09 2019
@@ -25,6 +25,8 @@ set(LIBFUZZER_SOURCES
   FuzzerUtilWindows.cpp)
 
 set(LIBFUZZER_HEADERS
+  FuzzerBuiltins.h
+  FuzzerBuiltinsMsvc.h
   FuzzerCommand.h
   FuzzerCorpus.h
   FuzzerDataFlowTrace.h

Added: compiler-rt/trunk/lib/fuzzer/FuzzerBuiltins.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerBuiltins.h?rev=350766&view=auto
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerBuiltins.h (added)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerBuiltins.h Wed Jan  9 13:46:09 2019
@@ -0,0 +1,36 @@
+//===- FuzzerBuiltins.h - Internal header for builtins ----------*- C++ -* ===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Wrapper functions and marcos around builtin functions.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_FUZZER_BUILTINS_H
+#define LLVM_FUZZER_BUILTINS_H
+
+#include "FuzzerDefs.h"
+
+#if !LIBFUZZER_MSVC
+#include <cstdint>
+
+#define GET_CALLER_PC() __builtin_return_address(0)
+
+namespace fuzzer {
+
+inline uint8_t  Bswap(uint8_t x)  { return x; }
+inline uint16_t Bswap(uint16_t x) { return __builtin_bswap16(x); }
+inline uint32_t Bswap(uint32_t x) { return __builtin_bswap32(x); }
+inline uint64_t Bswap(uint64_t x) { return __builtin_bswap64(x); }
+
+inline uint32_t Clzll(unsigned long long X) { return __builtin_clzll(X); }
+inline uint32_t Clz(unsigned long long X) { return __builtin_clz(X); }
+inline int Popcountll(unsigned long long X) { return __builtin_popcountll(X); }
+
+}  // namespace fuzzer
+
+#endif  // !LIBFUZZER_MSVC
+#endif  // LLVM_FUZZER_BUILTINS_H

Added: compiler-rt/trunk/lib/fuzzer/FuzzerBuiltinsMsvc.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerBuiltinsMsvc.h?rev=350766&view=auto
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerBuiltinsMsvc.h (added)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerBuiltinsMsvc.h Wed Jan  9 13:46:09 2019
@@ -0,0 +1,59 @@
+//===- FuzzerBuiltinsMSVC.h - Internal header for builtins ------*- C++ -* ===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Wrapper functions and marcos that use intrinsics instead of builtin functions
+// which cannot be compiled by MSVC.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_FUZZER_BUILTINS_MSVC_H
+#define LLVM_FUZZER_BUILTINS_MSVC_H
+
+#include "FuzzerDefs.h"
+
+#if LIBFUZZER_MSVC
+#if !defined(_M_ARM) && !defined(_M_X64)
+#error "_BitScanReverse64 unavailable on this platform so MSVC is unsupported."
+#endif
+#include <intrin.h>
+#include <cstdint>
+#include <cstdlib>
+
+// __builtin_return_address() cannot be compiled with MSVC. Use the equivalent
+// from <intrin.h>
+#define GET_CALLER_PC() reinterpret_cast<uintptr_t>(_ReturnAddress())
+
+namespace fuzzer {
+
+inline uint8_t  Bswap(uint8_t x)  { return x; }
+// Use alternatives to __builtin functions from <stdlib.h> and <intrin.h> on
+// Windows since the builtins are not supported by MSVC.
+inline uint16_t Bswap(uint16_t x) { return _byteswap_ushort(x); }
+inline uint32_t Bswap(uint32_t x) { return _byteswap_ulong(x); }
+inline uint64_t Bswap(uint64_t x) { return _byteswap_uint64(x); }
+
+// The functions below were mostly copied from
+// compiler-rt/lib/builtins/int_lib.h which defines the __builtin functions used
+// outside of Windows.
+inline uint32_t Clzll(uint64_t X) {
+  unsigned long LeadZeroIdx = 0;
+  if (_BitScanReverse64(&LeadZeroIdx, X)) return 63 - LeadZeroIdx;
+  return 64;
+}
+
+inline uint32_t Clz(uint32_t X) {
+  unsigned long LeadZeroIdx = 0;
+  if (_BitScanReverse(&LeadZeroIdx, X)) return 31 - LeadZeroIdx;
+  return 32;
+}
+
+inline int Popcountll(unsigned long long X) { return __popcnt64(X); }
+
+}  // namespace fuzzer
+
+#endif  // LIBFUZER_MSVC
+#endif  // LLVM_FUZZER_BUILTINS_MSVC_H

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerDefs.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerDefs.h?rev=350766&r1=350765&r2=350766&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerDefs.h (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerDefs.h Wed Jan  9 13:46:09 2019
@@ -82,6 +82,13 @@
 #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
@@ -183,11 +190,6 @@ typedef int (*UserCallback)(const uint8_
 
 int FuzzerDriver(int *argc, char ***argv, UserCallback Callback);
 
-inline uint8_t  Bswap(uint8_t x)  { return x; }
-inline uint16_t Bswap(uint16_t x) { return __builtin_bswap16(x); }
-inline uint32_t Bswap(uint32_t x) { return __builtin_bswap32(x); }
-inline uint64_t Bswap(uint64_t x) { return __builtin_bswap64(x); }
-
 uint8_t *ExtraCountersBegin();
 uint8_t *ExtraCountersEnd();
 void ClearExtraCounters();

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerTracePC.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerTracePC.cpp?rev=350766&r1=350765&r2=350766&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerTracePC.cpp (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerTracePC.cpp Wed Jan  9 13:46:09 2019
@@ -13,6 +13,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "FuzzerTracePC.h"
+#include "FuzzerBuiltins.h"
+#include "FuzzerBuiltinsMsvc.h"
 #include "FuzzerCorpus.h"
 #include "FuzzerDefs.h"
 #include "FuzzerDictionary.h"
@@ -446,9 +448,8 @@ void TracePC::HandleCmp(uintptr_t PC, T
       TORC4.Insert(ArgXor, Arg1, Arg2);
   else if (sizeof(T) == 8)
       TORC8.Insert(ArgXor, Arg1, Arg2);
-  uint64_t HammingDistance = __builtin_popcountll(ArgXor); // [0,64]
-  uint64_t AbsoluteDistance =
-      (Arg1 == Arg2 ? 0 : __builtin_clzll(Arg1 - Arg2) + 1);
+  uint64_t HammingDistance = Popcountll(ArgXor);  // [0,64]
+  uint64_t AbsoluteDistance = (Arg1 == Arg2 ? 0 : Clzll(Arg1 - Arg2) + 1);
   ValueProfileMap.AddValue(PC * 128 + HammingDistance);
   ValueProfileMap.AddValue(PC * 128 + 64 + AbsoluteDistance);
 }
@@ -491,7 +492,7 @@ extern "C" {
 ATTRIBUTE_INTERFACE
 ATTRIBUTE_NO_SANITIZE_ALL
 void __sanitizer_cov_trace_pc_guard(uint32_t *Guard) {
-  uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
+  uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
   uint32_t Idx = *Guard;
   __sancov_trace_pc_pcs[Idx] = PC;
   __sancov_trace_pc_guard_8bit_counters[Idx]++;
@@ -502,7 +503,7 @@ void __sanitizer_cov_trace_pc_guard(uint
 ATTRIBUTE_INTERFACE
 ATTRIBUTE_NO_SANITIZE_ALL
 void __sanitizer_cov_trace_pc() {
-  uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
+  uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
   uintptr_t Idx = PC & (((uintptr_t)1 << fuzzer::TracePC::kTracePcBits) - 1);
   __sancov_trace_pc_pcs[Idx] = PC;
   __sancov_trace_pc_guard_8bit_counters[Idx]++;
@@ -527,7 +528,7 @@ void __sanitizer_cov_pcs_init(const uint
 ATTRIBUTE_INTERFACE
 ATTRIBUTE_NO_SANITIZE_ALL
 void __sanitizer_cov_trace_pc_indir(uintptr_t Callee) {
-  uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
+  uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
   fuzzer::TPC.HandleCallerCallee(PC, Callee);
 }
 
@@ -535,7 +536,7 @@ ATTRIBUTE_INTERFACE
 ATTRIBUTE_NO_SANITIZE_ALL
 ATTRIBUTE_TARGET_POPCNT
 void __sanitizer_cov_trace_cmp8(uint64_t Arg1, uint64_t Arg2) {
-  uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
+  uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
   fuzzer::TPC.HandleCmp(PC, Arg1, Arg2);
 }
 
@@ -546,7 +547,7 @@ ATTRIBUTE_TARGET_POPCNT
 // the behaviour of __sanitizer_cov_trace_cmp[1248] ones. This, however,
 // should be changed later to make full use of instrumentation.
 void __sanitizer_cov_trace_const_cmp8(uint64_t Arg1, uint64_t Arg2) {
-  uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
+  uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
   fuzzer::TPC.HandleCmp(PC, Arg1, Arg2);
 }
 
@@ -554,7 +555,7 @@ ATTRIBUTE_INTERFACE
 ATTRIBUTE_NO_SANITIZE_ALL
 ATTRIBUTE_TARGET_POPCNT
 void __sanitizer_cov_trace_cmp4(uint32_t Arg1, uint32_t Arg2) {
-  uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
+  uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
   fuzzer::TPC.HandleCmp(PC, Arg1, Arg2);
 }
 
@@ -562,7 +563,7 @@ ATTRIBUTE_INTERFACE
 ATTRIBUTE_NO_SANITIZE_ALL
 ATTRIBUTE_TARGET_POPCNT
 void __sanitizer_cov_trace_const_cmp4(uint32_t Arg1, uint32_t Arg2) {
-  uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
+  uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
   fuzzer::TPC.HandleCmp(PC, Arg1, Arg2);
 }
 
@@ -570,7 +571,7 @@ ATTRIBUTE_INTERFACE
 ATTRIBUTE_NO_SANITIZE_ALL
 ATTRIBUTE_TARGET_POPCNT
 void __sanitizer_cov_trace_cmp2(uint16_t Arg1, uint16_t Arg2) {
-  uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
+  uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
   fuzzer::TPC.HandleCmp(PC, Arg1, Arg2);
 }
 
@@ -578,7 +579,7 @@ ATTRIBUTE_INTERFACE
 ATTRIBUTE_NO_SANITIZE_ALL
 ATTRIBUTE_TARGET_POPCNT
 void __sanitizer_cov_trace_const_cmp2(uint16_t Arg1, uint16_t Arg2) {
-  uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
+  uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
   fuzzer::TPC.HandleCmp(PC, Arg1, Arg2);
 }
 
@@ -586,7 +587,7 @@ ATTRIBUTE_INTERFACE
 ATTRIBUTE_NO_SANITIZE_ALL
 ATTRIBUTE_TARGET_POPCNT
 void __sanitizer_cov_trace_cmp1(uint8_t Arg1, uint8_t Arg2) {
-  uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
+  uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
   fuzzer::TPC.HandleCmp(PC, Arg1, Arg2);
 }
 
@@ -594,7 +595,7 @@ ATTRIBUTE_INTERFACE
 ATTRIBUTE_NO_SANITIZE_ALL
 ATTRIBUTE_TARGET_POPCNT
 void __sanitizer_cov_trace_const_cmp1(uint8_t Arg1, uint8_t Arg2) {
-  uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
+  uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
   fuzzer::TPC.HandleCmp(PC, Arg1, Arg2);
 }
 
@@ -608,7 +609,7 @@ void __sanitizer_cov_trace_switch(uint64
   // Skip the most common and the most boring case.
   if (Vals[N - 1]  < 256 && Val < 256)
     return;
-  uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
+  uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
   size_t i;
   uint64_t Token = 0;
   for (i = 0; i < N; i++) {
@@ -629,7 +630,7 @@ ATTRIBUTE_INTERFACE
 ATTRIBUTE_NO_SANITIZE_ALL
 ATTRIBUTE_TARGET_POPCNT
 void __sanitizer_cov_trace_div4(uint32_t Val) {
-  uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
+  uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
   fuzzer::TPC.HandleCmp(PC, Val, (uint32_t)0);
 }
 
@@ -637,7 +638,7 @@ ATTRIBUTE_INTERFACE
 ATTRIBUTE_NO_SANITIZE_ALL
 ATTRIBUTE_TARGET_POPCNT
 void __sanitizer_cov_trace_div8(uint64_t Val) {
-  uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
+  uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
   fuzzer::TPC.HandleCmp(PC, Val, (uint64_t)0);
 }
 
@@ -645,7 +646,7 @@ ATTRIBUTE_INTERFACE
 ATTRIBUTE_NO_SANITIZE_ALL
 ATTRIBUTE_TARGET_POPCNT
 void __sanitizer_cov_trace_gep(uintptr_t Idx) {
-  uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
+  uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
   fuzzer::TPC.HandleCmp(PC, Idx, (uintptr_t)0);
 }
 

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerUtil.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerUtil.h?rev=350766&r1=350765&r2=350766&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerUtil.h (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerUtil.h Wed Jan  9 13:46:09 2019
@@ -12,8 +12,10 @@
 #ifndef LLVM_FUZZER_UTIL_H
 #define LLVM_FUZZER_UTIL_H
 
-#include "FuzzerDefs.h"
+#include "FuzzerBuiltins.h"
+#include "FuzzerBuiltinsMsvc.h"
 #include "FuzzerCommand.h"
+#include "FuzzerDefs.h"
 
 namespace fuzzer {
 
@@ -84,7 +86,7 @@ std::string SearchRegexCmd(const std::st
 
 size_t SimpleFastHash(const uint8_t *Data, size_t Size);
 
-inline uint32_t Log(uint32_t X) { return 32 - __builtin_clz(X) - 1; }
+inline uint32_t Log(uint32_t X) { return 32 - Clz(X) - 1; }
 
 }  // namespace fuzzer
 




More information about the llvm-commits mailing list