blob: a96a2c087e2d843a3e763513081df1a7ae519992 [file] [log] [blame]
Kostya Serebryany6f5a8042016-09-21 01:50:50 +00001//===- FuzzerTracePC.h - Internal header for the Fuzzer ---------*- C++ -* ===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9// fuzzer::TracePC
10//===----------------------------------------------------------------------===//
11
12#ifndef LLVM_FUZZER_TRACE_PC
13#define LLVM_FUZZER_TRACE_PC
14
15#include "FuzzerDefs.h"
Kostya Serebryany86586182016-09-21 21:17:23 +000016#include "FuzzerValueBitMap.h"
Kostya Serebryany6f5a8042016-09-21 01:50:50 +000017
18namespace fuzzer {
19
20class TracePC {
21 public:
Kostya Serebryany2c556132016-09-30 01:19:56 +000022 static const size_t kFeatureSetSize = ValueBitMap::kNumberOfItems;
23
Kostya Serebryanya9b0dd02016-09-29 17:43:24 +000024 void HandleTrace(uint32_t *guard, uintptr_t PC);
25 void HandleInit(uint32_t *start, uint32_t *stop);
Kostya Serebryany6f5a8042016-09-21 01:50:50 +000026 void HandleCallerCallee(uintptr_t Caller, uintptr_t Callee);
Kostya Serebryanyab73c692016-09-23 00:46:18 +000027 void HandleValueProfile(size_t Value) { ValueProfileMap.AddValue(Value); }
Kostya Serebryany87a598e2016-09-23 01:20:07 +000028 size_t GetTotalPCCoverage() { return TotalPCCoverage; }
29 void ResetTotalPCCoverage() { TotalPCCoverage = 0; }
Kostya Serebryany6f5a8042016-09-21 01:50:50 +000030 void SetUseCounters(bool UC) { UseCounters = UC; }
Kostya Serebryanyab73c692016-09-23 00:46:18 +000031 void SetUseValueProfile(bool VP) { UseValueProfile = VP; }
Kostya Serebryanyd28099d2016-09-23 00:22:46 +000032 bool UpdateCounterMap(ValueBitMap *MaxCounterMap) {
Kostya Serebryany87a598e2016-09-23 01:20:07 +000033 return MaxCounterMap->MergeFrom(CounterMap);
Kostya Serebryanyd28099d2016-09-23 00:22:46 +000034 }
Kostya Serebryanyab73c692016-09-23 00:46:18 +000035 bool UpdateValueProfileMap(ValueBitMap *MaxValueProfileMap) {
36 return UseValueProfile && MaxValueProfileMap->MergeFrom(ValueProfileMap);
37 }
Kostya Serebryanyd2169222016-10-01 01:04:29 +000038 bool FinalizeTrace(size_t InputSize);
Kostya Serebryany6f5a8042016-09-21 01:50:50 +000039
Kostya Serebryany624f59f2016-09-22 01:34:58 +000040 size_t GetNewPCIDs(uintptr_t **NewPCIDsPtr) {
41 *NewPCIDsPtr = NewPCIDs;
Kostya Serebryanyd28099d2016-09-23 00:22:46 +000042 return Min(kMaxNewPCIDs, NumNewPCIDs);
Kostya Serebryany6f5a8042016-09-21 01:50:50 +000043 }
44
Kostya Serebryany624f59f2016-09-22 01:34:58 +000045 uintptr_t GetPCbyPCID(uintptr_t PCID) { return PCs[PCID]; }
46
Kostya Serebryanyce1cab12016-09-23 02:18:59 +000047 void ResetMaps() {
Kostya Serebryany624f59f2016-09-22 01:34:58 +000048 NumNewPCIDs = 0;
Kostya Serebryany6f5a8042016-09-21 01:50:50 +000049 CounterMap.Reset();
Kostya Serebryany16a145f2016-09-23 01:58:51 +000050 ValueProfileMap.Reset();
Kostya Serebryany0d26de32016-09-23 20:04:13 +000051 memset(Counters, 0, sizeof(Counters));
Kostya Serebryany6f5a8042016-09-21 01:50:50 +000052 }
53
Kostya Serebryany0800b812016-09-23 23:51:58 +000054 void UpdateFeatureSet(size_t CurrentElementIdx, size_t CurrentElementSize);
55 void PrintFeatureSet();
56
Kostya Serebryanyce1cab12016-09-23 02:18:59 +000057 void ResetGuards();
58
Kostya Serebryany6f5a8042016-09-21 01:50:50 +000059 void PrintModuleInfo();
60
61 void PrintCoverage();
62
Kostya Serebryany2c556132016-09-30 01:19:56 +000063 bool HasFeature(size_t Idx) { return CounterMap.Get(Idx); }
64
Kostya Serebryany379359c2016-10-05 01:09:40 +000065 void AddValueForMemcmp(void *caller_pc, const void *s1, const void *s2,
66 size_t n);
67 void AddValueForStrcmp(void *caller_pc, const char *s1, const char *s2,
68 size_t n);
69
Kostya Serebryany6f5a8042016-09-21 01:50:50 +000070private:
71 bool UseCounters = false;
Kostya Serebryanyab73c692016-09-23 00:46:18 +000072 bool UseValueProfile = false;
Kostya Serebryany87a598e2016-09-23 01:20:07 +000073 size_t TotalPCCoverage = 0;
Kostya Serebryany6f5a8042016-09-21 01:50:50 +000074
Kostya Serebryany5ff481f2016-09-27 00:10:20 +000075 static const size_t kMaxNewPCIDs = 1024;
Kostya Serebryany624f59f2016-09-22 01:34:58 +000076 uintptr_t NewPCIDs[kMaxNewPCIDs];
77 size_t NumNewPCIDs = 0;
78 void AddNewPCID(uintptr_t PCID) {
79 NewPCIDs[(NumNewPCIDs++) % kMaxNewPCIDs] = PCID;
80 }
Kostya Serebryany6f5a8042016-09-21 01:50:50 +000081
Kostya Serebryany6f5a8042016-09-21 01:50:50 +000082 struct Module {
Kostya Serebryanya9b0dd02016-09-29 17:43:24 +000083 uint32_t *Start, *Stop;
Kostya Serebryany6f5a8042016-09-21 01:50:50 +000084 };
85
86 Module Modules[4096];
87 size_t NumModules = 0;
88 size_t NumGuards = 0;
89
90 static const size_t kNumCounters = 1 << 14;
Kostya Serebryany3ee6c212016-09-28 01:16:24 +000091 alignas(8) uint8_t Counters[kNumCounters];
Kostya Serebryany6f5a8042016-09-21 01:50:50 +000092
93 static const size_t kNumPCs = 1 << 20;
94 uintptr_t PCs[kNumPCs];
95
96 ValueBitMap CounterMap;
Kostya Serebryanyab73c692016-09-23 00:46:18 +000097 ValueBitMap ValueProfileMap;
Kostya Serebryanyd2169222016-10-01 01:04:29 +000098 uint32_t InputSizesPerFeature[kFeatureSetSize];
Kostya Serebryany6f5a8042016-09-21 01:50:50 +000099};
100
101extern TracePC TPC;
102
103} // namespace fuzzer
104
105#endif // LLVM_FUZZER_TRACE_PC