[libFuzzer] refactor: hide CurrentUnitData inside an interface function. NFC

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@270922 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Kostya Serebryany 2016-05-26 21:32:30 +00:00
parent 81b104b6a0
commit 1c5d1efdb3
3 changed files with 37 additions and 28 deletions

View File

@ -402,6 +402,13 @@ public:
// Public for tests.
void ResetCoverage();
bool InFuzzingThread() const { return IsMyThread; }
size_t GetCurrentUnitInFuzzingThead(const uint8_t **Data) const {
assert(InFuzzingThread());
*Data = CurrentUnitData;
return CurrentUnitSize;
}
private:
void AlarmCallback();
void CrashCallback();
@ -463,6 +470,9 @@ private:
// Maximum recorded coverage.
Coverage MaxCoverage;
// Need to know our own thread.
static thread_local bool IsMyThread;
};
}; // namespace fuzzer

View File

@ -61,6 +61,8 @@ namespace fuzzer {
static const size_t kMaxUnitSizeToPrint = 256;
static const size_t TruncateMaxRuns = 1000;
thread_local bool Fuzzer::IsMyThread;
static void MissingWeakApiFunction(const char *FnName) {
Printf("ERROR: %s is not defined. Exiting.\n"
"Did you use -fsanitize-coverage=... to build your code?\n",
@ -154,6 +156,7 @@ Fuzzer::Fuzzer(UserCallback CB, MutationDispatcher &MD, FuzzingOptions Options)
assert(!F);
F = this;
ResetCoverage();
IsMyThread = true;
}
void Fuzzer::SetDeathCallback() {

View File

@ -174,15 +174,9 @@ static bool RecordingMemcmp = false;
class TraceState {
public:
TraceState(MutationDispatcher &MD, const Fuzzer::FuzzingOptions &Options,
const uint8_t **CurrentUnitData, size_t *CurrentUnitSize)
: MD(MD), Options(Options), CurrentUnitData(CurrentUnitData),
CurrentUnitSize(CurrentUnitSize) {
// Current trace collection is not thread-friendly and it probably
// does not have to be such, but at least we should not crash in presence
// of threads. So, just ignore all traces coming from all threads but one.
IsMyThread = true;
}
TraceState(MutationDispatcher &MD, const Fuzzer::FuzzingOptions &Options,
const Fuzzer::Fuzzer *F)
: MD(MD), Options(Options), F(F) {}
LabelRange GetLabelRange(dfsan_label L);
void DFSanCmpCallback(uintptr_t PC, size_t CmpSize, size_t CmpType,
@ -201,12 +195,13 @@ class TraceState {
void TraceSwitchCallback(uintptr_t PC, size_t ValSizeInBits, uint64_t Val,
size_t NumCases, uint64_t *Cases);
int TryToAddDesiredData(uint64_t PresentData, uint64_t DesiredData,
size_t DataSize);
size_t DataSize);
int TryToAddDesiredData(const uint8_t *PresentData,
const uint8_t *DesiredData, size_t DataSize);
void StartTraceRecording() {
if (!Options.UseTraces && !Options.UseMemcmp) return;
if (!Options.UseTraces && !Options.UseMemcmp)
return;
RecordingTraces = Options.UseTraces;
RecordingMemcmp = Options.UseMemcmp;
NumMutations = 0;
@ -293,14 +288,11 @@ class TraceState {
size_t LastDfsanLabel = 0;
MutationDispatcher &MD;
const Fuzzer::FuzzingOptions &Options;
const uint8_t **CurrentUnitData;
size_t *CurrentUnitSize;
const Fuzzer *F;
std::map<Word, size_t> AutoDictUnitCounts;
size_t AutoDictAdds = 0;
static thread_local bool IsMyThread;
};
thread_local bool TraceState::IsMyThread;
LabelRange TraceState::GetLabelRange(dfsan_label L) {
LabelRange &LR = LabelRanges[L];
@ -316,7 +308,7 @@ void TraceState::DFSanCmpCallback(uintptr_t PC, size_t CmpSize, size_t CmpType,
uint64_t Arg1, uint64_t Arg2, dfsan_label L1,
dfsan_label L2) {
assert(ReallyHaveDFSan());
if (!RecordingTraces || !IsMyThread) return;
if (!RecordingTraces || !F->InFuzzingThread()) return;
if (L1 == 0 && L2 == 0)
return; // Not actionable.
if (L1 != 0 && L2 != 0)
@ -346,7 +338,7 @@ void TraceState::DFSanMemcmpCallback(size_t CmpSize, const uint8_t *Data1,
dfsan_label L2) {
assert(ReallyHaveDFSan());
if (!RecordingMemcmp || !IsMyThread) return;
if (!RecordingMemcmp || !F->InFuzzingThread()) return;
if (L1 == 0 && L2 == 0)
return; // Not actionable.
if (L1 != 0 && L2 != 0)
@ -365,7 +357,7 @@ void TraceState::DFSanSwitchCallback(uint64_t PC, size_t ValSizeInBits,
uint64_t Val, size_t NumCases,
uint64_t *Cases, dfsan_label L) {
assert(ReallyHaveDFSan());
if (!RecordingTraces || !IsMyThread) return;
if (!RecordingTraces || !F->InFuzzingThread()) return;
if (!L) return; // Not actionable.
LabelRange LR = GetLabelRange(L);
size_t ValSize = ValSizeInBits / 8;
@ -391,15 +383,17 @@ void TraceState::DFSanSwitchCallback(uint64_t PC, size_t ValSizeInBits,
int TraceState::TryToAddDesiredData(uint64_t PresentData, uint64_t DesiredData,
size_t DataSize) {
if (NumMutations >= kMaxMutations || !WantToHandleOneMoreMutation()) return 0;
const uint8_t *UnitData;
auto UnitSize = F->GetCurrentUnitInFuzzingThead(&UnitData);
int Res = 0;
const uint8_t *Beg = *CurrentUnitData;
const uint8_t *End = Beg + *CurrentUnitSize;
const uint8_t *Beg = UnitData;
const uint8_t *End = Beg + UnitSize;
for (const uint8_t *Cur = Beg; Cur < End; Cur++) {
Cur = (uint8_t *)memmem(Cur, End - Cur, &PresentData, DataSize);
if (!Cur)
break;
size_t Pos = Cur - Beg;
assert(Pos < *CurrentUnitSize);
assert(Pos < UnitSize);
AddMutation(Pos, DataSize, DesiredData);
AddMutation(Pos, DataSize, DesiredData + 1);
AddMutation(Pos, DataSize, DesiredData - 1);
@ -412,15 +406,17 @@ int TraceState::TryToAddDesiredData(const uint8_t *PresentData,
const uint8_t *DesiredData,
size_t DataSize) {
if (NumMutations >= kMaxMutations || !WantToHandleOneMoreMutation()) return 0;
const uint8_t *UnitData;
auto UnitSize = F->GetCurrentUnitInFuzzingThead(&UnitData);
int Res = 0;
const uint8_t *Beg = *CurrentUnitData;
const uint8_t *End = Beg + *CurrentUnitSize;
const uint8_t *Beg = UnitData;
const uint8_t *End = Beg + UnitSize;
for (const uint8_t *Cur = Beg; Cur < End; Cur++) {
Cur = (uint8_t *)memmem(Cur, End - Cur, PresentData, DataSize);
if (!Cur)
break;
size_t Pos = Cur - Beg;
assert(Pos < *CurrentUnitSize);
assert(Pos < UnitSize);
AddMutation(Pos, DataSize, DesiredData);
Res++;
}
@ -429,7 +425,7 @@ int TraceState::TryToAddDesiredData(const uint8_t *PresentData,
void TraceState::TraceCmpCallback(uintptr_t PC, size_t CmpSize, size_t CmpType,
uint64_t Arg1, uint64_t Arg2) {
if (!RecordingTraces || !IsMyThread) return;
if (!RecordingTraces || !F->InFuzzingThread()) return;
if ((CmpType == ICMP_EQ || CmpType == ICMP_NE) && Arg1 == Arg2)
return; // No reason to mutate.
int Added = 0;
@ -445,7 +441,7 @@ void TraceState::TraceCmpCallback(uintptr_t PC, size_t CmpSize, size_t CmpType,
void TraceState::TraceMemcmpCallback(size_t CmpSize, const uint8_t *Data1,
const uint8_t *Data2) {
if (!RecordingMemcmp || !IsMyThread) return;
if (!RecordingMemcmp || !F->InFuzzingThread()) return;
CmpSize = std::min(CmpSize, Word::GetMaxSize());
int Added2 = TryToAddDesiredData(Data1, Data2, CmpSize);
int Added1 = TryToAddDesiredData(Data2, Data1, CmpSize);
@ -460,7 +456,7 @@ void TraceState::TraceMemcmpCallback(size_t CmpSize, const uint8_t *Data1,
void TraceState::TraceSwitchCallback(uintptr_t PC, size_t ValSizeInBits,
uint64_t Val, size_t NumCases,
uint64_t *Cases) {
if (!RecordingTraces || !IsMyThread) return;
if (!RecordingTraces || !F->InFuzzingThread()) return;
size_t ValSize = ValSizeInBits / 8;
bool TryShort = IsTwoByteData(Val);
for (size_t i = 0; i < NumCases; i++)
@ -499,7 +495,7 @@ void Fuzzer::AssignTaintLabels(uint8_t *Data, size_t Size) {
void Fuzzer::InitializeTraceState() {
if (!Options.UseTraces && !Options.UseMemcmp) return;
TS = new TraceState(MD, Options, &CurrentUnitData, &CurrentUnitSize);
TS = new TraceState(MD, Options, this);
}
static size_t InternalStrnlen(const char *S, size_t MaxLen) {