blob: 9cccfcbc26f1460572f9e9b5cd31efe8b7364bb8 [file] [log] [blame]
Kostya Serebryany22526252015-05-11 21:16:27 +00001//===- FuzzerTraceState.cpp - Trace-based fuzzer mutator ------------------===//
Kostya Serebryany16d03bd2015-03-30 22:09:51 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
Kostya Serebryany4820cc92016-10-04 06:08:46 +00009// Data tracing.
Kostya Serebryany16d03bd2015-03-30 22:09:51 +000010//===----------------------------------------------------------------------===//
11
Kostya Serebryany16d03bd2015-03-30 22:09:51 +000012#include "FuzzerInternal.h"
Kostya Serebryany6f5a8042016-09-21 01:50:50 +000013#include "FuzzerDictionary.h"
14#include "FuzzerMutate.h"
15#include "FuzzerRandom.h"
Kostya Serebryanyab73c692016-09-23 00:46:18 +000016#include "FuzzerTracePC.h"
Kostya Serebryany16d03bd2015-03-30 22:09:51 +000017
Kostya Serebryanybeb24c32015-05-07 21:02:11 +000018#include <algorithm>
Kostya Serebryany16d03bd2015-03-30 22:09:51 +000019#include <cstring>
Kostya Serebryany226b7342016-01-06 00:03:35 +000020#include <thread>
Kostya Serebryany859e86d2016-01-12 02:08:37 +000021#include <map>
Kostya Serebryanyc135b552016-07-15 23:27:19 +000022#include <set>
Kostya Serebryany16d03bd2015-03-30 22:09:51 +000023
Kostya Serebryany5a99ecb2015-05-11 20:51:19 +000024namespace fuzzer {
25
Kostya Serebryanybeb24c32015-05-07 21:02:11 +000026// For now, very simple: put Size bytes of Data at position Pos.
27struct TraceBasedMutation {
Kostya Serebryany476f0ce2016-01-16 03:53:32 +000028 uint32_t Pos;
29 Word W;
Kostya Serebryanybeb24c32015-05-07 21:02:11 +000030};
31
Kostya Serebryanyae5b9562016-01-15 06:24:05 +000032// Declared as static globals for faster checks inside the hooks.
Kostya Serebryanyae5b9562016-01-15 06:24:05 +000033static bool RecordingMemcmp = false;
Kostya Serebryanyc135b552016-07-15 23:27:19 +000034static bool RecordingMemmem = false;
Kostya Serebryany6b08be92016-07-19 18:29:06 +000035static bool DoingMyOwnMemmem = false;
36
Kostya Serebryanya5f94fb2016-10-14 20:20:33 +000037ScopedDoingMyOwnMemmem::ScopedDoingMyOwnMemmem() { DoingMyOwnMemmem = true; }
38ScopedDoingMyOwnMemmem::~ScopedDoingMyOwnMemmem() { DoingMyOwnMemmem = false; }
Kostya Serebryanyae5b9562016-01-15 06:24:05 +000039
Kostya Serebryany22526252015-05-11 21:16:27 +000040class TraceState {
Mike Aizatskyf0b3e852016-06-23 20:44:48 +000041public:
42 TraceState(MutationDispatcher &MD, const FuzzingOptions &Options,
Richard Smithb62e7e32016-05-27 21:05:35 +000043 const Fuzzer *F)
Kostya Serebryanyf26017b2016-05-26 21:32:30 +000044 : MD(MD), Options(Options), F(F) {}
Kostya Serebryany16d03bd2015-03-30 22:09:51 +000045
Kostya Serebryanyc5733162016-01-09 01:39:55 +000046 void TraceMemcmpCallback(size_t CmpSize, const uint8_t *Data1,
47 const uint8_t *Data2);
Kostya Serebryanyfb7d8d92015-07-31 01:33:06 +000048
49 void TraceSwitchCallback(uintptr_t PC, size_t ValSizeInBits, uint64_t Val,
50 size_t NumCases, uint64_t *Cases);
Kostya Serebryany5a99ecb2015-05-11 20:51:19 +000051 int TryToAddDesiredData(uint64_t PresentData, uint64_t DesiredData,
Kostya Serebryanyf26017b2016-05-26 21:32:30 +000052 size_t DataSize);
Kostya Serebryanyc5733162016-01-09 01:39:55 +000053 int TryToAddDesiredData(const uint8_t *PresentData,
54 const uint8_t *DesiredData, size_t DataSize);
Kostya Serebryanybeb24c32015-05-07 21:02:11 +000055
56 void StartTraceRecording() {
Kostya Serebryany5c04bd22016-09-09 01:17:03 +000057 if (!Options.UseMemcmp)
Kostya Serebryanyf26017b2016-05-26 21:32:30 +000058 return;
Kostya Serebryanyae5b9562016-01-15 06:24:05 +000059 RecordingMemcmp = Options.UseMemcmp;
Kostya Serebryanyc135b552016-07-15 23:27:19 +000060 RecordingMemmem = Options.UseMemmem;
Kostya Serebryanye7583d22016-01-09 00:38:40 +000061 NumMutations = 0;
Kostya Serebryanyc135b552016-07-15 23:27:19 +000062 InterestingWords.clear();
Kostya Serebryany7ec0c562016-02-13 03:25:16 +000063 MD.ClearAutoDictionary();
Kostya Serebryanybeb24c32015-05-07 21:02:11 +000064 }
65
Kostya Serebryanyb65805a2016-01-09 03:08:58 +000066 void StopTraceRecording() {
Kostya Serebryany5c04bd22016-09-09 01:17:03 +000067 if (!RecordingMemcmp)
Mike Aizatskyf0b3e852016-06-23 20:44:48 +000068 return;
Kostya Serebryanyae5b9562016-01-15 06:24:05 +000069 RecordingMemcmp = false;
Kostya Serebryanyb65805a2016-01-09 03:08:58 +000070 for (size_t i = 0; i < NumMutations; i++) {
71 auto &M = Mutations[i];
Kostya Serebryany859e86d2016-01-12 02:08:37 +000072 if (Options.Verbosity >= 2) {
Kostya Serebryany476f0ce2016-01-16 03:53:32 +000073 AutoDictUnitCounts[M.W]++;
Kostya Serebryany859e86d2016-01-12 02:08:37 +000074 AutoDictAdds++;
75 if ((AutoDictAdds & (AutoDictAdds - 1)) == 0) {
Kostya Serebryany476f0ce2016-01-16 03:53:32 +000076 typedef std::pair<size_t, Word> CU;
Kostya Serebryany859e86d2016-01-12 02:08:37 +000077 std::vector<CU> CountedUnits;
78 for (auto &I : AutoDictUnitCounts)
79 CountedUnits.push_back(std::make_pair(I.second, I.first));
80 std::sort(CountedUnits.begin(), CountedUnits.end(),
81 [](const CU &a, const CU &b) { return a.first > b.first; });
82 Printf("AutoDict:\n");
83 for (auto &I : CountedUnits) {
84 Printf(" %zd ", I.first);
Kostya Serebryany6f5a8042016-09-21 01:50:50 +000085 PrintASCII(I.second.data(), I.second.size());
Kostya Serebryany859e86d2016-01-12 02:08:37 +000086 Printf("\n");
87 }
88 }
89 }
Kostya Serebryanyc135b552016-07-15 23:27:19 +000090 MD.AddWordToAutoDictionary({M.W, M.Pos});
Kostya Serebryanyb65805a2016-01-09 03:08:58 +000091 }
Kostya Serebryanyc135b552016-07-15 23:27:19 +000092 for (auto &W : InterestingWords)
93 MD.AddWordToAutoDictionary({W});
Kostya Serebryanybeb24c32015-05-07 21:02:11 +000094 }
95
Kostya Serebryanyc5733162016-01-09 01:39:55 +000096 void AddMutation(uint32_t Pos, uint32_t Size, const uint8_t *Data) {
Kostya Serebryanye7583d22016-01-09 00:38:40 +000097 if (NumMutations >= kMaxMutations) return;
98 auto &M = Mutations[NumMutations++];
99 M.Pos = Pos;
Kostya Serebryany476f0ce2016-01-16 03:53:32 +0000100 M.W.Set(Data, Size);
Kostya Serebryanyc5733162016-01-09 01:39:55 +0000101 }
102
103 void AddMutation(uint32_t Pos, uint32_t Size, uint64_t Data) {
104 assert(Size <= sizeof(Data));
105 AddMutation(Pos, Size, reinterpret_cast<uint8_t*>(&Data));
Kostya Serebryanye7583d22016-01-09 00:38:40 +0000106 }
107
Kostya Serebryanyc135b552016-07-15 23:27:19 +0000108 void AddInterestingWord(const uint8_t *Data, size_t Size) {
109 if (!RecordingMemmem || !F->InFuzzingThread()) return;
110 if (Size <= 1) return;
111 Size = std::min(Size, Word::GetMaxSize());
112 Word W(Data, Size);
113 InterestingWords.insert(W);
114 }
115
Kostya Serebryany16d03bd2015-03-30 22:09:51 +0000116 private:
Kostya Serebryany5a99ecb2015-05-11 20:51:19 +0000117 bool IsTwoByteData(uint64_t Data) {
118 int64_t Signed = static_cast<int64_t>(Data);
119 Signed >>= 16;
120 return Signed == 0 || Signed == -1L;
121 }
Kostya Serebryanyd88d1302016-02-02 23:17:45 +0000122
123 // We don't want to create too many trace-based mutations as it is both
124 // expensive and useless. So after some number of mutations is collected,
125 // start rejecting some of them. The more there are mutations the more we
126 // reject.
127 bool WantToHandleOneMoreMutation() {
128 const size_t FirstN = 64;
129 // Gladly handle first N mutations.
130 if (NumMutations <= FirstN) return true;
131 size_t Diff = NumMutations - FirstN;
132 size_t DiffLog = sizeof(long) * 8 - __builtin_clzl((long)Diff);
133 assert(DiffLog > 0 && DiffLog < 64);
Kostya Serebryany7ec0c562016-02-13 03:25:16 +0000134 bool WantThisOne = MD.GetRand()(1 << DiffLog) == 0; // 1 out of DiffLog.
Kostya Serebryanyd88d1302016-02-02 23:17:45 +0000135 return WantThisOne;
136 }
137
Kostya Serebryanye7583d22016-01-09 00:38:40 +0000138 static const size_t kMaxMutations = 1 << 16;
139 size_t NumMutations;
140 TraceBasedMutation Mutations[kMaxMutations];
Kostya Serebryanyc135b552016-07-15 23:27:19 +0000141 // TODO: std::set is too inefficient, need to have a custom DS here.
142 std::set<Word> InterestingWords;
Kostya Serebryany7ec0c562016-02-13 03:25:16 +0000143 MutationDispatcher &MD;
Mike Aizatskyf0b3e852016-06-23 20:44:48 +0000144 const FuzzingOptions Options;
Kostya Serebryanyf26017b2016-05-26 21:32:30 +0000145 const Fuzzer *F;
Kostya Serebryany476f0ce2016-01-16 03:53:32 +0000146 std::map<Word, size_t> AutoDictUnitCounts;
Kostya Serebryany859e86d2016-01-12 02:08:37 +0000147 size_t AutoDictAdds = 0;
Kostya Serebryany16d03bd2015-03-30 22:09:51 +0000148};
149
Kostya Serebryany22526252015-05-11 21:16:27 +0000150int TraceState::TryToAddDesiredData(uint64_t PresentData, uint64_t DesiredData,
Kostya Serebryany5a99ecb2015-05-11 20:51:19 +0000151 size_t DataSize) {
Kostya Serebryanyd88d1302016-02-02 23:17:45 +0000152 if (NumMutations >= kMaxMutations || !WantToHandleOneMoreMutation()) return 0;
Kostya Serebryany6b08be92016-07-19 18:29:06 +0000153 ScopedDoingMyOwnMemmem scoped_doing_my_own_memmem;
Kostya Serebryanyf26017b2016-05-26 21:32:30 +0000154 const uint8_t *UnitData;
155 auto UnitSize = F->GetCurrentUnitInFuzzingThead(&UnitData);
Kostya Serebryany5a99ecb2015-05-11 20:51:19 +0000156 int Res = 0;
Kostya Serebryanyf26017b2016-05-26 21:32:30 +0000157 const uint8_t *Beg = UnitData;
158 const uint8_t *End = Beg + UnitSize;
Kostya Serebryanye641dd62015-09-04 22:32:25 +0000159 for (const uint8_t *Cur = Beg; Cur < End; Cur++) {
Kostya Serebryany5a99ecb2015-05-11 20:51:19 +0000160 Cur = (uint8_t *)memmem(Cur, End - Cur, &PresentData, DataSize);
161 if (!Cur)
162 break;
Kostya Serebryany5a99ecb2015-05-11 20:51:19 +0000163 size_t Pos = Cur - Beg;
Kostya Serebryanyf26017b2016-05-26 21:32:30 +0000164 assert(Pos < UnitSize);
Kostya Serebryanye7583d22016-01-09 00:38:40 +0000165 AddMutation(Pos, DataSize, DesiredData);
166 AddMutation(Pos, DataSize, DesiredData + 1);
167 AddMutation(Pos, DataSize, DesiredData - 1);
Kostya Serebryany5a99ecb2015-05-11 20:51:19 +0000168 Res++;
169 }
170 return Res;
171}
172
Kostya Serebryanyc5733162016-01-09 01:39:55 +0000173int TraceState::TryToAddDesiredData(const uint8_t *PresentData,
174 const uint8_t *DesiredData,
175 size_t DataSize) {
Kostya Serebryanyd88d1302016-02-02 23:17:45 +0000176 if (NumMutations >= kMaxMutations || !WantToHandleOneMoreMutation()) return 0;
Kostya Serebryany6b08be92016-07-19 18:29:06 +0000177 ScopedDoingMyOwnMemmem scoped_doing_my_own_memmem;
Kostya Serebryanyf26017b2016-05-26 21:32:30 +0000178 const uint8_t *UnitData;
179 auto UnitSize = F->GetCurrentUnitInFuzzingThead(&UnitData);
Kostya Serebryanyc5733162016-01-09 01:39:55 +0000180 int Res = 0;
Kostya Serebryanyf26017b2016-05-26 21:32:30 +0000181 const uint8_t *Beg = UnitData;
182 const uint8_t *End = Beg + UnitSize;
Kostya Serebryanyc5733162016-01-09 01:39:55 +0000183 for (const uint8_t *Cur = Beg; Cur < End; Cur++) {
184 Cur = (uint8_t *)memmem(Cur, End - Cur, PresentData, DataSize);
185 if (!Cur)
186 break;
187 size_t Pos = Cur - Beg;
Kostya Serebryanyf26017b2016-05-26 21:32:30 +0000188 assert(Pos < UnitSize);
Kostya Serebryanyc5733162016-01-09 01:39:55 +0000189 AddMutation(Pos, DataSize, DesiredData);
190 Res++;
191 }
192 return Res;
193}
194
Kostya Serebryanyc5733162016-01-09 01:39:55 +0000195void TraceState::TraceMemcmpCallback(size_t CmpSize, const uint8_t *Data1,
196 const uint8_t *Data2) {
Kostya Serebryanyf26017b2016-05-26 21:32:30 +0000197 if (!RecordingMemcmp || !F->InFuzzingThread()) return;
Kostya Serebryany476f0ce2016-01-16 03:53:32 +0000198 CmpSize = std::min(CmpSize, Word::GetMaxSize());
Kostya Serebryany1f9c40d2016-01-09 03:46:08 +0000199 int Added2 = TryToAddDesiredData(Data1, Data2, CmpSize);
200 int Added1 = TryToAddDesiredData(Data2, Data1, CmpSize);
201 if ((Added1 || Added2) && Options.Verbosity >= 3) {
202 Printf("MemCmp Added %d%d: ", Added1, Added2);
Kostya Serebryany41740052016-01-12 02:36:59 +0000203 if (Added1) PrintASCII(Data1, CmpSize);
204 if (Added2) PrintASCII(Data2, CmpSize);
Kostya Serebryany1f9c40d2016-01-09 03:46:08 +0000205 Printf("\n");
206 }
Kostya Serebryanyc5733162016-01-09 01:39:55 +0000207}
208
Kostya Serebryanyfb7d8d92015-07-31 01:33:06 +0000209void TraceState::TraceSwitchCallback(uintptr_t PC, size_t ValSizeInBits,
210 uint64_t Val, size_t NumCases,
211 uint64_t *Cases) {
Kostya Serebryany5c04bd22016-09-09 01:17:03 +0000212 if (F->InFuzzingThread()) return;
Kostya Serebryanyfe7e41e2015-07-31 20:58:55 +0000213 size_t ValSize = ValSizeInBits / 8;
214 bool TryShort = IsTwoByteData(Val);
Kostya Serebryanyfb7d8d92015-07-31 01:33:06 +0000215 for (size_t i = 0; i < NumCases; i++)
Kostya Serebryanyfe7e41e2015-07-31 20:58:55 +0000216 TryShort &= IsTwoByteData(Cases[i]);
217
218 if (Options.Verbosity >= 3)
219 Printf("TraceSwitch: %p %zd # %zd; TryShort %d\n", PC, Val, NumCases,
220 TryShort);
221
222 for (size_t i = 0; i < NumCases; i++) {
223 TryToAddDesiredData(Val, Cases[i], ValSize);
224 if (TryShort)
225 TryToAddDesiredData(Val, Cases[i], 2);
226 }
Kostya Serebryanyfb7d8d92015-07-31 01:33:06 +0000227}
228
Kostya Serebryany22526252015-05-11 21:16:27 +0000229static TraceState *TS;
Kostya Serebryany16d03bd2015-03-30 22:09:51 +0000230
Kostya Serebryanybeb24c32015-05-07 21:02:11 +0000231void Fuzzer::StartTraceRecording() {
Kostya Serebryany22526252015-05-11 21:16:27 +0000232 if (!TS) return;
233 TS->StartTraceRecording();
Kostya Serebryanybeb24c32015-05-07 21:02:11 +0000234}
235
Kostya Serebryanyb65805a2016-01-09 03:08:58 +0000236void Fuzzer::StopTraceRecording() {
237 if (!TS) return;
238 TS->StopTraceRecording();
Kostya Serebryany16d03bd2015-03-30 22:09:51 +0000239}
240
Kostya Serebryany22526252015-05-11 21:16:27 +0000241void Fuzzer::InitializeTraceState() {
Kostya Serebryany5c04bd22016-09-09 01:17:03 +0000242 if (!Options.UseMemcmp) return;
Kostya Serebryanyf26017b2016-05-26 21:32:30 +0000243 TS = new TraceState(MD, Options, this);
Kostya Serebryany16d03bd2015-03-30 22:09:51 +0000244}
245
Kostya Serebryanyc9dc96b2015-07-30 21:22:22 +0000246static size_t InternalStrnlen(const char *S, size_t MaxLen) {
247 size_t Len = 0;
248 for (; Len < MaxLen && S[Len]; Len++) {}
249 return Len;
250}
251
Kostya Serebryany16d03bd2015-03-30 22:09:51 +0000252} // namespace fuzzer
253
Kostya Serebryany22526252015-05-11 21:16:27 +0000254using fuzzer::TS;
Kostya Serebryanyae5b9562016-01-15 06:24:05 +0000255using fuzzer::RecordingMemcmp;
Kostya Serebryany5a99ecb2015-05-11 20:51:19 +0000256
Kostya Serebryany16d03bd2015-03-30 22:09:51 +0000257extern "C" {
Kostya Serebryany7f4227d2015-08-05 18:23:01 +0000258
Kostya Serebryany4b83a4f2016-01-12 16:50:18 +0000259// We may need to avoid defining weak hooks to stay compatible with older clang.
260#ifndef LLVM_FUZZER_DEFINES_SANITIZER_WEAK_HOOOKS
261# define LLVM_FUZZER_DEFINES_SANITIZER_WEAK_HOOOKS 1
262#endif
263
264#if LLVM_FUZZER_DEFINES_SANITIZER_WEAK_HOOOKS
Kostya Serebryany0e776a22015-07-30 01:34:58 +0000265void __sanitizer_weak_hook_memcmp(void *caller_pc, const void *s1,
Kostya Serebryanye3580952016-01-12 00:43:42 +0000266 const void *s2, size_t n, int result) {
Kostya Serebryany379359c2016-10-05 01:09:40 +0000267 fuzzer::TPC.AddValueForMemcmp(caller_pc, s1, s2, n);
Kostya Serebryanyae5b9562016-01-15 06:24:05 +0000268 if (!RecordingMemcmp) return;
Kostya Serebryanye3580952016-01-12 00:43:42 +0000269 if (result == 0) return; // No reason to mutate.
Kostya Serebryanyc5733162016-01-09 01:39:55 +0000270 if (n <= 1) return; // Not interesting.
271 TS->TraceMemcmpCallback(n, reinterpret_cast<const uint8_t *>(s1),
272 reinterpret_cast<const uint8_t *>(s2));
Kostya Serebryanyb74ba422015-07-30 02:33:45 +0000273}
274
275void __sanitizer_weak_hook_strncmp(void *caller_pc, const char *s1,
Kostya Serebryanye3580952016-01-12 00:43:42 +0000276 const char *s2, size_t n, int result) {
Kostya Serebryany379359c2016-10-05 01:09:40 +0000277 fuzzer::TPC.AddValueForStrcmp(caller_pc, s1, s2, n);
Kostya Serebryanyae5b9562016-01-15 06:24:05 +0000278 if (!RecordingMemcmp) return;
Kostya Serebryanye3580952016-01-12 00:43:42 +0000279 if (result == 0) return; // No reason to mutate.
Kostya Serebryanycd6a4662015-07-31 17:05:05 +0000280 size_t Len1 = fuzzer::InternalStrnlen(s1, n);
281 size_t Len2 = fuzzer::InternalStrnlen(s2, n);
282 n = std::min(n, Len1);
283 n = std::min(n, Len2);
284 if (n <= 1) return; // Not interesting.
Kostya Serebryanyc5733162016-01-09 01:39:55 +0000285 TS->TraceMemcmpCallback(n, reinterpret_cast<const uint8_t *>(s1),
286 reinterpret_cast<const uint8_t *>(s2));
Kostya Serebryany0e776a22015-07-30 01:34:58 +0000287}
288
Kostya Serebryany7f4227d2015-08-05 18:23:01 +0000289void __sanitizer_weak_hook_strcmp(void *caller_pc, const char *s1,
Kostya Serebryanye3580952016-01-12 00:43:42 +0000290 const char *s2, int result) {
Kostya Serebryany379359c2016-10-05 01:09:40 +0000291 fuzzer::TPC.AddValueForStrcmp(caller_pc, s1, s2, 64);
Kostya Serebryanyae5b9562016-01-15 06:24:05 +0000292 if (!RecordingMemcmp) return;
Kostya Serebryanye3580952016-01-12 00:43:42 +0000293 if (result == 0) return; // No reason to mutate.
Kostya Serebryany7f4227d2015-08-05 18:23:01 +0000294 size_t Len1 = strlen(s1);
295 size_t Len2 = strlen(s2);
296 size_t N = std::min(Len1, Len2);
297 if (N <= 1) return; // Not interesting.
Kostya Serebryanyc5733162016-01-09 01:39:55 +0000298 TS->TraceMemcmpCallback(N, reinterpret_cast<const uint8_t *>(s1),
299 reinterpret_cast<const uint8_t *>(s2));
Kostya Serebryany7f4227d2015-08-05 18:23:01 +0000300}
301
Kostya Serebryanyc135b552016-07-15 23:27:19 +0000302void __sanitizer_weak_hook_strncasecmp(void *called_pc, const char *s1,
303 const char *s2, size_t n, int result) {
304 return __sanitizer_weak_hook_strncmp(called_pc, s1, s2, n, result);
305}
306void __sanitizer_weak_hook_strcasecmp(void *called_pc, const char *s1,
307 const char *s2, int result) {
308 return __sanitizer_weak_hook_strcmp(called_pc, s1, s2, result);
309}
310void __sanitizer_weak_hook_strstr(void *called_pc, const char *s1,
311 const char *s2, char *result) {
312 TS->AddInterestingWord(reinterpret_cast<const uint8_t *>(s2), strlen(s2));
313}
314void __sanitizer_weak_hook_strcasestr(void *called_pc, const char *s1,
315 const char *s2, char *result) {
316 TS->AddInterestingWord(reinterpret_cast<const uint8_t *>(s2), strlen(s2));
317}
318void __sanitizer_weak_hook_memmem(void *called_pc, const void *s1, size_t len1,
319 const void *s2, size_t len2, void *result) {
Kostya Serebryany6b08be92016-07-19 18:29:06 +0000320 if (fuzzer::DoingMyOwnMemmem) return;
321 TS->AddInterestingWord(reinterpret_cast<const uint8_t *>(s2), len2);
Kostya Serebryanyc135b552016-07-15 23:27:19 +0000322}
323
Kostya Serebryany4b83a4f2016-01-12 16:50:18 +0000324#endif // LLVM_FUZZER_DEFINES_SANITIZER_WEAK_HOOOKS
Kostya Serebryany16d03bd2015-03-30 22:09:51 +0000325} // extern "C"