mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-28 06:00:28 +00:00
InstrProf: Teach llvm-cov to handle universal binaries when given -arch
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@231902 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e6e0135d1a
commit
d39109de09
@ -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.
|
||||
///
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
|
||||
|
BIN
test/tools/llvm-cov/Inputs/universal-binary
Executable file
BIN
test/tools/llvm-cov/Inputs/universal-binary
Executable file
Binary file not shown.
4
test/tools/llvm-cov/Inputs/universal-binary.proftext
Normal file
4
test/tools/llvm-cov/Inputs/universal-binary.proftext
Normal file
@ -0,0 +1,4 @@
|
||||
main
|
||||
0x0
|
||||
1
|
||||
100
|
13
test/tools/llvm-cov/universal-binary.c
Normal file
13
test/tools/llvm-cov/universal-binary.c
Normal file
@ -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
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user