1c5f01b2fSopenharmony_ci//===- FuzzerTraceState.cpp - Trace-based fuzzer mutator ------------------===//
2c5f01b2fSopenharmony_ci//
3c5f01b2fSopenharmony_ci//                     The LLVM Compiler Infrastructure
4c5f01b2fSopenharmony_ci//
5c5f01b2fSopenharmony_ci// This file is distributed under the University of Illinois Open Source
6c5f01b2fSopenharmony_ci// License. See LICENSE.TXT for details.
7c5f01b2fSopenharmony_ci//
8c5f01b2fSopenharmony_ci//===----------------------------------------------------------------------===//
9c5f01b2fSopenharmony_ci// Data tracing.
10c5f01b2fSopenharmony_ci//===----------------------------------------------------------------------===//
11c5f01b2fSopenharmony_ci
12c5f01b2fSopenharmony_ci#include "FuzzerDictionary.h"
13c5f01b2fSopenharmony_ci#include "FuzzerInternal.h"
14c5f01b2fSopenharmony_ci#include "FuzzerIO.h"
15c5f01b2fSopenharmony_ci#include "FuzzerMutate.h"
16c5f01b2fSopenharmony_ci#include "FuzzerRandom.h"
17c5f01b2fSopenharmony_ci#include "FuzzerTracePC.h"
18c5f01b2fSopenharmony_ci#include <algorithm>
19c5f01b2fSopenharmony_ci#include <cstring>
20c5f01b2fSopenharmony_ci#include <map>
21c5f01b2fSopenharmony_ci#include <set>
22c5f01b2fSopenharmony_ci#include <thread>
23c5f01b2fSopenharmony_ci
24c5f01b2fSopenharmony_cinamespace fuzzer {
25c5f01b2fSopenharmony_ci
26c5f01b2fSopenharmony_ci// For now, very simple: put Size bytes of Data at position Pos.
27c5f01b2fSopenharmony_cistruct TraceBasedMutation {
28c5f01b2fSopenharmony_ci  uint32_t Pos;
29c5f01b2fSopenharmony_ci  Word W;
30c5f01b2fSopenharmony_ci};
31c5f01b2fSopenharmony_ci
32c5f01b2fSopenharmony_ci// Declared as static globals for faster checks inside the hooks.
33c5f01b2fSopenharmony_cistatic bool RecordingMemcmp = false;
34c5f01b2fSopenharmony_cistatic bool RecordingMemmem = false;
35c5f01b2fSopenharmony_cistatic bool DoingMyOwnMemmem = false;
36c5f01b2fSopenharmony_ci
37c5f01b2fSopenharmony_ciScopedDoingMyOwnMemmem::ScopedDoingMyOwnMemmem() { DoingMyOwnMemmem = true; }
38c5f01b2fSopenharmony_ciScopedDoingMyOwnMemmem::~ScopedDoingMyOwnMemmem() { DoingMyOwnMemmem = false; }
39c5f01b2fSopenharmony_ci
40c5f01b2fSopenharmony_ciclass TraceState {
41c5f01b2fSopenharmony_cipublic:
42c5f01b2fSopenharmony_ci  TraceState(MutationDispatcher &MD, const FuzzingOptions &Options,
43c5f01b2fSopenharmony_ci             const Fuzzer *F)
44c5f01b2fSopenharmony_ci      : MD(MD), Options(Options), F(F) {}
45c5f01b2fSopenharmony_ci
46c5f01b2fSopenharmony_ci  void TraceMemcmpCallback(size_t CmpSize, const uint8_t *Data1,
47c5f01b2fSopenharmony_ci                           const uint8_t *Data2);
48c5f01b2fSopenharmony_ci
49c5f01b2fSopenharmony_ci  void TraceSwitchCallback(uintptr_t PC, size_t ValSizeInBits, uint64_t Val,
50c5f01b2fSopenharmony_ci                           size_t NumCases, uint64_t *Cases);
51c5f01b2fSopenharmony_ci  int TryToAddDesiredData(uint64_t PresentData, uint64_t DesiredData,
52c5f01b2fSopenharmony_ci                          size_t DataSize);
53c5f01b2fSopenharmony_ci  int TryToAddDesiredData(const uint8_t *PresentData,
54c5f01b2fSopenharmony_ci                          const uint8_t *DesiredData, size_t DataSize);
55c5f01b2fSopenharmony_ci
56c5f01b2fSopenharmony_ci  void StartTraceRecording() {
57c5f01b2fSopenharmony_ci    if (!Options.UseMemcmp)
58c5f01b2fSopenharmony_ci      return;
59c5f01b2fSopenharmony_ci    RecordingMemcmp = Options.UseMemcmp;
60c5f01b2fSopenharmony_ci    RecordingMemmem = Options.UseMemmem;
61c5f01b2fSopenharmony_ci    NumMutations = 0;
62c5f01b2fSopenharmony_ci    InterestingWords.clear();
63c5f01b2fSopenharmony_ci    MD.ClearAutoDictionary();
64c5f01b2fSopenharmony_ci  }
65c5f01b2fSopenharmony_ci
66c5f01b2fSopenharmony_ci  void StopTraceRecording() {
67c5f01b2fSopenharmony_ci    if (!RecordingMemcmp)
68c5f01b2fSopenharmony_ci      return;
69c5f01b2fSopenharmony_ci    RecordingMemcmp = false;
70c5f01b2fSopenharmony_ci    for (size_t i = 0; i < NumMutations; i++) {
71c5f01b2fSopenharmony_ci      auto &M = Mutations[i];
72c5f01b2fSopenharmony_ci      if (Options.Verbosity >= 2) {
73c5f01b2fSopenharmony_ci        AutoDictUnitCounts[M.W]++;
74c5f01b2fSopenharmony_ci        AutoDictAdds++;
75c5f01b2fSopenharmony_ci        if ((AutoDictAdds & (AutoDictAdds - 1)) == 0) {
76c5f01b2fSopenharmony_ci          typedef std::pair<size_t, Word> CU;
77c5f01b2fSopenharmony_ci          std::vector<CU> CountedUnits;
78c5f01b2fSopenharmony_ci          for (auto &I : AutoDictUnitCounts)
79c5f01b2fSopenharmony_ci            CountedUnits.push_back(std::make_pair(I.second, I.first));
80c5f01b2fSopenharmony_ci          std::sort(CountedUnits.begin(), CountedUnits.end(),
81c5f01b2fSopenharmony_ci                    [](const CU &a, const CU &b) { return a.first > b.first; });
82c5f01b2fSopenharmony_ci          Printf("AutoDict:\n");
83c5f01b2fSopenharmony_ci          for (auto &I : CountedUnits) {
84c5f01b2fSopenharmony_ci            Printf("   %zd ", I.first);
85c5f01b2fSopenharmony_ci            PrintASCII(I.second.data(), I.second.size());
86c5f01b2fSopenharmony_ci            Printf("\n");
87c5f01b2fSopenharmony_ci          }
88c5f01b2fSopenharmony_ci        }
89c5f01b2fSopenharmony_ci      }
90c5f01b2fSopenharmony_ci      MD.AddWordToAutoDictionary({M.W, M.Pos});
91c5f01b2fSopenharmony_ci    }
92c5f01b2fSopenharmony_ci    for (auto &W : InterestingWords)
93c5f01b2fSopenharmony_ci      MD.AddWordToAutoDictionary({W});
94c5f01b2fSopenharmony_ci  }
95c5f01b2fSopenharmony_ci
96c5f01b2fSopenharmony_ci  void AddMutation(uint32_t Pos, uint32_t Size, const uint8_t *Data) {
97c5f01b2fSopenharmony_ci    if (NumMutations >= kMaxMutations) return;
98c5f01b2fSopenharmony_ci    auto &M = Mutations[NumMutations++];
99c5f01b2fSopenharmony_ci    M.Pos = Pos;
100c5f01b2fSopenharmony_ci    M.W.Set(Data, Size);
101c5f01b2fSopenharmony_ci  }
102c5f01b2fSopenharmony_ci
103c5f01b2fSopenharmony_ci  void AddMutation(uint32_t Pos, uint32_t Size, uint64_t Data) {
104c5f01b2fSopenharmony_ci    assert(Size <= sizeof(Data));
105c5f01b2fSopenharmony_ci    AddMutation(Pos, Size, reinterpret_cast<uint8_t*>(&Data));
106c5f01b2fSopenharmony_ci  }
107c5f01b2fSopenharmony_ci
108c5f01b2fSopenharmony_ci  void AddInterestingWord(const uint8_t *Data, size_t Size) {
109c5f01b2fSopenharmony_ci    if (!RecordingMemmem || !F->InFuzzingThread()) return;
110c5f01b2fSopenharmony_ci    if (Size <= 1) return;
111c5f01b2fSopenharmony_ci    Size = std::min(Size, Word::GetMaxSize());
112c5f01b2fSopenharmony_ci    Word W(Data, Size);
113c5f01b2fSopenharmony_ci    InterestingWords.insert(W);
114c5f01b2fSopenharmony_ci  }
115c5f01b2fSopenharmony_ci
116c5f01b2fSopenharmony_ci private:
117c5f01b2fSopenharmony_ci  bool IsTwoByteData(uint64_t Data) {
118c5f01b2fSopenharmony_ci    int64_t Signed = static_cast<int64_t>(Data);
119c5f01b2fSopenharmony_ci    Signed >>= 16;
120c5f01b2fSopenharmony_ci    return Signed == 0 || Signed == -1L;
121c5f01b2fSopenharmony_ci  }
122c5f01b2fSopenharmony_ci
123c5f01b2fSopenharmony_ci  // We don't want to create too many trace-based mutations as it is both
124c5f01b2fSopenharmony_ci  // expensive and useless. So after some number of mutations is collected,
125c5f01b2fSopenharmony_ci  // start rejecting some of them. The more there are mutations the more we
126c5f01b2fSopenharmony_ci  // reject.
127c5f01b2fSopenharmony_ci  bool WantToHandleOneMoreMutation() {
128c5f01b2fSopenharmony_ci    const size_t FirstN = 64;
129c5f01b2fSopenharmony_ci    // Gladly handle first N mutations.
130c5f01b2fSopenharmony_ci    if (NumMutations <= FirstN) return true;
131c5f01b2fSopenharmony_ci    size_t Diff = NumMutations - FirstN;
132c5f01b2fSopenharmony_ci    size_t DiffLog = sizeof(long) * 8 - __builtin_clzl((long)Diff);
133c5f01b2fSopenharmony_ci    assert(DiffLog > 0 && DiffLog < 64);
134c5f01b2fSopenharmony_ci    bool WantThisOne = MD.GetRand()(1 << DiffLog) == 0;  // 1 out of DiffLog.
135c5f01b2fSopenharmony_ci    return WantThisOne;
136c5f01b2fSopenharmony_ci  }
137c5f01b2fSopenharmony_ci
138c5f01b2fSopenharmony_ci  static const size_t kMaxMutations = 1 << 16;
139c5f01b2fSopenharmony_ci  size_t NumMutations;
140c5f01b2fSopenharmony_ci  TraceBasedMutation Mutations[kMaxMutations];
141c5f01b2fSopenharmony_ci  // TODO: std::set is too inefficient, need to have a custom DS here.
142c5f01b2fSopenharmony_ci  std::set<Word> InterestingWords;
143c5f01b2fSopenharmony_ci  MutationDispatcher &MD;
144c5f01b2fSopenharmony_ci  const FuzzingOptions Options;
145c5f01b2fSopenharmony_ci  const Fuzzer *F;
146c5f01b2fSopenharmony_ci  std::map<Word, size_t> AutoDictUnitCounts;
147c5f01b2fSopenharmony_ci  size_t AutoDictAdds = 0;
148c5f01b2fSopenharmony_ci};
149c5f01b2fSopenharmony_ci
150c5f01b2fSopenharmony_ciint TraceState::TryToAddDesiredData(uint64_t PresentData, uint64_t DesiredData,
151c5f01b2fSopenharmony_ci                                    size_t DataSize) {
152c5f01b2fSopenharmony_ci  if (NumMutations >= kMaxMutations || !WantToHandleOneMoreMutation()) return 0;
153c5f01b2fSopenharmony_ci  ScopedDoingMyOwnMemmem scoped_doing_my_own_memmem;
154c5f01b2fSopenharmony_ci  const uint8_t *UnitData;
155c5f01b2fSopenharmony_ci  auto UnitSize = F->GetCurrentUnitInFuzzingThead(&UnitData);
156c5f01b2fSopenharmony_ci  int Res = 0;
157c5f01b2fSopenharmony_ci  const uint8_t *Beg = UnitData;
158c5f01b2fSopenharmony_ci  const uint8_t *End = Beg + UnitSize;
159c5f01b2fSopenharmony_ci  for (const uint8_t *Cur = Beg; Cur < End; Cur++) {
160c5f01b2fSopenharmony_ci    Cur = (uint8_t *)SearchMemory(Cur, End - Cur, &PresentData, DataSize);
161c5f01b2fSopenharmony_ci    if (!Cur)
162c5f01b2fSopenharmony_ci      break;
163c5f01b2fSopenharmony_ci    size_t Pos = Cur - Beg;
164c5f01b2fSopenharmony_ci    assert(Pos < UnitSize);
165c5f01b2fSopenharmony_ci    AddMutation(Pos, DataSize, DesiredData);
166c5f01b2fSopenharmony_ci    AddMutation(Pos, DataSize, DesiredData + 1);
167c5f01b2fSopenharmony_ci    AddMutation(Pos, DataSize, DesiredData - 1);
168c5f01b2fSopenharmony_ci    Res++;
169c5f01b2fSopenharmony_ci  }
170c5f01b2fSopenharmony_ci  return Res;
171c5f01b2fSopenharmony_ci}
172c5f01b2fSopenharmony_ci
173c5f01b2fSopenharmony_ciint TraceState::TryToAddDesiredData(const uint8_t *PresentData,
174c5f01b2fSopenharmony_ci                                    const uint8_t *DesiredData,
175c5f01b2fSopenharmony_ci                                    size_t DataSize) {
176c5f01b2fSopenharmony_ci  if (NumMutations >= kMaxMutations || !WantToHandleOneMoreMutation()) return 0;
177c5f01b2fSopenharmony_ci  ScopedDoingMyOwnMemmem scoped_doing_my_own_memmem;
178c5f01b2fSopenharmony_ci  const uint8_t *UnitData;
179c5f01b2fSopenharmony_ci  auto UnitSize = F->GetCurrentUnitInFuzzingThead(&UnitData);
180c5f01b2fSopenharmony_ci  int Res = 0;
181c5f01b2fSopenharmony_ci  const uint8_t *Beg = UnitData;
182c5f01b2fSopenharmony_ci  const uint8_t *End = Beg + UnitSize;
183c5f01b2fSopenharmony_ci  for (const uint8_t *Cur = Beg; Cur < End; Cur++) {
184c5f01b2fSopenharmony_ci    Cur = (uint8_t *)SearchMemory(Cur, End - Cur, PresentData, DataSize);
185c5f01b2fSopenharmony_ci    if (!Cur)
186c5f01b2fSopenharmony_ci      break;
187c5f01b2fSopenharmony_ci    size_t Pos = Cur - Beg;
188c5f01b2fSopenharmony_ci    assert(Pos < UnitSize);
189c5f01b2fSopenharmony_ci    AddMutation(Pos, DataSize, DesiredData);
190c5f01b2fSopenharmony_ci    Res++;
191c5f01b2fSopenharmony_ci  }
192c5f01b2fSopenharmony_ci  return Res;
193c5f01b2fSopenharmony_ci}
194c5f01b2fSopenharmony_ci
195c5f01b2fSopenharmony_civoid TraceState::TraceMemcmpCallback(size_t CmpSize, const uint8_t *Data1,
196c5f01b2fSopenharmony_ci                                     const uint8_t *Data2) {
197c5f01b2fSopenharmony_ci  if (!RecordingMemcmp || !F->InFuzzingThread()) return;
198c5f01b2fSopenharmony_ci  CmpSize = std::min(CmpSize, Word::GetMaxSize());
199c5f01b2fSopenharmony_ci  int Added2 = TryToAddDesiredData(Data1, Data2, CmpSize);
200c5f01b2fSopenharmony_ci  int Added1 = TryToAddDesiredData(Data2, Data1, CmpSize);
201c5f01b2fSopenharmony_ci  if ((Added1 || Added2) && Options.Verbosity >= 3) {
202c5f01b2fSopenharmony_ci    Printf("MemCmp Added %d%d: ", Added1, Added2);
203c5f01b2fSopenharmony_ci    if (Added1) PrintASCII(Data1, CmpSize);
204c5f01b2fSopenharmony_ci    if (Added2) PrintASCII(Data2, CmpSize);
205c5f01b2fSopenharmony_ci    Printf("\n");
206c5f01b2fSopenharmony_ci  }
207c5f01b2fSopenharmony_ci}
208c5f01b2fSopenharmony_ci
209c5f01b2fSopenharmony_civoid TraceState::TraceSwitchCallback(uintptr_t PC, size_t ValSizeInBits,
210c5f01b2fSopenharmony_ci                                     uint64_t Val, size_t NumCases,
211c5f01b2fSopenharmony_ci                                     uint64_t *Cases) {
212c5f01b2fSopenharmony_ci  if (F->InFuzzingThread()) return;
213c5f01b2fSopenharmony_ci  size_t ValSize = ValSizeInBits / 8;
214c5f01b2fSopenharmony_ci  bool TryShort = IsTwoByteData(Val);
215c5f01b2fSopenharmony_ci  for (size_t i = 0; i < NumCases; i++)
216c5f01b2fSopenharmony_ci    TryShort &= IsTwoByteData(Cases[i]);
217c5f01b2fSopenharmony_ci
218c5f01b2fSopenharmony_ci  if (Options.Verbosity >= 3)
219c5f01b2fSopenharmony_ci    Printf("TraceSwitch: %p %zd # %zd; TryShort %d\n", PC, Val, NumCases,
220c5f01b2fSopenharmony_ci           TryShort);
221c5f01b2fSopenharmony_ci
222c5f01b2fSopenharmony_ci  for (size_t i = 0; i < NumCases; i++) {
223c5f01b2fSopenharmony_ci    TryToAddDesiredData(Val, Cases[i], ValSize);
224c5f01b2fSopenharmony_ci    if (TryShort)
225c5f01b2fSopenharmony_ci      TryToAddDesiredData(Val, Cases[i], 2);
226c5f01b2fSopenharmony_ci  }
227c5f01b2fSopenharmony_ci}
228c5f01b2fSopenharmony_ci
229c5f01b2fSopenharmony_cistatic TraceState *TS;
230c5f01b2fSopenharmony_ci
231c5f01b2fSopenharmony_civoid Fuzzer::StartTraceRecording() {
232c5f01b2fSopenharmony_ci  if (!TS) return;
233c5f01b2fSopenharmony_ci  TS->StartTraceRecording();
234c5f01b2fSopenharmony_ci}
235c5f01b2fSopenharmony_ci
236c5f01b2fSopenharmony_civoid Fuzzer::StopTraceRecording() {
237c5f01b2fSopenharmony_ci  if (!TS) return;
238c5f01b2fSopenharmony_ci  TS->StopTraceRecording();
239c5f01b2fSopenharmony_ci}
240c5f01b2fSopenharmony_ci
241c5f01b2fSopenharmony_civoid Fuzzer::InitializeTraceState() {
242c5f01b2fSopenharmony_ci  if (!Options.UseMemcmp) return;
243c5f01b2fSopenharmony_ci  TS = new TraceState(MD, Options, this);
244c5f01b2fSopenharmony_ci}
245c5f01b2fSopenharmony_ci
246c5f01b2fSopenharmony_cistatic size_t InternalStrnlen(const char *S, size_t MaxLen) {
247c5f01b2fSopenharmony_ci  size_t Len = 0;
248c5f01b2fSopenharmony_ci  for (; Len < MaxLen && S[Len]; Len++) {}
249c5f01b2fSopenharmony_ci  return Len;
250c5f01b2fSopenharmony_ci}
251c5f01b2fSopenharmony_ci
252c5f01b2fSopenharmony_ci}  // namespace fuzzer
253c5f01b2fSopenharmony_ci
254c5f01b2fSopenharmony_ciusing fuzzer::TS;
255c5f01b2fSopenharmony_ciusing fuzzer::RecordingMemcmp;
256c5f01b2fSopenharmony_ci
257c5f01b2fSopenharmony_ciextern "C" {
258c5f01b2fSopenharmony_ci
259c5f01b2fSopenharmony_ci// We may need to avoid defining weak hooks to stay compatible with older clang.
260c5f01b2fSopenharmony_ci#ifndef LLVM_FUZZER_DEFINES_SANITIZER_WEAK_HOOOKS
261c5f01b2fSopenharmony_ci# define LLVM_FUZZER_DEFINES_SANITIZER_WEAK_HOOOKS 1
262c5f01b2fSopenharmony_ci#endif
263c5f01b2fSopenharmony_ci
264c5f01b2fSopenharmony_ci#if LLVM_FUZZER_DEFINES_SANITIZER_WEAK_HOOOKS
265c5f01b2fSopenharmony_civoid __sanitizer_weak_hook_memcmp(void *caller_pc, const void *s1,
266c5f01b2fSopenharmony_ci                                  const void *s2, size_t n, int result) {
267c5f01b2fSopenharmony_ci  fuzzer::TPC.AddValueForMemcmp(caller_pc, s1, s2, n);
268c5f01b2fSopenharmony_ci  if (!RecordingMemcmp) return;
269c5f01b2fSopenharmony_ci  if (result == 0) return;  // No reason to mutate.
270c5f01b2fSopenharmony_ci  if (n <= 1) return;  // Not interesting.
271c5f01b2fSopenharmony_ci  TS->TraceMemcmpCallback(n, reinterpret_cast<const uint8_t *>(s1),
272c5f01b2fSopenharmony_ci                          reinterpret_cast<const uint8_t *>(s2));
273c5f01b2fSopenharmony_ci}
274c5f01b2fSopenharmony_ci
275c5f01b2fSopenharmony_civoid __sanitizer_weak_hook_strncmp(void *caller_pc, const char *s1,
276c5f01b2fSopenharmony_ci                                   const char *s2, size_t n, int result) {
277c5f01b2fSopenharmony_ci  fuzzer::TPC.AddValueForStrcmp(caller_pc, s1, s2, n);
278c5f01b2fSopenharmony_ci  if (!RecordingMemcmp) return;
279c5f01b2fSopenharmony_ci  if (result == 0) return;  // No reason to mutate.
280c5f01b2fSopenharmony_ci  size_t Len1 = fuzzer::InternalStrnlen(s1, n);
281c5f01b2fSopenharmony_ci  size_t Len2 = fuzzer::InternalStrnlen(s2, n);
282c5f01b2fSopenharmony_ci  n = std::min(n, Len1);
283c5f01b2fSopenharmony_ci  n = std::min(n, Len2);
284c5f01b2fSopenharmony_ci  if (n <= 1) return;  // Not interesting.
285c5f01b2fSopenharmony_ci  TS->TraceMemcmpCallback(n, reinterpret_cast<const uint8_t *>(s1),
286c5f01b2fSopenharmony_ci                          reinterpret_cast<const uint8_t *>(s2));
287c5f01b2fSopenharmony_ci}
288c5f01b2fSopenharmony_ci
289c5f01b2fSopenharmony_civoid __sanitizer_weak_hook_strcmp(void *caller_pc, const char *s1,
290c5f01b2fSopenharmony_ci                                   const char *s2, int result) {
291c5f01b2fSopenharmony_ci  fuzzer::TPC.AddValueForStrcmp(caller_pc, s1, s2, 64);
292c5f01b2fSopenharmony_ci  if (!RecordingMemcmp) return;
293c5f01b2fSopenharmony_ci  if (result == 0) return;  // No reason to mutate.
294c5f01b2fSopenharmony_ci  size_t Len1 = strlen(s1);
295c5f01b2fSopenharmony_ci  size_t Len2 = strlen(s2);
296c5f01b2fSopenharmony_ci  size_t N = std::min(Len1, Len2);
297c5f01b2fSopenharmony_ci  if (N <= 1) return;  // Not interesting.
298c5f01b2fSopenharmony_ci  TS->TraceMemcmpCallback(N, reinterpret_cast<const uint8_t *>(s1),
299c5f01b2fSopenharmony_ci                          reinterpret_cast<const uint8_t *>(s2));
300c5f01b2fSopenharmony_ci}
301c5f01b2fSopenharmony_ci
302c5f01b2fSopenharmony_civoid __sanitizer_weak_hook_strncasecmp(void *called_pc, const char *s1,
303c5f01b2fSopenharmony_ci                                       const char *s2, size_t n, int result) {
304c5f01b2fSopenharmony_ci  return __sanitizer_weak_hook_strncmp(called_pc, s1, s2, n, result);
305c5f01b2fSopenharmony_ci}
306c5f01b2fSopenharmony_civoid __sanitizer_weak_hook_strcasecmp(void *called_pc, const char *s1,
307c5f01b2fSopenharmony_ci                                      const char *s2, int result) {
308c5f01b2fSopenharmony_ci  return __sanitizer_weak_hook_strcmp(called_pc, s1, s2, result);
309c5f01b2fSopenharmony_ci}
310c5f01b2fSopenharmony_civoid __sanitizer_weak_hook_strstr(void *called_pc, const char *s1,
311c5f01b2fSopenharmony_ci                                  const char *s2, char *result) {
312c5f01b2fSopenharmony_ci  TS->AddInterestingWord(reinterpret_cast<const uint8_t *>(s2), strlen(s2));
313c5f01b2fSopenharmony_ci}
314c5f01b2fSopenharmony_civoid __sanitizer_weak_hook_strcasestr(void *called_pc, const char *s1,
315c5f01b2fSopenharmony_ci                                      const char *s2, char *result) {
316c5f01b2fSopenharmony_ci  TS->AddInterestingWord(reinterpret_cast<const uint8_t *>(s2), strlen(s2));
317c5f01b2fSopenharmony_ci}
318c5f01b2fSopenharmony_civoid __sanitizer_weak_hook_memmem(void *called_pc, const void *s1, size_t len1,
319c5f01b2fSopenharmony_ci                                  const void *s2, size_t len2, void *result) {
320c5f01b2fSopenharmony_ci  if (fuzzer::DoingMyOwnMemmem) return;
321c5f01b2fSopenharmony_ci  TS->AddInterestingWord(reinterpret_cast<const uint8_t *>(s2), len2);
322c5f01b2fSopenharmony_ci}
323c5f01b2fSopenharmony_ci
324c5f01b2fSopenharmony_ci#endif  // LLVM_FUZZER_DEFINES_SANITIZER_WEAK_HOOOKS
325c5f01b2fSopenharmony_ci}  // extern "C"
326