summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2016-08-10 20:08:19 +0000
committerReid Kleckner <rnk@google.com>2016-08-10 20:08:19 +0000
commit0881472ac4e8f8b0624730162ce682b1a788f4a4 (patch)
tree4810c8ff4dfff71d5714483335eb85e2b6fac2a2
parent7725546a3263b81a792895aaa348d310263118ad (diff)
downloadbcm5719-llvm-0881472ac4e8f8b0624730162ce682b1a788f4a4.tar.gz
bcm5719-llvm-0881472ac4e8f8b0624730162ce682b1a788f4a4.zip
[sancov] Port sancov -print-coverage-pcs to COFF
The export table is not considered part of the object file symbol table, so we have to look through it separately. Reviewers: kcc Differential Revision: https://reviews.llvm.org/D23321 llvm-svn: 278284
-rw-r--r--llvm/test/tools/sancov/Inputs/test-windows_x86_64bin0 -> 712704 bytes
-rw-r--r--llvm/test/tools/sancov/print_coverage_pcs.test43
-rw-r--r--llvm/tools/sancov/sancov.cc31
3 files changed, 59 insertions, 15 deletions
diff --git a/llvm/test/tools/sancov/Inputs/test-windows_x86_64 b/llvm/test/tools/sancov/Inputs/test-windows_x86_64
new file mode 100644
index 00000000000..3eaab93b4cf
--- /dev/null
+++ b/llvm/test/tools/sancov/Inputs/test-windows_x86_64
Binary files differ
diff --git a/llvm/test/tools/sancov/print_coverage_pcs.test b/llvm/test/tools/sancov/print_coverage_pcs.test
index 8a86c4fa1ea..f106f46934f 100644
--- a/llvm/test/tools/sancov/print_coverage_pcs.test
+++ b/llvm/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
diff --git a/llvm/tools/sancov/sancov.cc b/llvm/tools/sancov/sancov.cc
index 55b03709dde..e3742fa0391 100644
--- a/llvm/tools/sancov/sancov.cc
+++ b/llvm/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 @@ static std::vector<AddrInfo> getAddrInfo(const std::string &ObjectFile,
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<uint64_t>
@@ -333,13 +339,28 @@ findSanitizerCovFunctions(const object::ObjectFile &O) {
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<object::COFFObjectFile>(&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 @@ public:
return BufOrErr.getError();
std::unique_ptr<MemoryBuffer> 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<const FileHeader *>(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 @@ public:
Addrs.get());
break;
default:
- errs() << "Unsupported bitness: " << Header->Bitness;
+ errs() << "Unsupported bitness: " << Header->Bitness << '\n';
return make_error_code(errc::illegal_byte_sequence);
}
OpenPOWER on IntegriCloud