blob: 788e6f4d9356626b6d5dca2213caedc0a8b9c065 [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 Serebryany17d176e12016-10-13 16:19:09 +000028 template <class T> void HandleCmp(void *PC, T Arg1, T Arg2);
Kostya Serebryany87a598e2016-09-23 01:20:07 +000029 size_t GetTotalPCCoverage() { return TotalPCCoverage; }
30 void ResetTotalPCCoverage() { TotalPCCoverage = 0; }
Kostya Serebryany6f5a8042016-09-21 01:50:50 +000031 void SetUseCounters(bool UC) { UseCounters = UC; }
Kostya Serebryanyab73c692016-09-23 00:46:18 +000032 void SetUseValueProfile(bool VP) { UseValueProfile = VP; }
Kostya Serebryany1c73f1b2016-10-05 22:56:21 +000033 size_t FinalizeTrace(InputCorpus *C, size_t InputSize, bool Shrink);
Kostya Serebryanyab73c692016-09-23 00:46:18 +000034 bool UpdateValueProfileMap(ValueBitMap *MaxValueProfileMap) {
35 return UseValueProfile && MaxValueProfileMap->MergeFrom(ValueProfileMap);
Kostya Serebryany17d176e12016-10-13 16:19:09 +000036 }
Kostya Serebryany6f5a8042016-09-21 01:50:50 +000037
Kostya Serebryany624f59f2016-09-22 01:34:58 +000038 size_t GetNewPCIDs(uintptr_t **NewPCIDsPtr) {
39 *NewPCIDsPtr = NewPCIDs;
Kostya Serebryanyd28099d2016-09-23 00:22:46 +000040 return Min(kMaxNewPCIDs, NumNewPCIDs);
Kostya Serebryany6f5a8042016-09-21 01:50:50 +000041 }
42
Kostya Serebryany624f59f2016-09-22 01:34:58 +000043 uintptr_t GetPCbyPCID(uintptr_t PCID) { return PCs[PCID]; }
44
Kostya Serebryanyce1cab12016-09-23 02:18:59 +000045 void ResetMaps() {
Kostya Serebryany624f59f2016-09-22 01:34:58 +000046 NumNewPCIDs = 0;
Kostya Serebryany16a145f2016-09-23 01:58:51 +000047 ValueProfileMap.Reset();
Kostya Serebryany0d26de32016-09-23 20:04:13 +000048 memset(Counters, 0, sizeof(Counters));
Kostya Serebryany6f5a8042016-09-21 01:50:50 +000049 }
50
Kostya Serebryany0800b812016-09-23 23:51:58 +000051 void UpdateFeatureSet(size_t CurrentElementIdx, size_t CurrentElementSize);
52 void PrintFeatureSet();
53
Kostya Serebryanyce1cab12016-09-23 02:18:59 +000054 void ResetGuards();
55
Kostya Serebryany6f5a8042016-09-21 01:50:50 +000056 void PrintModuleInfo();
57
58 void PrintCoverage();
59
Kostya Serebryany379359c2016-10-05 01:09:40 +000060 void AddValueForMemcmp(void *caller_pc, const void *s1, const void *s2,
61 size_t n);
62 void AddValueForStrcmp(void *caller_pc, const char *s1, const char *s2,
63 size_t n);
64
Kostya Serebryany1c73f1b2016-10-05 22:56:21 +000065 bool UsingTracePcGuard() const {return NumModules; }
66
Kostya Serebryany6f5a8042016-09-21 01:50:50 +000067private:
68 bool UseCounters = false;
Kostya Serebryanyab73c692016-09-23 00:46:18 +000069 bool UseValueProfile = false;
Kostya Serebryany87a598e2016-09-23 01:20:07 +000070 size_t TotalPCCoverage = 0;
Kostya Serebryany6f5a8042016-09-21 01:50:50 +000071
Kostya Serebryany5ff481f2016-09-27 00:10:20 +000072 static const size_t kMaxNewPCIDs = 1024;
Kostya Serebryany624f59f2016-09-22 01:34:58 +000073 uintptr_t NewPCIDs[kMaxNewPCIDs];
74 size_t NumNewPCIDs = 0;
75 void AddNewPCID(uintptr_t PCID) {
76 NewPCIDs[(NumNewPCIDs++) % kMaxNewPCIDs] = PCID;
77 }
Kostya Serebryany6f5a8042016-09-21 01:50:50 +000078
Kostya Serebryany6f5a8042016-09-21 01:50:50 +000079 struct Module {
Kostya Serebryanya9b0dd02016-09-29 17:43:24 +000080 uint32_t *Start, *Stop;
Kostya Serebryany6f5a8042016-09-21 01:50:50 +000081 };
82
83 Module Modules[4096];
84 size_t NumModules = 0;
85 size_t NumGuards = 0;
86
87 static const size_t kNumCounters = 1 << 14;
Kostya Serebryany3ee6c212016-09-28 01:16:24 +000088 alignas(8) uint8_t Counters[kNumCounters];
Kostya Serebryany6f5a8042016-09-21 01:50:50 +000089
Kostya Serebryanyd19919a2016-10-11 01:14:41 +000090 static const size_t kNumPCs = 1 << 24;
Kostya Serebryany6f5a8042016-09-21 01:50:50 +000091 uintptr_t PCs[kNumPCs];
92
Kostya Serebryanyab73c692016-09-23 00:46:18 +000093 ValueBitMap ValueProfileMap;
Kostya Serebryany6f5a8042016-09-21 01:50:50 +000094};
95
96extern TracePC TPC;
97
98} // namespace fuzzer
99
100#endif // LLVM_FUZZER_TRACE_PC