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__ || __DragonFly__
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 
Min(T a,T b)160 template <class T> T Min(T a, T b) { return a < b ? a : b; }
Max(T a,T 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>
fuzzer_allocator(const fuzzer_allocator<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