Index: compiler-rt/trunk/lib/fuzzer/FuzzerDefs.h =================================================================== --- compiler-rt/trunk/lib/fuzzer/FuzzerDefs.h +++ compiler-rt/trunk/lib/fuzzer/FuzzerDefs.h @@ -120,31 +120,39 @@ # define ALWAYS_INLINE #endif // __clang__ -#define ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address)) - -#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 LIBFUZZER_WINDOWS +#define ATTRIBUTE_NO_SANITIZE_ADDRESS #else -# define ATTRIBUTE_NO_SANITIZE_ALL +#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 \ - __attribute__((tls_model("initial-exec"))) thread_local static +#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 namespace fuzzer { Index: compiler-rt/trunk/lib/fuzzer/FuzzerDriver.cpp =================================================================== --- compiler-rt/trunk/lib/fuzzer/FuzzerDriver.cpp +++ compiler-rt/trunk/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 { Index: compiler-rt/trunk/lib/fuzzer/FuzzerInterface.h =================================================================== --- compiler-rt/trunk/lib/fuzzer/FuzzerInterface.h +++ compiler-rt/trunk/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 Index: compiler-rt/trunk/lib/fuzzer/FuzzerLoop.cpp =================================================================== --- compiler-rt/trunk/lib/fuzzer/FuzzerLoop.cpp +++ compiler-rt/trunk/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); Index: compiler-rt/trunk/lib/fuzzer/FuzzerMain.cpp =================================================================== --- compiler-rt/trunk/lib/fuzzer/FuzzerMain.cpp +++ compiler-rt/trunk/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); } Index: compiler-rt/trunk/lib/fuzzer/FuzzerTracePC.h =================================================================== --- compiler-rt/trunk/lib/fuzzer/FuzzerTracePC.h +++ compiler-rt/trunk/lib/fuzzer/FuzzerTracePC.h @@ -229,7 +229,7 @@ template // 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(); Index: compiler-rt/trunk/lib/fuzzer/FuzzerValueBitMap.h =================================================================== --- compiler-rt/trunk/lib/fuzzer/FuzzerValueBitMap.h +++ compiler-rt/trunk/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