[libFuzzer][MSVC] Make attribute-use compatible with MSVC
Summary:
Replace attributes with macros that use equivalent declspecs
for MSVC.
Reviewers: vitalybuka
Reviewed By: vitalybuka
Differential Revision: https://reviews.llvm.org/D56512
llvm-svn: 351456
diff --git a/compiler-rt/lib/fuzzer/FuzzerDefs.h b/compiler-rt/lib/fuzzer/FuzzerDefs.h
index c3dccbc..e1ddd1f 100644
--- a/compiler-rt/lib/fuzzer/FuzzerDefs.h
+++ b/compiler-rt/lib/fuzzer/FuzzerDefs.h
@@ -120,7 +120,28 @@
# 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)
@@ -134,19 +155,6 @@
# define ATTRIBUTE_NO_SANITIZE_ALL
#endif
-#if LIBFUZZER_WINDOWS
-#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 \
- __attribute__((tls_model("initial-exec"))) thread_local static
-#else
-#define ATTRIBUTE_INTERFACE __attribute__((visibility("default")))
-#define ATTRIBUTES_INTERFACE_TLS_INITIAL_EXEC \
- ATTRIBUTE_INTERFACE __attribute__((tls_model("initial-exec"))) thread_local
-#endif
-
namespace fuzzer {
template <class T> T Min(T a, T b) { return a < b ? a : b; }
diff --git a/compiler-rt/lib/fuzzer/FuzzerDriver.cpp b/compiler-rt/lib/fuzzer/FuzzerDriver.cpp
index ff2a639..92d4489 100644
--- a/compiler-rt/lib/fuzzer/FuzzerDriver.cpp
+++ b/compiler-rt/lib/fuzzer/FuzzerDriver.cpp
@@ -29,7 +29,12 @@
// This function should be present in the libFuzzer so that the client
// binary can test for its existence.
+#if LIBFUZZER_MSVC
+extern "C" void __libfuzzer_is_present() {}
+#pragma comment(linker, "/include:__libfuzzer_is_present")
+#else
extern "C" __attribute__((used)) void __libfuzzer_is_present() {}
+#endif // LIBFUZZER_MSVC
namespace fuzzer {
diff --git a/compiler-rt/lib/fuzzer/FuzzerInterface.h b/compiler-rt/lib/fuzzer/FuzzerInterface.h
index 0f7effb..0e76d77 100644
--- a/compiler-rt/lib/fuzzer/FuzzerInterface.h
+++ b/compiler-rt/lib/fuzzer/FuzzerInterface.h
@@ -26,25 +26,32 @@
extern "C" {
#endif // __cplusplus
+// Define FUZZER_INTERFACE_VISIBILITY to set default visibility in a way that
+// doesn't break MSVC.
+#if defined(_MSC_VER) && !defined(__clang__)
+#define FUZZER_INTERFACE_VISIBILITY __declspec(dllexport)
+#else
+#define FUZZER_INTERFACE_VISIBILITY __attribute__((visibility("default")))
+#endif
+
// Mandatory user-provided target function.
// Executes the code under test with [Data, Data+Size) as the input.
// libFuzzer will invoke this function *many* times with different inputs.
// Must return 0.
-__attribute__((visibility("default"))) int
+FUZZER_INTERFACE_VISIBILITY int
LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
// Optional user-provided initialization function.
// If provided, this function will be called by libFuzzer once at startup.
// It may read and modify argc/argv.
// Must return 0.
-__attribute__((visibility("default"))) int LLVMFuzzerInitialize(int *argc,
- char ***argv);
+FUZZER_INTERFACE_VISIBILITY int LLVMFuzzerInitialize(int *argc, char ***argv);
// Optional user-provided custom mutator.
// Mutates raw data in [Data, Data+Size) inplace.
// Returns the new size, which is not greater than MaxSize.
// Given the same Seed produces the same mutation.
-__attribute__((visibility("default"))) size_t
+FUZZER_INTERFACE_VISIBILITY size_t
LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size, size_t MaxSize,
unsigned int Seed);
@@ -52,7 +59,7 @@
// Combines pieces of Data1 & Data2 together into Out.
// Returns the new size, which is not greater than MaxOutSize.
// Should produce the same mutation given the same Seed.
-__attribute__((visibility("default"))) size_t
+FUZZER_INTERFACE_VISIBILITY size_t
LLVMFuzzerCustomCrossOver(const uint8_t *Data1, size_t Size1,
const uint8_t *Data2, size_t Size2, uint8_t *Out,
size_t MaxOutSize, unsigned int Seed);
@@ -61,9 +68,11 @@
// libFuzzer-provided function to be used inside LLVMFuzzerCustomMutator.
// Mutates raw data in [Data, Data+Size) inplace.
// Returns the new size, which is not greater than MaxSize.
-__attribute__((visibility("default"))) size_t
+FUZZER_INTERFACE_VISIBILITY size_t
LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize);
+#undef FUZZER_INTERFACE_VISIBILITY
+
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
diff --git a/compiler-rt/lib/fuzzer/FuzzerLoop.cpp b/compiler-rt/lib/fuzzer/FuzzerLoop.cpp
index a32a307..12bc5c9 100644
--- a/compiler-rt/lib/fuzzer/FuzzerLoop.cpp
+++ b/compiler-rt/lib/fuzzer/FuzzerLoop.cpp
@@ -852,14 +852,14 @@
extern "C" {
-__attribute__((visibility("default"))) size_t
+ATTRIBUTE_INTERFACE size_t
LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize) {
assert(fuzzer::F);
return fuzzer::F->GetMD().DefaultMutate(Data, Size, MaxSize);
}
// Experimental
-__attribute__((visibility("default"))) void
+ATTRIBUTE_INTERFACE void
LLVMFuzzerAnnounceOutput(const uint8_t *Data, size_t Size) {
assert(fuzzer::F);
fuzzer::F->AnnounceOutput(Data, Size);
diff --git a/compiler-rt/lib/fuzzer/FuzzerMain.cpp b/compiler-rt/lib/fuzzer/FuzzerMain.cpp
index f2c8e9c..f66c057 100644
--- a/compiler-rt/lib/fuzzer/FuzzerMain.cpp
+++ b/compiler-rt/lib/fuzzer/FuzzerMain.cpp
@@ -16,6 +16,6 @@
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
} // extern "C"
-__attribute__((visibility("default"))) int main(int argc, char **argv) {
+ATTRIBUTE_INTERFACE int main(int argc, char **argv) {
return fuzzer::FuzzerDriver(&argc, &argv, LLVMFuzzerTestOneInput);
}
diff --git a/compiler-rt/lib/fuzzer/FuzzerTracePC.h b/compiler-rt/lib/fuzzer/FuzzerTracePC.h
index 46d6c24..2dc02a2 100644
--- a/compiler-rt/lib/fuzzer/FuzzerTracePC.h
+++ b/compiler-rt/lib/fuzzer/FuzzerTracePC.h
@@ -229,7 +229,7 @@
template <class Callback> // void Callback(size_t Feature)
ATTRIBUTE_NO_SANITIZE_ADDRESS
-__attribute__((noinline))
+ATTRIBUTE_NOINLINE
void TracePC::CollectFeatures(Callback HandleFeature) const {
uint8_t *Counters = this->Counters();
size_t N = GetNumPCs();
diff --git a/compiler-rt/lib/fuzzer/FuzzerValueBitMap.h b/compiler-rt/lib/fuzzer/FuzzerValueBitMap.h
index 13d7cbd..a7c24f8 100644
--- a/compiler-rt/lib/fuzzer/FuzzerValueBitMap.h
+++ b/compiler-rt/lib/fuzzer/FuzzerValueBitMap.h
@@ -65,7 +65,7 @@
}
private:
- uintptr_t Map[kMapSizeInWords] __attribute__((aligned(512)));
+ ATTRIBUTE_ALIGNED(512) uintptr_t Map[kMapSizeInWords];
};
} // namespace fuzzer