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