mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 04:32:44 +01:00
f7f1e6f3b0
This is a version of D32090 that unifies all of the `getInstrProf*SectionName` helper functions. (Note: the build failures which D32090 would have addressed were fixed with r300352.) We should unify these helper functions because they are hard to use in their current form. E.g we recently introduced more helpers to fix section naming for COFF files. This scheme doesn't totally succeed at hiding low-level details about section naming, so we should switch to an API that is easier to maintain. This is not an NFC commit because it fixes llvm-cov's testing support for COFF files (this falls out of the API change naturally). This is an area where we lack tests -- I will see about adding one as a follow up. Testing: check-clang, check-profile, check-llvm. Differential Revision: https://reviews.llvm.org/D32097 llvm-svn: 300381
96 lines
3.0 KiB
C++
96 lines
3.0 KiB
C++
//===- TestingSupport.cpp - Convert objects files into test files --------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/Object/ObjectFile.h"
|
|
#include "llvm/ProfileData/InstrProf.h"
|
|
#include "llvm/Support/CommandLine.h"
|
|
#include "llvm/Support/LEB128.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
#include <functional>
|
|
#include <system_error>
|
|
|
|
using namespace llvm;
|
|
using namespace object;
|
|
|
|
int convertForTestingMain(int argc, const char *argv[]) {
|
|
cl::opt<std::string> InputSourceFile(cl::Positional, cl::Required,
|
|
cl::desc("<Source file>"));
|
|
|
|
cl::opt<std::string> OutputFilename(
|
|
"o", cl::Required,
|
|
cl::desc(
|
|
"File with the profile data obtained after an instrumented run"));
|
|
|
|
cl::ParseCommandLineOptions(argc, argv, "LLVM code coverage tool\n");
|
|
|
|
auto ObjErr = llvm::object::ObjectFile::createObjectFile(InputSourceFile);
|
|
if (!ObjErr) {
|
|
std::string Buf;
|
|
raw_string_ostream OS(Buf);
|
|
logAllUnhandledErrors(ObjErr.takeError(), OS, "");
|
|
OS.flush();
|
|
errs() << "error: " << Buf;
|
|
return 1;
|
|
}
|
|
ObjectFile *OF = ObjErr.get().getBinary();
|
|
auto BytesInAddress = OF->getBytesInAddress();
|
|
if (BytesInAddress != 8) {
|
|
errs() << "error: 64 bit binary expected\n";
|
|
return 1;
|
|
}
|
|
|
|
// Look for the sections that we are interested in.
|
|
int FoundSectionCount = 0;
|
|
SectionRef ProfileNames, CoverageMapping;
|
|
auto ObjFormat = OF->getTripleObjectFormat();
|
|
for (const auto &Section : OF->sections()) {
|
|
StringRef Name;
|
|
if (Section.getName(Name))
|
|
return 1;
|
|
if (Name == llvm::getInstrProfSectionName(IPSK_name, ObjFormat,
|
|
/*AddSegmentInfo=*/false)) {
|
|
ProfileNames = Section;
|
|
} else if (Name == llvm::getInstrProfSectionName(
|
|
IPSK_covmap, ObjFormat, /*AddSegmentInfo=*/false)) {
|
|
CoverageMapping = Section;
|
|
} else
|
|
continue;
|
|
++FoundSectionCount;
|
|
}
|
|
if (FoundSectionCount != 2)
|
|
return 1;
|
|
|
|
// Get the contents of the given sections.
|
|
uint64_t ProfileNamesAddress = ProfileNames.getAddress();
|
|
StringRef CoverageMappingData;
|
|
StringRef ProfileNamesData;
|
|
if (CoverageMapping.getContents(CoverageMappingData) ||
|
|
ProfileNames.getContents(ProfileNamesData))
|
|
return 1;
|
|
|
|
int FD;
|
|
if (auto Err =
|
|
sys::fs::openFileForWrite(OutputFilename, FD, sys::fs::F_None)) {
|
|
errs() << "error: " << Err.message() << "\n";
|
|
return 1;
|
|
}
|
|
|
|
raw_fd_ostream OS(FD, true);
|
|
OS << "llvmcovmtestdata";
|
|
encodeULEB128(ProfileNamesData.size(), OS);
|
|
encodeULEB128(ProfileNamesAddress, OS);
|
|
OS << ProfileNamesData;
|
|
// Coverage mapping data is expected to have an alignment of 8.
|
|
for (unsigned Pad = OffsetToAlignment(OS.tell(), 8); Pad; --Pad)
|
|
OS.write(uint8_t(0));
|
|
OS << CoverageMappingData;
|
|
|
|
return 0;
|
|
}
|