blob: 39bdade127477685decec9db3037e008c668485a [file] [log] [blame]
Alex Lorenze82d89c2014-08-22 22:56:03 +00001//===- TestingSupport.cpp - Convert objects files into test files --------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Alex Lorenze82d89c2014-08-22 22:56:03 +00006//
7//===----------------------------------------------------------------------===//
8
9#include "llvm/Object/ObjectFile.h"
Vedant Kumar5c3ff132016-06-02 17:00:50 +000010#include "llvm/ProfileData/InstrProf.h"
Alex Lorenze82d89c2014-08-22 22:56:03 +000011#include "llvm/Support/CommandLine.h"
Chandler Carruthd9903882015-01-14 11:23:27 +000012#include "llvm/Support/LEB128.h"
Chandler Carruthd9903882015-01-14 11:23:27 +000013#include "llvm/Support/raw_ostream.h"
Alex Lorenze82d89c2014-08-22 22:56:03 +000014#include <functional>
Chandler Carruthd9903882015-01-14 11:23:27 +000015#include <system_error>
Alex Lorenze82d89c2014-08-22 22:56:03 +000016
17using namespace llvm;
18using namespace object;
19
Justin Bognerd249a3b2014-10-30 20:57:49 +000020int convertForTestingMain(int argc, const char *argv[]) {
Alex Lorenze82d89c2014-08-22 22:56:03 +000021 cl::opt<std::string> InputSourceFile(cl::Positional, cl::Required,
22 cl::desc("<Source file>"));
23
24 cl::opt<std::string> OutputFilename(
25 "o", cl::Required,
26 cl::desc(
27 "File with the profile data obtained after an instrumented run"));
28
29 cl::ParseCommandLineOptions(argc, argv, "LLVM code coverage tool\n");
30
31 auto ObjErr = llvm::object::ObjectFile::createObjectFile(InputSourceFile);
Kevin Enderby3fcdf6a2016-04-06 22:14:09 +000032 if (!ObjErr) {
33 std::string Buf;
34 raw_string_ostream OS(Buf);
Jonas Devlieghere45eb84f2018-11-11 01:46:03 +000035 logAllUnhandledErrors(ObjErr.takeError(), OS);
Kevin Enderby3fcdf6a2016-04-06 22:14:09 +000036 OS.flush();
37 errs() << "error: " << Buf;
Alex Lorenze82d89c2014-08-22 22:56:03 +000038 return 1;
39 }
Lang Hamesf04de6e2014-10-31 21:37:49 +000040 ObjectFile *OF = ObjErr.get().getBinary();
Alex Lorenze82d89c2014-08-22 22:56:03 +000041 auto BytesInAddress = OF->getBytesInAddress();
42 if (BytesInAddress != 8) {
43 errs() << "error: 64 bit binary expected\n";
44 return 1;
45 }
46
47 // Look for the sections that we are interested in.
48 int FoundSectionCount = 0;
49 SectionRef ProfileNames, CoverageMapping;
Vedant Kumar1a6a2b62017-04-15 00:09:57 +000050 auto ObjFormat = OF->getTripleObjectFormat();
Alex Lorenze82d89c2014-08-22 22:56:03 +000051 for (const auto &Section : OF->sections()) {
52 StringRef Name;
George Rimarbcc00e12019-08-14 11:10:11 +000053 if (Expected<StringRef> NameOrErr = Section.getName()) {
54 Name = *NameOrErr;
55 } else {
56 consumeError(NameOrErr.takeError());
Alex Lorenze82d89c2014-08-22 22:56:03 +000057 return 1;
George Rimarbcc00e12019-08-14 11:10:11 +000058 }
59
Vedant Kumar1a6a2b62017-04-15 00:09:57 +000060 if (Name == llvm::getInstrProfSectionName(IPSK_name, ObjFormat,
61 /*AddSegmentInfo=*/false)) {
Alex Lorenze82d89c2014-08-22 22:56:03 +000062 ProfileNames = Section;
Vedant Kumar1a6a2b62017-04-15 00:09:57 +000063 } else if (Name == llvm::getInstrProfSectionName(
64 IPSK_covmap, ObjFormat, /*AddSegmentInfo=*/false)) {
Alex Lorenze82d89c2014-08-22 22:56:03 +000065 CoverageMapping = Section;
66 } else
67 continue;
68 ++FoundSectionCount;
69 }
70 if (FoundSectionCount != 2)
71 return 1;
72
73 // Get the contents of the given sections.
Rafael Espindola80291272014-10-08 15:28:58 +000074 uint64_t ProfileNamesAddress = ProfileNames.getAddress();
Alex Lorenze82d89c2014-08-22 22:56:03 +000075 StringRef CoverageMappingData;
Alex Lorenze82d89c2014-08-22 22:56:03 +000076 StringRef ProfileNamesData;
Fangrui Songe1833402019-05-16 13:24:04 +000077 if (Expected<StringRef> E = CoverageMapping.getContents())
78 CoverageMappingData = *E;
79 else {
80 consumeError(E.takeError());
Alex Lorenze82d89c2014-08-22 22:56:03 +000081 return 1;
Fangrui Songe1833402019-05-16 13:24:04 +000082 }
83 if (Expected<StringRef> E = ProfileNames.getContents())
84 ProfileNamesData = *E;
85 else {
86 consumeError(E.takeError());
87 return 1;
88 }
Alex Lorenze82d89c2014-08-22 22:56:03 +000089
90 int FD;
Zachary Turner1f67a3c2018-06-07 19:58:58 +000091 if (auto Err = sys::fs::openFileForWrite(OutputFilename, FD)) {
Alex Lorenze82d89c2014-08-22 22:56:03 +000092 errs() << "error: " << Err.message() << "\n";
93 return 1;
94 }
95
96 raw_fd_ostream OS(FD, true);
97 OS << "llvmcovmtestdata";
98 encodeULEB128(ProfileNamesData.size(), OS);
99 encodeULEB128(ProfileNamesAddress, OS);
Igor Kudrineb103072016-05-18 07:43:27 +0000100 OS << ProfileNamesData;
101 // Coverage mapping data is expected to have an alignment of 8.
102 for (unsigned Pad = OffsetToAlignment(OS.tell(), 8); Pad; --Pad)
103 OS.write(uint8_t(0));
104 OS << CoverageMappingData;
Alex Lorenze82d89c2014-08-22 22:56:03 +0000105
106 return 0;
107}