blob: 8353442a7e4480227840c1f9c301a2bec2a93e45 [file] [log] [blame]
Alex Lorenze82d89c2014-08-22 22:56:03 +00001//===- 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"
Vedant Kumar5c3ff132016-06-02 17:00:50 +000011#include "llvm/ProfileData/InstrProf.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"
Alex Lorenze82d89c2014-08-22 22:56:03 +000014#include "llvm/Support/ManagedStatic.h"
Alex Lorenze82d89c2014-08-22 22:56:03 +000015#include "llvm/Support/PrettyStackTrace.h"
Chandler Carruthd9903882015-01-14 11:23:27 +000016#include "llvm/Support/Signals.h"
17#include "llvm/Support/raw_ostream.h"
Alex Lorenze82d89c2014-08-22 22:56:03 +000018#include <functional>
Chandler Carruthd9903882015-01-14 11:23:27 +000019#include <system_error>
Alex Lorenze82d89c2014-08-22 22:56:03 +000020
21using namespace llvm;
22using namespace object;
23
Justin Bognerd249a3b2014-10-30 20:57:49 +000024int convertForTestingMain(int argc, const char *argv[]) {
Alex Lorenze82d89c2014-08-22 22:56:03 +000025 sys::PrintStackTraceOnErrorSignal();
26 PrettyStackTraceProgram X(argc, argv);
27 llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
28
29 cl::opt<std::string> InputSourceFile(cl::Positional, cl::Required,
30 cl::desc("<Source file>"));
31
32 cl::opt<std::string> OutputFilename(
33 "o", cl::Required,
34 cl::desc(
35 "File with the profile data obtained after an instrumented run"));
36
37 cl::ParseCommandLineOptions(argc, argv, "LLVM code coverage tool\n");
38
39 auto ObjErr = llvm::object::ObjectFile::createObjectFile(InputSourceFile);
Kevin Enderby3fcdf6a2016-04-06 22:14:09 +000040 if (!ObjErr) {
41 std::string Buf;
42 raw_string_ostream OS(Buf);
43 logAllUnhandledErrors(ObjErr.takeError(), OS, "");
44 OS.flush();
45 errs() << "error: " << Buf;
Alex Lorenze82d89c2014-08-22 22:56:03 +000046 return 1;
47 }
Lang Hamesf04de6e2014-10-31 21:37:49 +000048 ObjectFile *OF = ObjErr.get().getBinary();
Alex Lorenze82d89c2014-08-22 22:56:03 +000049 auto BytesInAddress = OF->getBytesInAddress();
50 if (BytesInAddress != 8) {
51 errs() << "error: 64 bit binary expected\n";
52 return 1;
53 }
54
55 // Look for the sections that we are interested in.
56 int FoundSectionCount = 0;
57 SectionRef ProfileNames, CoverageMapping;
58 for (const auto &Section : OF->sections()) {
59 StringRef Name;
60 if (Section.getName(Name))
61 return 1;
Vedant Kumar5c3ff132016-06-02 17:00:50 +000062 if (Name == llvm::getInstrProfNameSectionName(false)) {
Alex Lorenze82d89c2014-08-22 22:56:03 +000063 ProfileNames = Section;
Vedant Kumar5c3ff132016-06-02 17:00:50 +000064 } else if (Name == llvm::getInstrProfCoverageSectionName(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;
77 if (CoverageMapping.getContents(CoverageMappingData) ||
Alex Lorenze82d89c2014-08-22 22:56:03 +000078 ProfileNames.getContents(ProfileNamesData))
79 return 1;
80
81 int FD;
82 if (auto Err =
83 sys::fs::openFileForWrite(OutputFilename, FD, sys::fs::F_None)) {
84 errs() << "error: " << Err.message() << "\n";
85 return 1;
86 }
87
88 raw_fd_ostream OS(FD, true);
89 OS << "llvmcovmtestdata";
90 encodeULEB128(ProfileNamesData.size(), OS);
91 encodeULEB128(ProfileNamesAddress, OS);
Igor Kudrineb103072016-05-18 07:43:27 +000092 OS << ProfileNamesData;
93 // Coverage mapping data is expected to have an alignment of 8.
94 for (unsigned Pad = OffsetToAlignment(OS.tell(), 8); Pad; --Pad)
95 OS.write(uint8_t(0));
96 OS << CoverageMappingData;
Alex Lorenze82d89c2014-08-22 22:56:03 +000097
98 return 0;
99}