diff options
| author | Mike Aizatsky <aizatsky@chromium.org> | 2017-01-17 23:11:32 +0000 |
|---|---|---|
| committer | Mike Aizatsky <aizatsky@chromium.org> | 2017-01-17 23:11:32 +0000 |
| commit | 0e37f8e41d6d4c9095112360f8d3d14492249e33 (patch) | |
| tree | 97a8570411ee580a525befd2bc2bb4e09cb4439b /llvm/lib/Fuzzer/FuzzerTracePC.cpp | |
| parent | c095f6a037f48c223d6aa893549939e953428bf9 (diff) | |
| download | bcm5719-llvm-0e37f8e41d6d4c9095112360f8d3d14492249e33.tar.gz bcm5719-llvm-0e37f8e41d6d4c9095112360f8d3d14492249e33.zip | |
[libfuzzer] fixing collected pc addresses for coverage
Summary: The causes google/ossfuzz#84
Reviewers: kcc
Subscribers: mgorny
Differential Revision: https://reviews.llvm.org/D28827
llvm-svn: 292289
Diffstat (limited to 'llvm/lib/Fuzzer/FuzzerTracePC.cpp')
| -rw-r--r-- | llvm/lib/Fuzzer/FuzzerTracePC.cpp | 43 |
1 files changed, 26 insertions, 17 deletions
diff --git a/llvm/lib/Fuzzer/FuzzerTracePC.cpp b/llvm/lib/Fuzzer/FuzzerTracePC.cpp index e9101fbb786..6b31808c843 100644 --- a/llvm/lib/Fuzzer/FuzzerTracePC.cpp +++ b/llvm/lib/Fuzzer/FuzzerTracePC.cpp @@ -236,15 +236,11 @@ void TracePC::AddValueForMemcmp(void *caller_pc, const void *s1, const void *s2, } template <class T> -ATTRIBUTE_TARGET_POPCNT -#ifdef __clang__ // g++ can't handle this __attribute__ here :( -__attribute__((always_inline)) -#endif // __clang__ -void TracePC::HandleCmp(void *PC, T Arg1, T Arg2) { - uintptr_t PCuint = reinterpret_cast<uintptr_t>(PC); +ATTRIBUTE_TARGET_POPCNT ALWAYS_INLINE +void TracePC::HandleCmp(uintptr_t PC, T Arg1, T Arg2) { uint64_t ArgXor = Arg1 ^ Arg2; uint64_t ArgDistance = __builtin_popcountl(ArgXor) + 1; // [1,65] - uintptr_t Idx = ((PCuint & 4095) + 1) * ArgDistance; + uintptr_t Idx = ((PC & 4095) + 1) * ArgDistance; if (sizeof(T) == 4) TORC4.Insert(ArgXor, Arg1, Arg2); else if (sizeof(T) == 8) @@ -252,12 +248,18 @@ void TracePC::HandleCmp(void *PC, T Arg1, T Arg2) { HandleValueProfile(Idx); } +inline ALWAYS_INLINE uintptr_t GetPreviousInstructionPc(void* pc) { + // TODO: this implementation is x86 only. + // see sanitizer_common GetPreviousInstructionPc for full implementation. + return reinterpret_cast<uintptr_t>(pc) - 1; +} + } // namespace fuzzer extern "C" { __attribute__((visibility("default"))) void __sanitizer_cov_trace_pc_guard(uint32_t *Guard) { - uintptr_t PC = (uintptr_t)__builtin_return_address(0); + uintptr_t PC = fuzzer::GetPreviousInstructionPc(__builtin_return_address(0)); fuzzer::TPC.HandleTrace(Guard, PC); } @@ -268,25 +270,29 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *Start, uint32_t *Stop) { __attribute__((visibility("default"))) void __sanitizer_cov_trace_pc_indir(uintptr_t Callee) { - uintptr_t PC = (uintptr_t)__builtin_return_address(0); + uintptr_t PC = fuzzer::GetPreviousInstructionPc(__builtin_return_address(0)); fuzzer::TPC.HandleCallerCallee(PC, Callee); } __attribute__((visibility("default"))) void __sanitizer_cov_trace_cmp8(uint64_t Arg1, uint64_t Arg2) { - fuzzer::TPC.HandleCmp(__builtin_return_address(0), Arg1, Arg2); + uintptr_t PC = fuzzer::GetPreviousInstructionPc(__builtin_return_address(0)); + fuzzer::TPC.HandleCmp(PC, Arg1, Arg2); } __attribute__((visibility("default"))) void __sanitizer_cov_trace_cmp4(uint32_t Arg1, uint32_t Arg2) { - fuzzer::TPC.HandleCmp(__builtin_return_address(0), Arg1, Arg2); + uintptr_t PC = fuzzer::GetPreviousInstructionPc(__builtin_return_address(0)); + fuzzer::TPC.HandleCmp(PC, Arg1, Arg2); } __attribute__((visibility("default"))) void __sanitizer_cov_trace_cmp2(uint16_t Arg1, uint16_t Arg2) { - fuzzer::TPC.HandleCmp(__builtin_return_address(0), Arg1, Arg2); + uintptr_t PC = fuzzer::GetPreviousInstructionPc(__builtin_return_address(0)); + fuzzer::TPC.HandleCmp(PC, Arg1, Arg2); } __attribute__((visibility("default"))) void __sanitizer_cov_trace_cmp1(uint8_t Arg1, uint8_t Arg2) { - fuzzer::TPC.HandleCmp(__builtin_return_address(0), Arg1, Arg2); + uintptr_t PC = fuzzer::GetPreviousInstructionPc(__builtin_return_address(0)); + fuzzer::TPC.HandleCmp(PC, Arg1, Arg2); } __attribute__((visibility("default"))) @@ -297,7 +303,7 @@ void __sanitizer_cov_trace_switch(uint64_t Val, uint64_t *Cases) { // Skip the most common and the most boring case. if (Vals[N - 1] < 256 && Val < 256) return; - char *PC = (char*)__builtin_return_address(0); + uintptr_t PC = fuzzer::GetPreviousInstructionPc(__builtin_return_address(0)); size_t i; uint64_t Token = 0; for (i = 0; i < N; i++) { @@ -316,15 +322,18 @@ void __sanitizer_cov_trace_switch(uint64_t Val, uint64_t *Cases) { __attribute__((visibility("default"))) void __sanitizer_cov_trace_div4(uint32_t Val) { - fuzzer::TPC.HandleCmp(__builtin_return_address(0), Val, (uint32_t)0); + uintptr_t PC = fuzzer::GetPreviousInstructionPc(__builtin_return_address(0)); + fuzzer::TPC.HandleCmp(PC, Val, (uint32_t)0); } __attribute__((visibility("default"))) void __sanitizer_cov_trace_div8(uint64_t Val) { - fuzzer::TPC.HandleCmp(__builtin_return_address(0), Val, (uint64_t)0); + uintptr_t PC = fuzzer::GetPreviousInstructionPc(__builtin_return_address(0)); + fuzzer::TPC.HandleCmp(PC, Val, (uint64_t)0); } __attribute__((visibility("default"))) void __sanitizer_cov_trace_gep(uintptr_t Idx) { - fuzzer::TPC.HandleCmp(__builtin_return_address(0), Idx, (uintptr_t)0); + uintptr_t PC = fuzzer::GetPreviousInstructionPc(__builtin_return_address(0)); + fuzzer::TPC.HandleCmp(PC, Idx, (uintptr_t)0); } } // extern "C" |

