blob: 39f809a8f0d672d1839ae3569e87053397ba1159 [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"
Guillaume Chateletaf11cc72019-09-12 15:20:36 +000011#include "llvm/Support/Alignment.h"
Alex Lorenze82d89c2014-08-22 22:56:03 +000012#include "llvm/Support/CommandLine.h"
Chandler Carruthd9903882015-01-14 11:23:27 +000013#include "llvm/Support/LEB128.h"
Chandler Carruthd9903882015-01-14 11:23:27 +000014#include "llvm/Support/raw_ostream.h"
Alex Lorenze82d89c2014-08-22 22:56:03 +000015#include <functional>
Chandler Carruthd9903882015-01-14 11:23:27 +000016#include <system_error>
Alex Lorenze82d89c2014-08-22 22:56:03 +000017
18using namespace llvm;
19using namespace object;
20
Justin Bognerd249a3b2014-10-30 20:57:49 +000021int convertForTestingMain(int argc, const char *argv[]) {
Alex Lorenze82d89c2014-08-22 22:56:03 +000022 cl::opt<std::string> InputSourceFile(cl::Positional, cl::Required,
23 cl::desc("<Source file>"));
24
25 cl::opt<std::string> OutputFilename(
26 "o", cl::Required,
27 cl::desc(
28 "File with the profile data obtained after an instrumented run"));
29
30 cl::ParseCommandLineOptions(argc, argv, "LLVM code coverage tool\n");
31
32 auto ObjErr = llvm::object::ObjectFile::createObjectFile(InputSourceFile);
Kevin Enderby3fcdf6a2016-04-06 22:14:09 +000033 if (!ObjErr) {
34 std::string Buf;
35 raw_string_ostream OS(Buf);
Jonas Devlieghere45eb84f2018-11-11 01:46:03 +000036 logAllUnhandledErrors(ObjErr.takeError(), OS);
Kevin Enderby3fcdf6a2016-04-06 22:14:09 +000037 OS.flush();
38 errs() << "error: " << Buf;
Alex Lorenze82d89c2014-08-22 22:56:03 +000039 return 1;
40 }
Lang Hamesf04de6e2014-10-31 21:37:49 +000041 ObjectFile *OF = ObjErr.get().getBinary();
Alex Lorenze82d89c2014-08-22 22:56:03 +000042 auto BytesInAddress = OF->getBytesInAddress();
43 if (BytesInAddress != 8) {
44 errs() << "error: 64 bit binary expected\n";
45 return 1;
46 }
47
48 // Look for the sections that we are interested in.
49 int FoundSectionCount = 0;
50 SectionRef ProfileNames, CoverageMapping;
Vedant Kumar1a6a2b62017-04-15 00:09:57 +000051 auto ObjFormat = OF->getTripleObjectFormat();
Alex Lorenze82d89c2014-08-22 22:56:03 +000052 for (const auto &Section : OF->sections()) {
53 StringRef Name;
George Rimarbcc00e12019-08-14 11:10:11 +000054 if (Expected<StringRef> NameOrErr = Section.getName()) {
55 Name = *NameOrErr;
56 } else {
57 consumeError(NameOrErr.takeError());
Alex Lorenze82d89c2014-08-22 22:56:03 +000058 return 1;
George Rimarbcc00e12019-08-14 11:10:11 +000059 }
60
Vedant Kumar1a6a2b62017-04-15 00:09:57 +000061 if (Name == llvm::getInstrProfSectionName(IPSK_name, ObjFormat,
62 /*AddSegmentInfo=*/false)) {
Alex Lorenze82d89c2014-08-22 22:56:03 +000063 ProfileNames = Section;
Vedant Kumar1a6a2b62017-04-15 00:09:57 +000064 } else if (Name == llvm::getInstrProfSectionName(
65 IPSK_covmap, ObjFormat, /*AddSegmentInfo=*/false)) {
Alex Lorenze82d89c2014-08-22 22:56:03 +000066 CoverageMapping = Section;
67 } else
68 continue;
69 ++FoundSectionCount;
70 }
71 if (FoundSectionCount != 2)
72 return 1;
73
74 // Get the contents of the given sections.
Rafael Espindola80291272014-10-08 15:28:58 +000075 uint64_t ProfileNamesAddress = ProfileNames.getAddress();
Alex Lorenze82d89c2014-08-22 22:56:03 +000076 StringRef CoverageMappingData;
Alex Lorenze82d89c2014-08-22 22:56:03 +000077 StringRef ProfileNamesData;
Fangrui Songe1833402019-05-16 13:24:04 +000078 if (Expected<StringRef> E = CoverageMapping.getContents())
79 CoverageMappingData = *E;
80 else {
81 consumeError(E.takeError());
Alex Lorenze82d89c2014-08-22 22:56:03 +000082 return 1;
Fangrui Songe1833402019-05-16 13:24:04 +000083 }
84 if (Expected<StringRef> E = ProfileNames.getContents())
85 ProfileNamesData = *E;
86 else {
87 consumeError(E.takeError());
88 return 1;
89 }
Alex Lorenze82d89c2014-08-22 22:56:03 +000090
91 int FD;
Zachary Turner1f67a3c2018-06-07 19:58:58 +000092 if (auto Err = sys::fs::openFileForWrite(OutputFilename, FD)) {
Alex Lorenze82d89c2014-08-22 22:56:03 +000093 errs() << "error: " << Err.message() << "\n";
94 return 1;
95 }
96
97 raw_fd_ostream OS(FD, true);
98 OS << "llvmcovmtestdata";
99 encodeULEB128(ProfileNamesData.size(), OS);
100 encodeULEB128(ProfileNamesAddress, OS);
Igor Kudrineb103072016-05-18 07:43:27 +0000101 OS << ProfileNamesData;
102 // Coverage mapping data is expected to have an alignment of 8.
Guillaume Chateletaf11cc72019-09-12 15:20:36 +0000103 for (unsigned Pad = offsetToAlignment(OS.tell(), llvm::Align(8)); Pad; --Pad)
Igor Kudrineb103072016-05-18 07:43:27 +0000104 OS.write(uint8_t(0));
105 OS << CoverageMappingData;
Alex Lorenze82d89c2014-08-22 22:56:03 +0000106
107 return 0;
108}