diff options
author | George Karpenkov <ekarpenkov@apple.com> | 2018-10-10 00:57:44 +0000 |
---|---|---|
committer | George Karpenkov <ekarpenkov@apple.com> | 2018-10-10 00:57:44 +0000 |
commit | f28523bb3fd67ab80a60d989bbfa7ca7763596ab (patch) | |
tree | 0d40c382b22ec10cb2ca816303d81b316fe5eeae | |
parent | ea13613572db918380b21c34a755abc3531a39a4 (diff) | |
download | llvm-f28523bb3fd67ab80a60d989bbfa7ca7763596ab.zip llvm-f28523bb3fd67ab80a60d989bbfa7ca7763596ab.tar.gz llvm-f28523bb3fd67ab80a60d989bbfa7ca7763596ab.tar.bz2 |
[libFuzzer] Generalize the code for getting the previous offset for different architectures
Without this change, tests in coverage.test and dump_coverage.test are
failing on non-x86_64 platforms.
The diff is copied from sanitizer_common library, an alternative would
be to link it together with libFuzzer.
Differential Revision: https://reviews.llvm.org/D53040
llvm-svn: 344104
-rw-r--r-- | compiler-rt/lib/fuzzer/FuzzerTracePC.cpp | 46 | ||||
-rw-r--r-- | compiler-rt/test/fuzzer/coverage.test | 2 | ||||
-rw-r--r-- | compiler-rt/test/fuzzer/dump_coverage.test | 2 | ||||
-rw-r--r-- | compiler-rt/test/fuzzer/handle-unstable.test | 2 |
4 files changed, 36 insertions, 16 deletions
diff --git a/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp b/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp index 7513084..7ba75c7 100644 --- a/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerTracePC.cpp @@ -194,11 +194,42 @@ void TracePC::HandleCallerCallee(uintptr_t Caller, uintptr_t Callee) { ValueProfileMap.AddValueModPrime(Idx); } +/// \return the address of the previous instruction. +/// Note: the logic is copied from `sanitizer_common/sanitizer_stacktrace.h` +inline ALWAYS_INLINE uintptr_t GetPreviousInstructionPc(uintptr_t PC) { +#if defined(__arm__) + // T32 (Thumb) branch instructions might be 16 or 32 bit long, + // so we return (pc-2) in that case in order to be safe. + // For A32 mode we return (pc-4) because all instructions are 32 bit long. + return (PC - 3) & (~1); +#elif defined(__powerpc__) || defined(__powerpc64__) || defined(__aarch64__) + // PCs are always 4 byte aligned. + return PC - 4; +#elif defined(__sparc__) || defined(__mips__) + return PC - 8; +#else + return PC - 1; +#endif +} + +/// \return the address of the next instruction. +/// Note: the logic is copied from `sanitizer_common/sanitizer_stacktrace.cc` +inline ALWAYS_INLINE uintptr_t GetNextInstructionPc(uintptr_t PC) { +#if defined(__mips__) + return PC + 8; +#elif defined(__powerpc__) || defined(__sparc__) || defined(__arm__) || \ + defined(__aarch64__) + return PC + 4; +#else + return PC + 1; +#endif +} + void TracePC::UpdateObservedPCs() { Vector<uintptr_t> CoveredFuncs; auto ObservePC = [&](uintptr_t PC) { if (ObservedPCs.insert(PC).second && DoPrintNewPCs) { - PrintPC("\tNEW_PC: %p %F %L", "\tNEW_PC: %p", PC + 1); + PrintPC("\tNEW_PC: %p %F %L", "\tNEW_PC: %p", GetNextInstructionPc(PC)); Printf("\n"); } }; @@ -233,22 +264,11 @@ void TracePC::UpdateObservedPCs() { for (size_t i = 0, N = Min(CoveredFuncs.size(), NumPrintNewFuncs); i < N; i++) { Printf("\tNEW_FUNC[%zd/%zd]: ", i + 1, CoveredFuncs.size()); - PrintPC("%p %F %L", "%p", CoveredFuncs[i] + 1); + PrintPC("%p %F %L", "%p", GetNextInstructionPc(CoveredFuncs[i])); Printf("\n"); } } -inline ALWAYS_INLINE uintptr_t GetPreviousInstructionPc(uintptr_t PC) { - // TODO: this implementation is x86 only. - // see sanitizer_common GetPreviousInstructionPc for full implementation. - return PC - 1; -} - -inline ALWAYS_INLINE uintptr_t GetNextInstructionPc(uintptr_t PC) { - // TODO: this implementation is x86 only. - // see sanitizer_common GetPreviousInstructionPc for full implementation. - return PC + 1; -} static std::string GetModuleName(uintptr_t PC) { char ModulePathRaw[4096] = ""; // What's PATH_MAX in portable C++? diff --git a/compiler-rt/test/fuzzer/coverage.test b/compiler-rt/test/fuzzer/coverage.test index 12a91c8..ff7a436 100644 --- a/compiler-rt/test/fuzzer/coverage.test +++ b/compiler-rt/test/fuzzer/coverage.test @@ -1,5 +1,5 @@ # FIXME: Disabled on Windows because -fPIC cannot be used to compile for Windows. -UNSUPPORTED: aarch64, windows +UNSUPPORTED: windows RUN: %cpp_compiler -mllvm -use-unknown-locations=Disable %S/NullDerefTest.cpp -o %t-NullDerefTest RUN: %cpp_compiler -mllvm -use-unknown-locations=Disable %S/DSO1.cpp -fPIC %ld_flags_rpath_so1 -shared -o %dynamiclib1 RUN: %cpp_compiler -mllvm -use-unknown-locations=Disable %S/DSO2.cpp -fPIC %ld_flags_rpath_so2 -shared -o %dynamiclib2 diff --git a/compiler-rt/test/fuzzer/dump_coverage.test b/compiler-rt/test/fuzzer/dump_coverage.test index 21e4348..803a4fb 100644 --- a/compiler-rt/test/fuzzer/dump_coverage.test +++ b/compiler-rt/test/fuzzer/dump_coverage.test @@ -8,7 +8,7 @@ RUN: %cpp_compiler -fsanitize-coverage=0 -fsanitize-coverage=trace-pc-guard %S/N RUN: rm -rf %t_workdir && mkdir -p %t_workdir RUN: env ASAN_OPTIONS=coverage_dir='"%t_workdir"' not %run %t-NullDerefTest -dump_coverage=1 2>&1 | FileCheck %s -RUN: sancov -covered-functions %t-NullDerefTest* %t_workdir/*.sancov | FileCheck %s --check-prefix=SANCOV +RUN: sancov -covered-functions %t-NullDerefTest %t_workdir/*.sancov | FileCheck %s --check-prefix=SANCOV RUN: env ASAN_OPTIONS=coverage_dir='"%t_workdir"' %run %t-DSOTest -dump_coverage=1 -runs=0 2>&1 | FileCheck -allow-deprecated-dag-overlap %s --check-prefix=DSO RUN: env ASAN_OPTIONS=coverage_dir='"%t_workdir"' not %run %t-NullDerefTest -dump_coverage=0 2>&1 | FileCheck %s --check-prefix=NOCOV diff --git a/compiler-rt/test/fuzzer/handle-unstable.test b/compiler-rt/test/fuzzer/handle-unstable.test index ea8d9e8..d202246 100644 --- a/compiler-rt/test/fuzzer/handle-unstable.test +++ b/compiler-rt/test/fuzzer/handle-unstable.test @@ -1,6 +1,6 @@ # Tests -handle_unstable # FIXME: Disabled on Windows until symbolization works properly. -UNSUPPORTED: aarch64, windows +UNSUPPORTED: windows RUN: %cpp_compiler %S/PrintUnstableStatsTest.cpp -o %t-HandleUnstableTest |