mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-28 22:20:37 +00:00
[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
This commit is contained in:
parent
5fb1d32848
commit
2d7392fe48
@ -229,7 +229,7 @@ int RunOneTest(Fuzzer *F, const char *InputFilePath) {
|
||||
Unit U = FileToVector(InputFilePath);
|
||||
Unit PreciseSizedU(U);
|
||||
assert(PreciseSizedU.size() == PreciseSizedU.capacity());
|
||||
F->ExecuteCallback(PreciseSizedU);
|
||||
F->ExecuteCallback(PreciseSizedU.data(), PreciseSizedU.size());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -93,7 +93,7 @@ void ComputeSHA1(const uint8_t *Data, size_t Len, uint8_t *Out);
|
||||
|
||||
// Changes U to contain only ASCII (isprint+isspace) characters.
|
||||
// Returns true iff U has been changed.
|
||||
bool ToASCII(Unit &U);
|
||||
bool ToASCII(uint8_t *Data, size_t Size);
|
||||
bool IsASCII(const Unit &U);
|
||||
|
||||
int NumberOfCpuCores();
|
||||
@ -251,6 +251,7 @@ private:
|
||||
std::vector<Mutator> CurrentMutatorSequence;
|
||||
std::vector<DictionaryEntry *> CurrentDictionaryEntrySequence;
|
||||
const std::vector<Unit> *Corpus = nullptr;
|
||||
std::vector<uint8_t> MutateInPlaceHere;
|
||||
|
||||
static Mutator Mutators[];
|
||||
};
|
||||
@ -318,7 +319,7 @@ public:
|
||||
|
||||
static void StaticAlarmCallback();
|
||||
|
||||
void ExecuteCallback(const Unit &U);
|
||||
void ExecuteCallback(const uint8_t *Data, size_t Size);
|
||||
|
||||
// Merge Corpora[1:] into Corpora[0].
|
||||
void Merge(const std::vector<std::string> &Corpora);
|
||||
@ -328,8 +329,9 @@ private:
|
||||
void AlarmCallback();
|
||||
void MutateAndTestOne();
|
||||
void ReportNewCoverage(const Unit &U);
|
||||
bool RunOne(const Unit &U);
|
||||
void RunOneAndUpdateCorpus(Unit &U);
|
||||
bool RunOne(const uint8_t *Data, size_t Size);
|
||||
bool RunOne(const Unit &U) { return RunOne(U.data(), U.size()); }
|
||||
void RunOneAndUpdateCorpus(uint8_t *Data, size_t Size);
|
||||
void WriteToOutputCorpus(const Unit &U);
|
||||
void WriteUnitToFileWithPrefix(const Unit &U, const char *Prefix);
|
||||
void PrintStats(const char *Where, const char *End = "\n");
|
||||
@ -376,6 +378,8 @@ private:
|
||||
return Res;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> MutateInPlaceHere;
|
||||
|
||||
std::piecewise_constant_distribution<double> CorpusDistribution;
|
||||
UserCallback CB;
|
||||
MutationDispatcher &MD;
|
||||
|
@ -208,7 +208,7 @@ void Fuzzer::ShuffleAndMinimize() {
|
||||
size_t Last = std::min(First + Options.MaxLen, C.size());
|
||||
U.insert(U.begin(), C.begin() + First, C.begin() + Last);
|
||||
if (Options.OnlyASCII)
|
||||
ToASCII(U);
|
||||
ToASCII(U.data(), U.size());
|
||||
if (RunOne(U)) {
|
||||
NewCorpus.push_back(U);
|
||||
if (Options.Verbosity >= 2)
|
||||
@ -223,12 +223,12 @@ void Fuzzer::ShuffleAndMinimize() {
|
||||
PrintStats("INITED");
|
||||
}
|
||||
|
||||
bool Fuzzer::RunOne(const Unit &U) {
|
||||
bool Fuzzer::RunOne(const uint8_t *Data, size_t Size) {
|
||||
UnitStartTime = system_clock::now();
|
||||
TotalNumberOfRuns++;
|
||||
|
||||
PrepareCoverageBeforeRun();
|
||||
ExecuteCallback(U);
|
||||
ExecuteCallback(Data, Size);
|
||||
bool Res = CheckCoverageAfterRun();
|
||||
|
||||
auto UnitStopTime = system_clock::now();
|
||||
@ -241,29 +241,29 @@ bool Fuzzer::RunOne(const Unit &U) {
|
||||
TimeOfUnit >= Options.ReportSlowUnits) {
|
||||
TimeOfLongestUnitInSeconds = TimeOfUnit;
|
||||
Printf("Slowest unit: %zd s:\n", TimeOfLongestUnitInSeconds);
|
||||
WriteUnitToFileWithPrefix(U, "slow-unit-");
|
||||
WriteUnitToFileWithPrefix({Data, Data + Size}, "slow-unit-");
|
||||
}
|
||||
return Res;
|
||||
}
|
||||
|
||||
void Fuzzer::RunOneAndUpdateCorpus(Unit &U) {
|
||||
void Fuzzer::RunOneAndUpdateCorpus(uint8_t *Data, size_t Size) {
|
||||
if (TotalNumberOfRuns >= Options.MaxNumberOfRuns)
|
||||
return;
|
||||
if (Options.OnlyASCII)
|
||||
ToASCII(U);
|
||||
if (RunOne(U))
|
||||
ReportNewCoverage(U);
|
||||
ToASCII(Data, Size);
|
||||
if (RunOne(Data, Size))
|
||||
ReportNewCoverage({Data, Data + Size});
|
||||
}
|
||||
|
||||
void Fuzzer::ExecuteCallback(const Unit &U) {
|
||||
void Fuzzer::ExecuteCallback(const uint8_t *Data, size_t Size) {
|
||||
// We copy the contents of Unit into a separate heap buffer
|
||||
// so that we reliably find buffer overflows in it.
|
||||
std::unique_ptr<uint8_t[]> Data(new uint8_t[U.size()]);
|
||||
memcpy(Data.get(), U.data(), U.size());
|
||||
AssignTaintLabels(Data.get(), U.size());
|
||||
CurrentUnitData = Data.get();
|
||||
CurrentUnitSize = U.size();
|
||||
int Res = CB(Data.get(), U.size());
|
||||
std::unique_ptr<uint8_t[]> DataCopy(new uint8_t[Size]);
|
||||
memcpy(DataCopy.get(), Data, Size);
|
||||
AssignTaintLabels(DataCopy.get(), Size);
|
||||
CurrentUnitData = DataCopy.get();
|
||||
CurrentUnitSize = Size;
|
||||
int Res = CB(DataCopy.get(), Size);
|
||||
(void)Res;
|
||||
assert(Res == 0);
|
||||
CurrentUnitData = nullptr;
|
||||
@ -411,24 +411,25 @@ void Fuzzer::Merge(const std::vector<std::string> &Corpora) {
|
||||
void Fuzzer::MutateAndTestOne() {
|
||||
MD.StartMutationSequence();
|
||||
|
||||
auto U = ChooseUnitToMutate();
|
||||
auto &U = ChooseUnitToMutate();
|
||||
MutateInPlaceHere.resize(Options.MaxLen);
|
||||
memcpy(MutateInPlaceHere.data(), U.data(), U.size());
|
||||
size_t Size = U.size();
|
||||
|
||||
for (int i = 0; i < Options.MutateDepth; i++) {
|
||||
size_t Size = U.size();
|
||||
U.resize(Options.MaxLen);
|
||||
size_t NewSize = 0;
|
||||
if (LLVMFuzzerCustomMutator)
|
||||
NewSize = LLVMFuzzerCustomMutator(U.data(), Size, U.size(),
|
||||
MD.GetRand().Rand());
|
||||
NewSize = LLVMFuzzerCustomMutator(MutateInPlaceHere.data(), Size,
|
||||
Options.MaxLen, MD.GetRand().Rand());
|
||||
else
|
||||
NewSize = MD.Mutate(U.data(), Size, U.size());
|
||||
NewSize = MD.Mutate(MutateInPlaceHere.data(), Size, Options.MaxLen);
|
||||
assert(NewSize > 0 && "Mutator returned empty unit");
|
||||
assert(NewSize <= (size_t)Options.MaxLen &&
|
||||
"Mutator return overisized unit");
|
||||
U.resize(NewSize);
|
||||
Size = NewSize;
|
||||
if (i == 0)
|
||||
StartTraceRecording();
|
||||
RunOneAndUpdateCorpus(U);
|
||||
RunOneAndUpdateCorpus(MutateInPlaceHere.data(), Size);
|
||||
StopTraceRecording();
|
||||
}
|
||||
}
|
||||
|
@ -176,7 +176,8 @@ size_t MutationDispatcher::Mutate_CrossOver(uint8_t *Data, size_t Size,
|
||||
size_t Idx = Rand(Corpus->size());
|
||||
const Unit &Other = (*Corpus)[Idx];
|
||||
if (Other.empty()) return 0;
|
||||
Unit U(MaxSize);
|
||||
MutateInPlaceHere.resize(MaxSize);
|
||||
auto &U = MutateInPlaceHere;
|
||||
size_t NewSize =
|
||||
CrossOver(Data, Size, Other.data(), Other.size(), U.data(), U.size());
|
||||
assert(NewSize > 0 && "CrossOver returned empty unit");
|
||||
|
@ -93,9 +93,10 @@ int ExecuteCommand(const std::string &Command) {
|
||||
return system(Command.c_str());
|
||||
}
|
||||
|
||||
bool ToASCII(Unit &U) {
|
||||
bool ToASCII(uint8_t *Data, size_t Size) {
|
||||
bool Changed = false;
|
||||
for (auto &X : U) {
|
||||
for (size_t i = 0; i < Size; i++) {
|
||||
uint8_t &X = Data[i];
|
||||
auto NewX = X;
|
||||
NewX &= 127;
|
||||
if (!isspace(NewX) && !isprint(NewX))
|
||||
|
Loading…
Reference in New Issue
Block a user