Index: llvm/trunk/test/tools/sancov/print_coverage_pcs.test =================================================================== --- llvm/trunk/test/tools/sancov/print_coverage_pcs.test +++ llvm/trunk/test/tools/sancov/print_coverage_pcs.test @@ -1,13 +1,36 @@ REQUIRES: x86-registered-target -RUN: sancov -print-coverage-pcs %p/Inputs/test-linux_x86_64 | FileCheck %s +RUN: sancov -print-coverage-pcs %p/Inputs/test-linux_x86_64 | FileCheck %s --check-prefix=LINUX +RUN: llvm-objdump -d %p/Inputs/test-windows_x86_64 | FileCheck %s --check-prefix=DISAS_WIN +RUN: sancov -print-coverage-pcs %p/Inputs/test-windows_x86_64 | FileCheck %s --check-prefix=WINDOWS -CHECK: 0x4e132b -CHECK: 0x4e1472 -CHECK: 0x4e14c2 -CHECK: 0x4e1520 -CHECK: 0x4e1553 -CHECK: 0x4e1586 -CHECK: 0x4e1635 -CHECK: 0x4e1690 -CHECK: 0x4e178c +LINUX: 0x4e132b +LINUX: 0x4e1472 +LINUX: 0x4e14c2 +LINUX: 0x4e1520 +LINUX: 0x4e1553 +LINUX: 0x4e1586 +LINUX: 0x4e1635 +LINUX: 0x4e1690 +LINUX: 0x4e178c +The coverage PCs should be equal to the return address of the call minus one. A +direct call is five bytes, so the coverage PCs should be call PC plus four. + +DISAS_WIN: 14000103f: {{.*}} callq {{.*}} <__sanitizer_cov> +WINDOWS: 0x140001043 +DISAS_WIN: 140001074: {{.*}} callq {{.*}} <__sanitizer_cov> +WINDOWS: 0x140001078 +DISAS_WIN: 1400011df: {{.*}} callq {{.*}} <__sanitizer_cov> +WINDOWS: 0x1400011e3 +DISAS_WIN: 140001227: {{.*}} callq {{.*}} <__sanitizer_cov> +WINDOWS: 0x14000122b +DISAS_WIN: 14000147e: {{.*}} callq {{.*}} <__sanitizer_cov> +WINDOWS: 0x140001482 +DISAS_WIN: 1400015b6: {{.*}} callq {{.*}} <__sanitizer_cov> +WINDOWS: 0x1400015ba +DISAS_WIN: 140001629: {{.*}} callq {{.*}} <__sanitizer_cov> +WINDOWS: 0x14000162d +DISAS_WIN: 140001664: {{.*}} callq {{.*}} <__sanitizer_cov> +WINDOWS: 0x140001668 +DISAS_WIN: 1400016f2: {{.*}} callq {{.*}} <__sanitizer_cov> +WINDOWS: 0x1400016f6 Index: llvm/trunk/tools/sancov/sancov.cc =================================================================== --- llvm/trunk/tools/sancov/sancov.cc +++ llvm/trunk/tools/sancov/sancov.cc @@ -25,6 +25,7 @@ #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/Object/Archive.h" #include "llvm/Object/Binary.h" +#include "llvm/Object/COFF.h" #include "llvm/Object/ELFObjectFile.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Casting.h" @@ -319,6 +320,11 @@ return Result; } +static bool isCoveragePointSymbol(StringRef Name) { + return Name == "__sanitizer_cov" || Name == "__sanitizer_cov_with_check" || + Name == "__sanitizer_cov_trace_func_enter"; +} + // Locate __sanitizer_cov* function addresses that are used for coverage // reporting. static std::set @@ -333,13 +339,28 @@ FailIfError(errorToErrorCode(NameOrErr.takeError())); StringRef Name = NameOrErr.get(); - if (Name == "__sanitizer_cov" || Name == "__sanitizer_cov_with_check" || - Name == "__sanitizer_cov_trace_func_enter") { + if (isCoveragePointSymbol(Name)) { if (!(Symbol.getFlags() & object::BasicSymbolRef::SF_Undefined)) Result.insert(AddressOrErr.get()); } } + if (const auto *CO = dyn_cast(&O)) { + for (const object::ExportDirectoryEntryRef &Export : + CO->export_directories()) { + uint32_t RVA; + std::error_code EC = Export.getExportRVA(RVA); + FailIfError(EC); + + StringRef Name; + EC = Export.getSymbolName(Name); + FailIfError(EC); + + if (isCoveragePointSymbol(Name)) + Result.insert(CO->getImageBase() + RVA); + } + } + return Result; } @@ -577,14 +598,14 @@ return BufOrErr.getError(); std::unique_ptr Buf = std::move(BufOrErr.get()); if (Buf->getBufferSize() < 8) { - errs() << "File too small (<8): " << Buf->getBufferSize(); + errs() << "File too small (<8): " << Buf->getBufferSize() << '\n'; return make_error_code(errc::illegal_byte_sequence); } const FileHeader *Header = reinterpret_cast(Buf->getBufferStart()); if (Header->Magic != BinCoverageMagic) { - errs() << "Wrong magic: " << Header->Magic; + errs() << "Wrong magic: " << Header->Magic << '\n'; return make_error_code(errc::illegal_byte_sequence); } @@ -600,7 +621,7 @@ Addrs.get()); break; default: - errs() << "Unsupported bitness: " << Header->Bitness; + errs() << "Unsupported bitness: " << Header->Bitness << '\n'; return make_error_code(errc::illegal_byte_sequence); }