1 //===- FuzzerDefs.h - Internal header for the Fuzzer ------------*- C++ -* ===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // Basic definitions. 9 //===----------------------------------------------------------------------===// 10 11 #ifndef LLVM_FUZZER_DEFS_H 12 #define LLVM_FUZZER_DEFS_H 13 14 #include <cassert> 15 #include <cstddef> 16 #include <cstdint> 17 #include <cstring> 18 #include <memory> 19 #include <set> 20 #include <string> 21 #include <vector> 22 23 24 // Platform detection. 25 #ifdef __linux__ 26 #define LIBFUZZER_APPLE 0 27 #define LIBFUZZER_FUCHSIA 0 28 #define LIBFUZZER_LINUX 1 29 #define LIBFUZZER_NETBSD 0 30 #define LIBFUZZER_FREEBSD 0 31 #define LIBFUZZER_OPENBSD 0 32 #define LIBFUZZER_WINDOWS 0 33 #elif __APPLE__ 34 #define LIBFUZZER_APPLE 1 35 #define LIBFUZZER_FUCHSIA 0 36 #define LIBFUZZER_LINUX 0 37 #define LIBFUZZER_NETBSD 0 38 #define LIBFUZZER_FREEBSD 0 39 #define LIBFUZZER_OPENBSD 0 40 #define LIBFUZZER_WINDOWS 0 41 #elif __NetBSD__ 42 #define LIBFUZZER_APPLE 0 43 #define LIBFUZZER_FUCHSIA 0 44 #define LIBFUZZER_LINUX 0 45 #define LIBFUZZER_NETBSD 1 46 #define LIBFUZZER_FREEBSD 0 47 #define LIBFUZZER_OPENBSD 0 48 #define LIBFUZZER_WINDOWS 0 49 #elif __FreeBSD__ 50 #define LIBFUZZER_APPLE 0 51 #define LIBFUZZER_FUCHSIA 0 52 #define LIBFUZZER_LINUX 0 53 #define LIBFUZZER_NETBSD 0 54 #define LIBFUZZER_FREEBSD 1 55 #define LIBFUZZER_OPENBSD 0 56 #define LIBFUZZER_WINDOWS 0 57 #elif __OpenBSD__ 58 #define LIBFUZZER_APPLE 0 59 #define LIBFUZZER_FUCHSIA 0 60 #define LIBFUZZER_LINUX 0 61 #define LIBFUZZER_NETBSD 0 62 #define LIBFUZZER_FREEBSD 0 63 #define LIBFUZZER_OPENBSD 1 64 #define LIBFUZZER_WINDOWS 0 65 #elif _WIN32 66 #define LIBFUZZER_APPLE 0 67 #define LIBFUZZER_FUCHSIA 0 68 #define LIBFUZZER_LINUX 0 69 #define LIBFUZZER_NETBSD 0 70 #define LIBFUZZER_FREEBSD 0 71 #define LIBFUZZER_OPENBSD 0 72 #define LIBFUZZER_WINDOWS 1 73 #elif __Fuchsia__ 74 #define LIBFUZZER_APPLE 0 75 #define LIBFUZZER_FUCHSIA 1 76 #define LIBFUZZER_LINUX 0 77 #define LIBFUZZER_NETBSD 0 78 #define LIBFUZZER_FREEBSD 0 79 #define LIBFUZZER_OPENBSD 0 80 #define LIBFUZZER_WINDOWS 0 81 #else 82 #error "Support for your platform has not been implemented" 83 #endif 84 85 #if defined(_MSC_VER) && !defined(__clang__) 86 // MSVC compiler is being used. 87 #define LIBFUZZER_MSVC 1 88 #else 89 #define LIBFUZZER_MSVC 0 90 #endif 91 92 #ifndef __has_attribute 93 # define __has_attribute(x) 0 94 #endif 95 96 #define LIBFUZZER_POSIX \ 97 (LIBFUZZER_APPLE || LIBFUZZER_LINUX || LIBFUZZER_NETBSD || \ 98 LIBFUZZER_FREEBSD || LIBFUZZER_OPENBSD) 99 100 #ifdef __x86_64 101 # if __has_attribute(target) 102 # define ATTRIBUTE_TARGET_POPCNT __attribute__((target("popcnt"))) 103 # else 104 # define ATTRIBUTE_TARGET_POPCNT 105 # endif 106 #else 107 # define ATTRIBUTE_TARGET_POPCNT 108 #endif 109 110 111 #ifdef __clang__ // avoid gcc warning. 112 # if __has_attribute(no_sanitize) 113 # define ATTRIBUTE_NO_SANITIZE_MEMORY __attribute__((no_sanitize("memory"))) 114 # else 115 # define ATTRIBUTE_NO_SANITIZE_MEMORY 116 # endif 117 # define ALWAYS_INLINE __attribute__((always_inline)) 118 #else 119 # define ATTRIBUTE_NO_SANITIZE_MEMORY 120 # define ALWAYS_INLINE 121 #endif // __clang__ 122 123 #if LIBFUZZER_WINDOWS 124 #define ATTRIBUTE_NO_SANITIZE_ADDRESS 125 #else 126 #define ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address)) 127 #endif 128 129 #if LIBFUZZER_WINDOWS 130 #define ATTRIBUTE_ALIGNED(X) __declspec(align(X)) 131 #define ATTRIBUTE_INTERFACE __declspec(dllexport) 132 // This is used for __sancov_lowest_stack which is needed for 133 // -fsanitize-coverage=stack-depth. That feature is not yet available on 134 // Windows, so make the symbol static to avoid linking errors. 135 #define ATTRIBUTES_INTERFACE_TLS_INITIAL_EXEC static 136 #define ATTRIBUTE_NOINLINE __declspec(noinline) 137 #else 138 #define ATTRIBUTE_ALIGNED(X) __attribute__((aligned(X))) 139 #define ATTRIBUTE_INTERFACE __attribute__((visibility("default"))) 140 #define ATTRIBUTES_INTERFACE_TLS_INITIAL_EXEC \ 141 ATTRIBUTE_INTERFACE __attribute__((tls_model("initial-exec"))) thread_local 142 143 #define ATTRIBUTE_NOINLINE __attribute__((noinline)) 144 #endif 145 146 #if defined(__has_feature) 147 # if __has_feature(address_sanitizer) 148 # define ATTRIBUTE_NO_SANITIZE_ALL ATTRIBUTE_NO_SANITIZE_ADDRESS 149 # elif __has_feature(memory_sanitizer) 150 # define ATTRIBUTE_NO_SANITIZE_ALL ATTRIBUTE_NO_SANITIZE_MEMORY 151 # else 152 # define ATTRIBUTE_NO_SANITIZE_ALL 153 # endif 154 #else 155 # define ATTRIBUTE_NO_SANITIZE_ALL 156 #endif 157 158 namespace fuzzer { 159 160 template <class T> T Min(T a, T b) { return a < b ? a : b; } 161 template <class T> T Max(T a, T b) { return a > b ? a : b; } 162 163 class Random; 164 class Dictionary; 165 class DictionaryEntry; 166 class MutationDispatcher; 167 struct FuzzingOptions; 168 class InputCorpus; 169 struct InputInfo; 170 struct ExternalFunctions; 171 172 // Global interface to functions that may or may not be available. 173 extern ExternalFunctions *EF; 174 175 // We are using a custom allocator to give a different symbol name to STL 176 // containers in order to avoid ODR violations. 177 template<typename T> 178 class fuzzer_allocator: public std::allocator<T> { 179 public: 180 fuzzer_allocator() = default; 181 182 template<class U> 183 fuzzer_allocator(const fuzzer_allocator<U>&) {} 184 185 template<class Other> 186 struct rebind { typedef fuzzer_allocator<Other> other; }; 187 }; 188 189 template<typename T> 190 using Vector = std::vector<T, fuzzer_allocator<T>>; 191 192 template<typename T> 193 using Set = std::set<T, std::less<T>, fuzzer_allocator<T>>; 194 195 typedef Vector<uint8_t> Unit; 196 typedef Vector<Unit> UnitVector; 197 typedef int (*UserCallback)(const uint8_t *Data, size_t Size); 198 199 int FuzzerDriver(int *argc, char ***argv, UserCallback Callback); 200 201 uint8_t *ExtraCountersBegin(); 202 uint8_t *ExtraCountersEnd(); 203 void ClearExtraCounters(); 204 205 extern bool RunningUserCallback; 206 207 } // namespace fuzzer 208 209 #endif // LLVM_FUZZER_DEFS_H 210