mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[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
This commit is contained in:
parent
661ec64587
commit
1117519321
BIN
test/tools/sancov/Inputs/test-windows_x86_64
Normal file
BIN
test/tools/sancov/Inputs/test-windows_x86_64
Normal file
Binary file not shown.
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user