23 #include <sanitizer/coverage_interface.h>
34 PCs[Idx % kNumPCs] =
PC;
35 Counters[Idx % kNumCounters]++;
47 if (Start == Stop || *Start)
return;
48 assert(NumModules <
sizeof(Modules) /
sizeof(Modules[0]));
51 Modules[NumModules].Start = Start;
52 Modules[NumModules].Stop = Stop;
57 Printf(
"INFO: Loaded %zd modules (%zd guards): ", NumModules, NumGuards);
58 for (
size_t i = 0;
i < NumModules;
i++)
59 Printf(
"[%p, %p), ", Modules[
i].Start, Modules[
i].Stop);
64 const uintptr_t kBits = 12;
65 const uintptr_t kMask = (1 << kBits) - 1;
66 uintptr_t Idx = (Caller & kMask) | ((Callee & kMask) << kBits);
71 if (File.find(
"compiler-rt/lib/") != std::string::npos)
73 if (File.find(
"/usr/lib/") != std::string::npos)
75 if (File.find(
"/usr/include/") != std::string::npos)
83 if (!DoPrintNewPCs)
return;
85 PrintedPCs =
new std::set<uintptr_t>;
88 PrintedPCs->insert(PCs[i]);
92 if (!DoPrintNewPCs)
return;
95 if (PCs[
i] && PrintedPCs->insert(PCs[
i]).second)
96 PrintPC(
"\tNEW_PC: %p %F %L\n",
"\tNEW_PC: %p\n", PCs[i]);
100 if (!
EF->__sanitizer_symbolize_pc ||
101 !
EF->__sanitizer_get_module_and_offset_for_pc) {
102 Printf(
"INFO: __sanitizer_symbolize_pc or "
103 "__sanitizer_get_module_and_offset_for_pc is not available,"
104 " not printing coverage\n");
107 std::map<std::string, std::vector<uintptr_t>> CoveredPCsPerModule;
108 std::map<std::string, uintptr_t> ModuleOffsets;
109 std::set<std::string> CoveredDirs, CoveredFiles, CoveredFunctions,
113 if (!PCs[
i])
continue;
114 std::string FileStr =
DescribePC(
"%s", PCs[i]);
116 std::string FixedPCStr =
DescribePC(
"%p", PCs[i]);
117 std::string FunctionStr =
DescribePC(
"%F", PCs[i]);
118 std::string LineStr =
DescribePC(
"%l", PCs[i]);
119 char ModulePathRaw[4096] =
"";
120 void *OffsetRaw =
nullptr;
121 if (!
EF->__sanitizer_get_module_and_offset_for_pc(
122 reinterpret_cast<void *>(PCs[i]), ModulePathRaw,
123 sizeof(ModulePathRaw), &OffsetRaw))
125 std::string Module = ModulePathRaw;
126 uintptr_t FixedPC = std::stol(FixedPCStr, 0, 16);
127 uintptr_t PcOffset =
reinterpret_cast<uintptr_t
>(OffsetRaw);
128 ModuleOffsets[Module] = FixedPC - PcOffset;
129 CoveredPCsPerModule[Module].push_back(PcOffset);
130 CoveredFunctions.insert(FunctionStr);
131 CoveredFiles.insert(FileStr);
132 CoveredDirs.insert(
DirName(FileStr));
133 if (!CoveredLines.insert(FileStr +
":" + LineStr).second)
135 Printf(
"COVERED: %s %s:%s\n", FunctionStr.c_str(),
136 FileStr.c_str(), LineStr.c_str());
139 std::string CoveredDirsStr;
140 for (
auto &Dir : CoveredDirs) {
141 if (!CoveredDirsStr.empty())
142 CoveredDirsStr +=
",";
143 CoveredDirsStr += Dir;
145 Printf(
"COVERED_DIRS: %s\n", CoveredDirsStr.c_str());
147 for (
auto &M : CoveredPCsPerModule) {
148 std::set<std::string> UncoveredFiles, UncoveredFunctions;
149 std::map<std::string, std::set<int> > UncoveredLines;
150 auto &ModuleName = M.first;
151 auto &CoveredOffsets = M.second;
152 uintptr_t ModuleOffset = ModuleOffsets[ModuleName];
153 std::sort(CoveredOffsets.begin(), CoveredOffsets.end());
154 Printf(
"MODULE_WITH_COVERAGE: %s\n", ModuleName.c_str());
157 std::string Cmd =
"objdump -d " + ModuleName +
158 " | grep 'call.*__sanitizer_cov_trace_pc_guard' | awk -F: '{print $1}'";
159 std::string SanCovOutput;
161 Printf(
"INFO: Command failed: %s\n", Cmd.c_str());
164 std::istringstream ISS(SanCovOutput);
166 while (std::getline(ISS, S,
'\n')) {
167 uintptr_t PcOffset = std::stol(S, 0, 16);
168 if (!std::binary_search(CoveredOffsets.begin(), CoveredOffsets.end(),
170 uintptr_t
PC = ModuleOffset + PcOffset;
173 if (CoveredFiles.count(FileStr) == 0) {
174 UncoveredFiles.insert(FileStr);
178 if (CoveredFunctions.count(FunctionStr) == 0) {
179 UncoveredFunctions.insert(FunctionStr);
183 uintptr_t Line = std::stoi(LineStr);
184 std::string FileLineStr = FileStr +
":" + LineStr;
185 if (CoveredLines.count(FileLineStr) == 0)
186 UncoveredLines[FunctionStr +
" " + FileStr].insert(Line);
189 for (
auto &FileLine: UncoveredLines)
190 for (
int Line : FileLine.second)
191 Printf(
"UNCOVERED_LINE: %s:%d\n", FileLine.first.c_str(), Line);
192 for (
auto &
Func : UncoveredFunctions)
194 for (
auto &
File : UncoveredFiles)
200 __sanitizer_dump_coverage(PCs,
GetNumPCs());
217 size_t Len =
std::min(n, (
size_t)32);
218 const uint8_t *A1 =
reinterpret_cast<const uint8_t *
>(s1);
219 const uint8_t *A2 =
reinterpret_cast<const uint8_t *
>(s2);
224 size_t PC =
reinterpret_cast<size_t>(caller_pc);
235 size_t Len =
std::min(n, (
size_t)32);
236 const uint8_t *A1 =
reinterpret_cast<const uint8_t *
>(s1);
237 const uint8_t *A2 =
reinterpret_cast<const uint8_t *
>(s2);
240 if (A1[I] != A2[I] || A1[I] == 0)
242 size_t PC =
reinterpret_cast<size_t>(caller_pc);
251 #ifdef __clang__ // g++ can't handle this __attribute__ here :(
255 uintptr_t PCuint =
reinterpret_cast<uintptr_t
>(
PC);
256 uint64_t ArgXor = Arg1 ^
Arg2;
257 uint64_t ArgDistance = __builtin_popcountl(ArgXor) + 1;
258 uintptr_t Idx = ((PCuint & 4095) + 1) * ArgDistance;
261 else if (
sizeof(
T) == 8)
270 void __sanitizer_cov_trace_pc_guard(
uint32_t *Guard) {
271 uintptr_t
PC = (uintptr_t)__builtin_return_address(0);
281 void __sanitizer_cov_trace_pc_indir(uintptr_t Callee) {
282 uintptr_t
PC = (uintptr_t)__builtin_return_address(0);
287 void __sanitizer_cov_trace_cmp8(uint64_t Arg1, uint64_t
Arg2) {
295 void __sanitizer_cov_trace_cmp2(uint16_t Arg1, uint16_t Arg2) {
299 void __sanitizer_cov_trace_cmp1(uint8_t Arg1, uint8_t Arg2) {
304 void __sanitizer_cov_trace_switch(uint64_t Val, uint64_t *
Cases) {
305 uint64_t
N = Cases[0];
309 if (Vals[N - 1] < 256 && Val < 256)
311 char *PC = (
char*)__builtin_return_address(0);
314 for (i = 0; i <
N; i++) {
315 Token = Val ^ Vals[
i];
320 if (ValSizeInBits == 16)
322 else if (ValSizeInBits == 32)
329 void __sanitizer_cov_trace_div4(
uint32_t Val) {
333 void __sanitizer_cov_trace_div8(uint64_t Val) {
337 void __sanitizer_cov_trace_gep(uintptr_t Idx) {
void AddValueForStrcmp(void *caller_pc, const char *s1, const char *s2, size_t n)
__attribute__((visibility("default"))) void __sanitizer_cov_trace_pc_guard(uint32_t *Guard)
TableOfRecentCompares< uint32_t, kTORCSize > TORC4
bool ExecuteCommandAndReadOutput(const std::string &Command, std::string *Out)
void AddValueForMemcmp(void *caller_pc, const void *s1, const void *s2, size_t n)
#define ATTRIBUTE_NO_SANITIZE_MEMORY
void HandleCallerCallee(uintptr_t Caller, uintptr_t Callee)
void HandleTrace(uint32_t *guard, uintptr_t PC)
std::string DescribePC(const char *SymbolizedFMT, uintptr_t PC)
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with etc Experimental Use value profile to guide fuzzing Number of simultaneous worker processes to run the jobs If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
void Printf(const char *Fmt,...)
void HandleValueProfile(size_t Value)
size_t GetTotalPCCoverage()
void HandleCmp(void *PC, T Arg1, T Arg2)
void HandleInit(uint32_t *start, uint32_t *stop)
void PrintPC(const char *SymbolizedFMT, const char *FallbackFMT, uintptr_t PC)
void Insert(size_t Idx, T Arg1, T Arg2)
#define ATTRIBUTE_TARGET_POPCNT
void InitializePrintNewPCs()
TableOfRecentCompares< uint64_t, kTORCSize > TORC8
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
std::string DirName(const std::string &FileName)
static bool IsInterestingCoverageFile(std::string &File)