llvm.org GIT mirror llvm / 2d7392f
[libFuzzer] remove std::vector operations from hot paths, NFC git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@260829 91177308-0d34-0410-b5e6-96231b3b80d8 Kostya Serebryany 4 years ago
5 changed file(s) with 40 addition(s) and 33 deletion(s). Raw diff Collapse all Expand all
228228 Unit U = FileToVector(InputFilePath);
229229 Unit PreciseSizedU(U);
230230 assert(PreciseSizedU.size() == PreciseSizedU.capacity());
231 F->ExecuteCallback(PreciseSizedU);
231 F->ExecuteCallback(PreciseSizedU.data(), PreciseSizedU.size());
232232 return 0;
233233 }
234234
9292
9393 // Changes U to contain only ASCII (isprint+isspace) characters.
9494 // Returns true iff U has been changed.
95 bool ToASCII(Unit &U);
95 bool ToASCII(uint8_t *Data, size_t Size);
9696 bool IsASCII(const Unit &U);
9797
9898 int NumberOfCpuCores();
250250 std::vector CurrentMutatorSequence;
251251 std::vector CurrentDictionaryEntrySequence;
252252 const std::vector *Corpus = nullptr;
253 std::vector MutateInPlaceHere;
253254
254255 static Mutator Mutators[];
255256 };
317318
318319 static void StaticAlarmCallback();
319320
320 void ExecuteCallback(const Unit &U);
321 void ExecuteCallback(const uint8_t *Data, size_t Size);
321322
322323 // Merge Corpora[1:] into Corpora[0].
323324 void Merge(const std::vector &Corpora);
327328 void AlarmCallback();
328329 void MutateAndTestOne();
329330 void ReportNewCoverage(const Unit &U);
330 bool RunOne(const Unit &U);
331 void RunOneAndUpdateCorpus(Unit &U);
331 bool RunOne(const uint8_t *Data, size_t Size);
332 bool RunOne(const Unit &U) { return RunOne(U.data(), U.size()); }
333 void RunOneAndUpdateCorpus(uint8_t *Data, size_t Size);
332334 void WriteToOutputCorpus(const Unit &U);
333335 void WriteUnitToFileWithPrefix(const Unit &U, const char *Prefix);
334336 void PrintStats(const char *Where, const char *End = "\n");
374376 Res += __builtin_popcount(x);
375377 return Res;
376378 }
379
380 std::vector MutateInPlaceHere;
377381
378382 std::piecewise_constant_distribution CorpusDistribution;
379383 UserCallback CB;
207207 size_t Last = std::min(First + Options.MaxLen, C.size());
208208 U.insert(U.begin(), C.begin() + First, C.begin() + Last);
209209 if (Options.OnlyASCII)
210 ToASCII(U);
210 ToASCII(U.data(), U.size());
211211 if (RunOne(U)) {
212212 NewCorpus.push_back(U);
213213 if (Options.Verbosity >= 2)
222222 PrintStats("INITED");
223223 }
224224
225 bool Fuzzer::RunOne(const Unit &U) {
225 bool Fuzzer::RunOne(const uint8_t *Data, size_t Size) {
226226 UnitStartTime = system_clock::now();
227227 TotalNumberOfRuns++;
228228
229229 PrepareCoverageBeforeRun();
230 ExecuteCallback(U);
230 ExecuteCallback(Data, Size);
231231 bool Res = CheckCoverageAfterRun();
232232
233233 auto UnitStopTime = system_clock::now();
240240 TimeOfUnit >= Options.ReportSlowUnits) {
241241 TimeOfLongestUnitInSeconds = TimeOfUnit;
242242 Printf("Slowest unit: %zd s:\n", TimeOfLongestUnitInSeconds);
243 WriteUnitToFileWithPrefix(U, "slow-unit-");
243 WriteUnitToFileWithPrefix({Data, Data + Size}, "slow-unit-");
244244 }
245245 return Res;
246246 }
247247
248 void Fuzzer::RunOneAndUpdateCorpus(Unit &U) {
248 void Fuzzer::RunOneAndUpdateCorpus(uint8_t *Data, size_t Size) {
249249 if (TotalNumberOfRuns >= Options.MaxNumberOfRuns)
250250 return;
251251 if (Options.OnlyASCII)
252 ToASCII(U);
253 if (RunOne(U))
254 ReportNewCoverage(U);
255 }
256
257 void Fuzzer::ExecuteCallback(const Unit &U) {
252 ToASCII(Data, Size);
253 if (RunOne(Data, Size))
254 ReportNewCoverage({Data, Data + Size});
255 }
256
257 void Fuzzer::ExecuteCallback(const uint8_t *Data, size_t Size) {
258258 // We copy the contents of Unit into a separate heap buffer
259259 // so that we reliably find buffer overflows in it.
260 std::unique_ptr Data(new uint8_t[U.size()]);
261 memcpy(Data.get(), U.data(), U.size());
262 AssignTaintLabels(Data.get(), U.size());
263 CurrentUnitData = Data.get();
264 CurrentUnitSize = U.size();
265 int Res = CB(Data.get(), U.size());
260 std::unique_ptr DataCopy(new uint8_t[Size]);
261 memcpy(DataCopy.get(), Data, Size);
262 AssignTaintLabels(DataCopy.get(), Size);
263 CurrentUnitData = DataCopy.get();
264 CurrentUnitSize = Size;
265 int Res = CB(DataCopy.get(), Size);
266266 (void)Res;
267267 assert(Res == 0);
268268 CurrentUnitData = nullptr;
410410 void Fuzzer::MutateAndTestOne() {
411411 MD.StartMutationSequence();
412412
413 auto U = ChooseUnitToMutate();
413 auto &U = ChooseUnitToMutate();
414 MutateInPlaceHere.resize(Options.MaxLen);
415 memcpy(MutateInPlaceHere.data(), U.data(), U.size());
416 size_t Size = U.size();
414417
415418 for (int i = 0; i < Options.MutateDepth; i++) {
416 size_t Size = U.size();
417 U.resize(Options.MaxLen);
418419 size_t NewSize = 0;
419420 if (LLVMFuzzerCustomMutator)
420 NewSize = LLVMFuzzerCustomMutator(U.data(), Size, U.size(),
421 MD.GetRand().Rand());
421 NewSize = LLVMFuzzerCustomMutator(MutateInPlaceHere.data(), Size,
422 Options.MaxLen, MD.GetRand().Rand());
422423 else
423 NewSize = MD.Mutate(U.data(), Size, U.size());
424 NewSize = MD.Mutate(MutateInPlaceHere.data(), Size, Options.MaxLen);
424425 assert(NewSize > 0 && "Mutator returned empty unit");
425426 assert(NewSize <= (size_t)Options.MaxLen &&
426427 "Mutator return overisized unit");
427 U.resize(NewSize);
428 Size = NewSize;
428429 if (i == 0)
429430 StartTraceRecording();
430 RunOneAndUpdateCorpus(U);
431 RunOneAndUpdateCorpus(MutateInPlaceHere.data(), Size);
431432 StopTraceRecording();
432433 }
433434 }
175175 size_t Idx = Rand(Corpus->size());
176176 const Unit &Other = (*Corpus)[Idx];
177177 if (Other.empty()) return 0;
178 Unit U(MaxSize);
178 MutateInPlaceHere.resize(MaxSize);
179 auto &U = MutateInPlaceHere;
179180 size_t NewSize =
180181 CrossOver(Data, Size, Other.data(), Other.size(), U.data(), U.size());
181182 assert(NewSize > 0 && "CrossOver returned empty unit");
9292 return system(Command.c_str());
9393 }
9494
95 bool ToASCII(Unit &U) {
95 bool ToASCII(uint8_t *Data, size_t Size) {
9696 bool Changed = false;
97 for (auto &X : U) {
97 for (size_t i = 0; i < Size; i++) {
98 uint8_t &X = Data[i];
9899 auto NewX = X;
99100 NewX &= 127;
100101 if (!isspace(NewX) && !isprint(NewX))