1*9880d681SAndroid Build Coastguard Worker //===- TestingSupport.cpp - Convert objects files into test files --------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker
10*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/ObjectFile.h"
11*9880d681SAndroid Build Coastguard Worker #include "llvm/ProfileData/InstrProf.h"
12*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h"
13*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/LEB128.h"
14*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
15*9880d681SAndroid Build Coastguard Worker #include <functional>
16*9880d681SAndroid Build Coastguard Worker #include <system_error>
17*9880d681SAndroid Build Coastguard Worker
18*9880d681SAndroid Build Coastguard Worker using namespace llvm;
19*9880d681SAndroid Build Coastguard Worker using namespace object;
20*9880d681SAndroid Build Coastguard Worker
convertForTestingMain(int argc,const char * argv[])21*9880d681SAndroid Build Coastguard Worker int convertForTestingMain(int argc, const char *argv[]) {
22*9880d681SAndroid Build Coastguard Worker cl::opt<std::string> InputSourceFile(cl::Positional, cl::Required,
23*9880d681SAndroid Build Coastguard Worker cl::desc("<Source file>"));
24*9880d681SAndroid Build Coastguard Worker
25*9880d681SAndroid Build Coastguard Worker cl::opt<std::string> OutputFilename(
26*9880d681SAndroid Build Coastguard Worker "o", cl::Required,
27*9880d681SAndroid Build Coastguard Worker cl::desc(
28*9880d681SAndroid Build Coastguard Worker "File with the profile data obtained after an instrumented run"));
29*9880d681SAndroid Build Coastguard Worker
30*9880d681SAndroid Build Coastguard Worker cl::ParseCommandLineOptions(argc, argv, "LLVM code coverage tool\n");
31*9880d681SAndroid Build Coastguard Worker
32*9880d681SAndroid Build Coastguard Worker auto ObjErr = llvm::object::ObjectFile::createObjectFile(InputSourceFile);
33*9880d681SAndroid Build Coastguard Worker if (!ObjErr) {
34*9880d681SAndroid Build Coastguard Worker std::string Buf;
35*9880d681SAndroid Build Coastguard Worker raw_string_ostream OS(Buf);
36*9880d681SAndroid Build Coastguard Worker logAllUnhandledErrors(ObjErr.takeError(), OS, "");
37*9880d681SAndroid Build Coastguard Worker OS.flush();
38*9880d681SAndroid Build Coastguard Worker errs() << "error: " << Buf;
39*9880d681SAndroid Build Coastguard Worker return 1;
40*9880d681SAndroid Build Coastguard Worker }
41*9880d681SAndroid Build Coastguard Worker ObjectFile *OF = ObjErr.get().getBinary();
42*9880d681SAndroid Build Coastguard Worker auto BytesInAddress = OF->getBytesInAddress();
43*9880d681SAndroid Build Coastguard Worker if (BytesInAddress != 8) {
44*9880d681SAndroid Build Coastguard Worker errs() << "error: 64 bit binary expected\n";
45*9880d681SAndroid Build Coastguard Worker return 1;
46*9880d681SAndroid Build Coastguard Worker }
47*9880d681SAndroid Build Coastguard Worker
48*9880d681SAndroid Build Coastguard Worker // Look for the sections that we are interested in.
49*9880d681SAndroid Build Coastguard Worker int FoundSectionCount = 0;
50*9880d681SAndroid Build Coastguard Worker SectionRef ProfileNames, CoverageMapping;
51*9880d681SAndroid Build Coastguard Worker for (const auto &Section : OF->sections()) {
52*9880d681SAndroid Build Coastguard Worker StringRef Name;
53*9880d681SAndroid Build Coastguard Worker if (Section.getName(Name))
54*9880d681SAndroid Build Coastguard Worker return 1;
55*9880d681SAndroid Build Coastguard Worker if (Name == llvm::getInstrProfNameSectionName(false)) {
56*9880d681SAndroid Build Coastguard Worker ProfileNames = Section;
57*9880d681SAndroid Build Coastguard Worker } else if (Name == llvm::getInstrProfCoverageSectionName(false)) {
58*9880d681SAndroid Build Coastguard Worker CoverageMapping = Section;
59*9880d681SAndroid Build Coastguard Worker } else
60*9880d681SAndroid Build Coastguard Worker continue;
61*9880d681SAndroid Build Coastguard Worker ++FoundSectionCount;
62*9880d681SAndroid Build Coastguard Worker }
63*9880d681SAndroid Build Coastguard Worker if (FoundSectionCount != 2)
64*9880d681SAndroid Build Coastguard Worker return 1;
65*9880d681SAndroid Build Coastguard Worker
66*9880d681SAndroid Build Coastguard Worker // Get the contents of the given sections.
67*9880d681SAndroid Build Coastguard Worker uint64_t ProfileNamesAddress = ProfileNames.getAddress();
68*9880d681SAndroid Build Coastguard Worker StringRef CoverageMappingData;
69*9880d681SAndroid Build Coastguard Worker StringRef ProfileNamesData;
70*9880d681SAndroid Build Coastguard Worker if (CoverageMapping.getContents(CoverageMappingData) ||
71*9880d681SAndroid Build Coastguard Worker ProfileNames.getContents(ProfileNamesData))
72*9880d681SAndroid Build Coastguard Worker return 1;
73*9880d681SAndroid Build Coastguard Worker
74*9880d681SAndroid Build Coastguard Worker int FD;
75*9880d681SAndroid Build Coastguard Worker if (auto Err =
76*9880d681SAndroid Build Coastguard Worker sys::fs::openFileForWrite(OutputFilename, FD, sys::fs::F_None)) {
77*9880d681SAndroid Build Coastguard Worker errs() << "error: " << Err.message() << "\n";
78*9880d681SAndroid Build Coastguard Worker return 1;
79*9880d681SAndroid Build Coastguard Worker }
80*9880d681SAndroid Build Coastguard Worker
81*9880d681SAndroid Build Coastguard Worker raw_fd_ostream OS(FD, true);
82*9880d681SAndroid Build Coastguard Worker OS << "llvmcovmtestdata";
83*9880d681SAndroid Build Coastguard Worker encodeULEB128(ProfileNamesData.size(), OS);
84*9880d681SAndroid Build Coastguard Worker encodeULEB128(ProfileNamesAddress, OS);
85*9880d681SAndroid Build Coastguard Worker OS << ProfileNamesData;
86*9880d681SAndroid Build Coastguard Worker // Coverage mapping data is expected to have an alignment of 8.
87*9880d681SAndroid Build Coastguard Worker for (unsigned Pad = OffsetToAlignment(OS.tell(), 8); Pad; --Pad)
88*9880d681SAndroid Build Coastguard Worker OS.write(uint8_t(0));
89*9880d681SAndroid Build Coastguard Worker OS << CoverageMappingData;
90*9880d681SAndroid Build Coastguard Worker
91*9880d681SAndroid Build Coastguard Worker return 0;
92*9880d681SAndroid Build Coastguard Worker }
93