summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/ProfileData/CoverageMapping.h4
-rw-r--r--llvm/include/llvm/ProfileData/CoverageMappingReader.h4
-rw-r--r--llvm/lib/ProfileData/CoverageMapping.cpp5
-rw-r--r--llvm/lib/ProfileData/CoverageMappingReader.cpp34
-rwxr-xr-xllvm/test/tools/llvm-cov/Inputs/universal-binarybin0 -> 960 bytes
-rw-r--r--llvm/test/tools/llvm-cov/Inputs/universal-binary.proftext4
-rw-r--r--llvm/test/tools/llvm-cov/universal-binary.c13
-rw-r--r--llvm/tools/llvm-cov/CodeCoverage.cpp18
8 files changed, 71 insertions, 11 deletions
diff --git a/llvm/include/llvm/ProfileData/CoverageMapping.h b/llvm/include/llvm/ProfileData/CoverageMapping.h
index 08a4f5ca16a..e9d6ea5a492 100644
--- a/llvm/include/llvm/ProfileData/CoverageMapping.h
+++ b/llvm/include/llvm/ProfileData/CoverageMapping.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Hashing.h"
+#include "llvm/ADT/Triple.h"
#include "llvm/ADT/iterator.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorOr.h"
@@ -408,7 +409,8 @@ public:
/// \brief Load the coverage mapping from the given files.
static ErrorOr<std::unique_ptr<CoverageMapping>>
- load(StringRef ObjectFilename, StringRef ProfileFilename);
+ load(StringRef ObjectFilename, StringRef ProfileFilename,
+ Triple::ArchType Arch = Triple::ArchType::UnknownArch);
/// \brief The number of functions that couldn't have their profiles mapped.
///
diff --git a/llvm/include/llvm/ProfileData/CoverageMappingReader.h b/llvm/include/llvm/ProfileData/CoverageMappingReader.h
index 671436608ff..bc68f0b47a2 100644
--- a/llvm/include/llvm/ProfileData/CoverageMappingReader.h
+++ b/llvm/include/llvm/ProfileData/CoverageMappingReader.h
@@ -17,6 +17,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/ProfileData/CoverageMapping.h"
#include "llvm/ProfileData/InstrProf.h"
@@ -175,7 +176,8 @@ private:
public:
static ErrorOr<std::unique_ptr<BinaryCoverageReader>>
- create(std::unique_ptr<MemoryBuffer> &ObjectBuffer);
+ create(std::unique_ptr<MemoryBuffer> &ObjectBuffer,
+ Triple::ArchType Arch = Triple::ArchType::UnknownArch);
std::error_code readNextRecord(CoverageMappingRecord &Record) override;
};
diff --git a/llvm/lib/ProfileData/CoverageMapping.cpp b/llvm/lib/ProfileData/CoverageMapping.cpp
index 31213d7fb2d..86b2b879904 100644
--- a/llvm/lib/ProfileData/CoverageMapping.cpp
+++ b/llvm/lib/ProfileData/CoverageMapping.cpp
@@ -217,12 +217,13 @@ CoverageMapping::load(CoverageMappingReader &CoverageReader,
}
ErrorOr<std::unique_ptr<CoverageMapping>>
-CoverageMapping::load(StringRef ObjectFilename, StringRef ProfileFilename) {
+CoverageMapping::load(StringRef ObjectFilename, StringRef ProfileFilename,
+ Triple::ArchType Arch) {
auto CounterMappingBuff = MemoryBuffer::getFileOrSTDIN(ObjectFilename);
if (std::error_code EC = CounterMappingBuff.getError())
return EC;
auto CoverageReaderOrErr =
- BinaryCoverageReader::create(CounterMappingBuff.get());
+ BinaryCoverageReader::create(CounterMappingBuff.get(), Arch);
if (std::error_code EC = CoverageReaderOrErr.getError())
return EC;
auto CoverageReader = std::move(CoverageReaderOrErr.get());
diff --git a/llvm/lib/ProfileData/CoverageMappingReader.cpp b/llvm/lib/ProfileData/CoverageMappingReader.cpp
index d32f1dac456..3f8f76f6094 100644
--- a/llvm/lib/ProfileData/CoverageMappingReader.cpp
+++ b/llvm/lib/ProfileData/CoverageMappingReader.cpp
@@ -14,6 +14,7 @@
#include "llvm/ProfileData/CoverageMappingReader.h"
#include "llvm/ADT/DenseSet.h"
+#include "llvm/Object/MachOUniversal.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/LEB128.h"
@@ -444,11 +445,31 @@ static std::error_code loadTestingFormat(StringRef Data,
static std::error_code loadBinaryFormat(MemoryBufferRef ObjectBuffer,
SectionData &ProfileNames,
StringRef &CoverageMapping,
- uint8_t &BytesInAddress) {
- auto ObjectFileOrErr = object::ObjectFile::createObjectFile(ObjectBuffer);
- if (std::error_code EC = ObjectFileOrErr.getError())
+ uint8_t &BytesInAddress,
+ Triple::ArchType Arch) {
+ auto BinOrErr = object::createBinary(ObjectBuffer);
+ if (std::error_code EC = BinOrErr.getError())
return EC;
- auto OF = std::move(ObjectFileOrErr.get());
+ auto Bin = std::move(BinOrErr.get());
+ std::unique_ptr<ObjectFile> OF;
+ if (auto *Universal = dyn_cast<object::MachOUniversalBinary>(Bin.get())) {
+ // If we have a universal binary, try to look up the object for the
+ // appropriate architecture.
+ auto ObjectFileOrErr = Universal->getObjectForArch(Arch);
+ if (std::error_code EC = ObjectFileOrErr.getError())
+ return EC;
+ OF = std::move(ObjectFileOrErr.get());
+ } else if (isa<object::ObjectFile>(Bin.get())) {
+ // For any other object file, upcast and take ownership.
+ OF.reset(cast<object::ObjectFile>(Bin.release()));
+ // If we've asked for a particular arch, make sure they match.
+ if (Arch != Triple::ArchType::UnknownArch && OF->getArch() != Arch)
+ return object_error::arch_not_found;
+ } else
+ // We can only handle object files.
+ return instrprof_error::malformed;
+
+ // The coverage uses native pointer sizes for the object it's written in.
BytesInAddress = OF->getBytesInAddress();
// Look for the sections that we are interested in.
@@ -479,7 +500,8 @@ static std::error_code loadBinaryFormat(MemoryBufferRef ObjectBuffer,
}
ErrorOr<std::unique_ptr<BinaryCoverageReader>>
-BinaryCoverageReader::create(std::unique_ptr<MemoryBuffer> &ObjectBuffer) {
+BinaryCoverageReader::create(std::unique_ptr<MemoryBuffer> &ObjectBuffer,
+ Triple::ArchType Arch) {
std::unique_ptr<BinaryCoverageReader> Reader(new BinaryCoverageReader());
SectionData Profile;
@@ -492,7 +514,7 @@ BinaryCoverageReader::create(std::unique_ptr<MemoryBuffer> &ObjectBuffer) {
BytesInAddress);
else
EC = loadBinaryFormat(ObjectBuffer->getMemBufferRef(), Profile, Coverage,
- BytesInAddress);
+ BytesInAddress, Arch);
if (EC)
return EC;
diff --git a/llvm/test/tools/llvm-cov/Inputs/universal-binary b/llvm/test/tools/llvm-cov/Inputs/universal-binary
new file mode 100755
index 00000000000..d566df95e4c
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/Inputs/universal-binary
Binary files differ
diff --git a/llvm/test/tools/llvm-cov/Inputs/universal-binary.proftext b/llvm/test/tools/llvm-cov/Inputs/universal-binary.proftext
new file mode 100644
index 00000000000..97816c29f36
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/Inputs/universal-binary.proftext
@@ -0,0 +1,4 @@
+main
+0x0
+1
+100
diff --git a/llvm/test/tools/llvm-cov/universal-binary.c b/llvm/test/tools/llvm-cov/universal-binary.c
new file mode 100644
index 00000000000..7fe2fe86243
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/universal-binary.c
@@ -0,0 +1,13 @@
+// The coverage reader should be able to handle universal binaries
+
+//CHECK: 100| @[[LINE+1]]| int main
+int main(int argc, const char *argv[]) {}
+
+// RUN: llvm-profdata merge %S/Inputs/universal-binary.proftext -o %t.profdata
+// RUN: llvm-cov show %S/Inputs/universal-binary -instr-profile %t.profdata -no-colors -filename-equivalence %s -arch x86_64 | FileCheck %s
+
+// RUN: not llvm-cov show %S/Inputs/universal-binary -instr-profile %t.profdata -no-colors -filename-equivalence %s -arch i386 2>&1 | FileCheck --check-prefix=WRONG-ARCH %s
+// WRONG-ARCH: Failed to load coverage
+
+// llvm-cov doesn't work on big endian yet
+// XFAIL: powerpc64-, s390x, mips-, mips64-, sparc
diff --git a/llvm/tools/llvm-cov/CodeCoverage.cpp b/llvm/tools/llvm-cov/CodeCoverage.cpp
index cf8ab337797..b4a05843311 100644
--- a/llvm/tools/llvm-cov/CodeCoverage.cpp
+++ b/llvm/tools/llvm-cov/CodeCoverage.cpp
@@ -20,6 +20,7 @@
#include "SourceCoverageView.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
#include "llvm/ProfileData/CoverageMapping.h"
#include "llvm/ProfileData/InstrProfReader.h"
#include "llvm/Support/CommandLine.h"
@@ -87,6 +88,7 @@ public:
LoadedSourceFiles;
bool CompareFilenamesOnly;
StringMap<std::string> RemappedFilenames;
+ llvm::Triple::ArchType CoverageArch;
};
}
@@ -193,7 +195,8 @@ CodeCoverageTool::createSourceFileView(StringRef SourceFile,
}
std::unique_ptr<CoverageMapping> CodeCoverageTool::load() {
- auto CoverageOrErr = CoverageMapping::load(ObjectFilename, PGOFilename);
+ auto CoverageOrErr = CoverageMapping::load(ObjectFilename, PGOFilename,
+ CoverageArch);
if (std::error_code EC = CoverageOrErr.getError()) {
colored_ostream(errs(), raw_ostream::RED)
<< "error: Failed to load coverage: " << EC.message();
@@ -242,6 +245,9 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
cl::desc(
"File with the profile data obtained after an instrumented run"));
+ cl::opt<std::string> Arch(
+ "arch", cl::desc("architecture of the coverage mapping binary"));
+
cl::opt<bool> DebugDump("dump", cl::Optional,
cl::desc("Show internal debug dump"));
@@ -322,6 +328,16 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
Filters.push_back(std::unique_ptr<CoverageFilter>(StatFilterer));
}
+ if (Arch.empty())
+ CoverageArch = llvm::Triple::ArchType::UnknownArch;
+ else {
+ CoverageArch = Triple(Arch).getArch();
+ if (CoverageArch == llvm::Triple::ArchType::UnknownArch) {
+ errs() << "error: Unknown architecture: " << Arch << "\n";
+ return 1;
+ }
+ }
+
for (const auto &File : InputSourceFiles) {
SmallString<128> Path(File);
if (!CompareFilenamesOnly)
OpenPOWER on IntegriCloud