1 //===- FuzzerMutate.cpp - Mutation utilities -----------------------------===//
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 // Mutate utilities.
9 //===----------------------------------------------------------------------===//
10 
11 #include "FuzzerMutate.h"
12 #include "FuzzerExtFunctions.h"
13 #include "FuzzerIO.h"
14 #include "FuzzerTracePC.h"
15 #include "FuzzerUtil.h"
16 
17 namespace fuzzer {
18 namespace {
19 
20 void FromTORC4(size_t Idx, uint32_t *A, uint32_t *B) {
21   const auto &X = TPC.TORC4.Get(Idx);
22   *A = X.A;
23   *B = X.B;
24 }
25 
26 void FromTORC8(size_t Idx, uint64_t *A, uint64_t *B) {
27   const auto &X = TPC.TORC8.Get(Idx);
28   *A = X.A;
29   *B = X.B;
30 }
31 
32 void FromTORCW(size_t Idx, const uint8_t **DataA, size_t *SizeA,
33                const uint8_t **DataB, size_t *SizeB) {
34   const auto &X = TPC.TORCW.Get(Idx);
35   *DataA = X.A.data();
36   *SizeA = X.A.size();
37   *DataB = X.B.data();
38   *SizeB = X.B.size();
39 }
40 
41 void FromMMT(size_t Idx, const uint8_t **Data, size_t *Size) {
42   const auto &W = TPC.MMT.Get(Idx);
43   *Data = W.data();
44   *Size = W.size();
45 }
46 
47 void PrintASCII(const Word &W, const char *PrintAfter) {
48   fuzzer::PrintASCII(W.data(), W.size(), PrintAfter);
49 }
50 
51 } // namespace
52 
53 void ConfigureMutagen(unsigned int Seed, const FuzzingOptions &Options,
54                       LLVMMutagenConfiguration *OutConfig) {
55   memset(OutConfig, 0, sizeof(*OutConfig));
56   OutConfig->Seed = Seed;
57   OutConfig->UseCmp = Options.UseCmp;
58   OutConfig->FromTORC4 = FromTORC4;
59   OutConfig->FromTORC8 = FromTORC8;
60   OutConfig->FromTORCW = FromTORCW;
61   OutConfig->UseMemmem = Options.UseMemmem;
62   OutConfig->FromMMT = FromMMT;
63   OutConfig->CustomMutator = EF->LLVMFuzzerCustomMutator;
64   OutConfig->CustomCrossOver = EF->LLVMFuzzerCustomCrossOver;
65   OutConfig->MSanUnpoison = EF->__msan_unpoison;
66   OutConfig->MSanUnpoisonParam = EF->__msan_unpoison_param;
67 }
68 
69 void PrintRecommendedDictionary(MutationDispatcher &MD) {
70   auto RecommendedDictionary = MD.RecommendDictionary();
71   if (RecommendedDictionary.empty())
72     return;
73   Printf("###### Recommended dictionary. ######\n");
74   for (auto &DE : RecommendedDictionary) {
75     assert(DE.GetW().size());
76     Printf("\"");
77     PrintASCII(DE.GetW(), "\"");
78     Printf(" # Uses: %zd\n", DE.GetUseCount());
79   }
80   Printf("###### End of recommended dictionary. ######\n");
81 }
82 
83 void PrintMutationSequence(MutationDispatcher &MD, bool Verbose) {
84   const auto &MS = MD.MutationSequence();
85   const auto &DS = MD.DictionaryEntrySequence();
86   Printf("MS: %zd %s", MS.size(), MS.GetString(Verbose).c_str());
87   if (!DS.empty())
88     Printf(" DE: %s", DS.GetString(Verbose).c_str());
89 }
90 
91 }  // namespace fuzzer
92