summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Fuzzer/FuzzerTracePC.cpp
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2016-10-14 20:20:33 +0000
committerKostya Serebryany <kcc@google.com>2016-10-14 20:20:33 +0000
commita5f94fb6c9cb447ebf32bef848d81ac867fd1c63 (patch)
tree7517f668bf9bcebd8fec1c80d44e3086426557e2 /llvm/lib/Fuzzer/FuzzerTracePC.cpp
parent3ed0f643fc3267b7fbb319e4cb5610e5a7e1ba86 (diff)
downloadbcm5719-llvm-a5f94fb6c9cb447ebf32bef848d81ac867fd1c63.tar.gz
bcm5719-llvm-a5f94fb6c9cb447ebf32bef848d81ac867fd1c63.zip
[libFuzzer] add -trace_cmp=1 (guiding mutations based on the observed CMP instructions). This is a reincarnation of the previously deleted -use_traces, but using a different approach for collecting traces. Still a toy, but at least it scales well. Also fix -merge in trace-pc-guard mode
llvm-svn: 284273
Diffstat (limited to 'llvm/lib/Fuzzer/FuzzerTracePC.cpp')
-rw-r--r--llvm/lib/Fuzzer/FuzzerTracePC.cpp54
1 files changed, 53 insertions, 1 deletions
diff --git a/llvm/lib/Fuzzer/FuzzerTracePC.cpp b/llvm/lib/Fuzzer/FuzzerTracePC.cpp
index d843f542cdd..cfaf9c5e571 100644
--- a/llvm/lib/Fuzzer/FuzzerTracePC.cpp
+++ b/llvm/lib/Fuzzer/FuzzerTracePC.cpp
@@ -14,6 +14,7 @@
#include "FuzzerCorpus.h"
#include "FuzzerDefs.h"
+#include "FuzzerDictionary.h"
#include "FuzzerTracePC.h"
#include "FuzzerValueBitMap.h"
@@ -170,11 +171,62 @@ __attribute__((always_inline))
#endif // __clang__
void TracePC::HandleCmp(void *PC, T Arg1, T Arg2) {
uintptr_t PCuint = reinterpret_cast<uintptr_t>(PC);
- uint64_t ArgDistance = __builtin_popcountl(Arg1 ^ Arg2) + 1; // [1,65]
+ uint64_t ArgXor = Arg1 ^ Arg2;
+ uint64_t ArgDistance = __builtin_popcountl(ArgXor) + 1; // [1,65]
uintptr_t Idx = ((PCuint & 4095) + 1) * ArgDistance;
+ TORCInsert(ArgXor, Arg1, Arg2);
HandleValueProfile(Idx);
}
+void TracePC::ProcessTORC(Dictionary *Dict, const uint8_t *Data, size_t Size) {
+ TORCToDict(TORC8, Dict, Data, Size);
+ TORCToDict(TORC4, Dict, Data, Size);
+}
+
+template <class T>
+void TracePC::TORCToDict(const TableOfRecentCompares<T, kTORCSize> &TORC,
+ Dictionary *Dict, const uint8_t *Data, size_t Size) {
+ ScopedDoingMyOwnMemmem scoped_doing_my_own_memmem;
+ for (size_t i = 0; i < TORC.kSize; i++) {
+ T A[2] = {TORC.Table[i][0], TORC.Table[i][1]};
+ if (!A[0] && !A[1]) continue;
+ for (int j = 0; j < 2; j++)
+ TORCToDict(Dict, A[j], A[!j], Data, Size);
+ }
+}
+
+template <class T>
+void TracePC::TORCToDict(Dictionary *Dict, T FindInData, T Substitute,
+ const uint8_t *Data, size_t Size) {
+ if (FindInData == Substitute) return;
+ if (sizeof(T) == 4) {
+ uint16_t HigherBytes = Substitute >> sizeof(T) * 4;
+ if (HigherBytes == 0 || HigherBytes == 0xffff)
+ TORCToDict(Dict, static_cast<uint16_t>(FindInData),
+ static_cast<uint16_t>(Substitute), Data, Size);
+ }
+ const size_t DataSize = sizeof(T);
+ const uint8_t *End = Data + Size;
+ int Attempts = 3;
+ // TODO: also swap bytes in FindInData.
+ for (const uint8_t *Cur = Data; Cur < End && Attempts--; Cur++) {
+ Cur = (uint8_t *)memmem(Cur, End - Cur, &FindInData, DataSize);
+ if (!Cur)
+ break;
+ size_t Pos = Cur - Data;
+ for (int Offset = 0; Offset <= 0; Offset++) {
+ T Tmp = Substitute + Offset;
+ Word W(reinterpret_cast<uint8_t *>(&Tmp), sizeof(Tmp));
+ DictionaryEntry DE(W, Pos);
+ // TODO: evict all entries from Dic if it's full.
+ Dict->push_back(DE);
+ // Printf("Dict[%zd] TORC%zd %llx => %llx pos %zd\n", Dict->size(),
+ // sizeof(T),
+ // (uint64_t)FindInData, (uint64_t)Tmp, Pos);
+ }
+ }
+}
+
} // namespace fuzzer
extern "C" {
OpenPOWER on IntegriCloud