xref: /aosp_15_r20/external/llvm/tools/llvm-cov/TestingSupport.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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