1*e82d89ccSAlex Lorenz //===- TestingSupport.cpp - Convert objects files into test files --------===// 2*e82d89ccSAlex Lorenz // 3*e82d89ccSAlex Lorenz // The LLVM Compiler Infrastructure 4*e82d89ccSAlex Lorenz // 5*e82d89ccSAlex Lorenz // This file is distributed under the University of Illinois Open Source 6*e82d89ccSAlex Lorenz // License. See LICENSE.TXT for details. 7*e82d89ccSAlex Lorenz // 8*e82d89ccSAlex Lorenz //===----------------------------------------------------------------------===// 9*e82d89ccSAlex Lorenz 10*e82d89ccSAlex Lorenz #include "llvm/Object/ObjectFile.h" 11*e82d89ccSAlex Lorenz #include "llvm/Support/raw_ostream.h" 12*e82d89ccSAlex Lorenz #include "llvm/Support/LEB128.h" 13*e82d89ccSAlex Lorenz #include "llvm/Support/CommandLine.h" 14*e82d89ccSAlex Lorenz #include "llvm/Support/ManagedStatic.h" 15*e82d89ccSAlex Lorenz #include "llvm/Support/MemoryObject.h" 16*e82d89ccSAlex Lorenz #include "llvm/Support/Signals.h" 17*e82d89ccSAlex Lorenz #include "llvm/Support/PrettyStackTrace.h" 18*e82d89ccSAlex Lorenz #include <system_error> 19*e82d89ccSAlex Lorenz #include <functional> 20*e82d89ccSAlex Lorenz 21*e82d89ccSAlex Lorenz using namespace llvm; 22*e82d89ccSAlex Lorenz using namespace object; 23*e82d89ccSAlex Lorenz 24*e82d89ccSAlex Lorenz int convert_for_testing_main(int argc, const char **argv) { 25*e82d89ccSAlex Lorenz sys::PrintStackTraceOnErrorSignal(); 26*e82d89ccSAlex Lorenz PrettyStackTraceProgram X(argc, argv); 27*e82d89ccSAlex Lorenz llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 28*e82d89ccSAlex Lorenz 29*e82d89ccSAlex Lorenz cl::opt<std::string> InputSourceFile(cl::Positional, cl::Required, 30*e82d89ccSAlex Lorenz cl::desc("<Source file>")); 31*e82d89ccSAlex Lorenz 32*e82d89ccSAlex Lorenz cl::opt<std::string> OutputFilename( 33*e82d89ccSAlex Lorenz "o", cl::Required, 34*e82d89ccSAlex Lorenz cl::desc( 35*e82d89ccSAlex Lorenz "File with the profile data obtained after an instrumented run")); 36*e82d89ccSAlex Lorenz 37*e82d89ccSAlex Lorenz cl::ParseCommandLineOptions(argc, argv, "LLVM code coverage tool\n"); 38*e82d89ccSAlex Lorenz 39*e82d89ccSAlex Lorenz auto ObjErr = llvm::object::ObjectFile::createObjectFile(InputSourceFile); 40*e82d89ccSAlex Lorenz if (auto Err = ObjErr.getError()) { 41*e82d89ccSAlex Lorenz errs() << "error: " << Err.message() << "\n"; 42*e82d89ccSAlex Lorenz return 1; 43*e82d89ccSAlex Lorenz } 44*e82d89ccSAlex Lorenz ObjectFile *OF = ObjErr.get().getBinary().get(); 45*e82d89ccSAlex Lorenz auto BytesInAddress = OF->getBytesInAddress(); 46*e82d89ccSAlex Lorenz if (BytesInAddress != 8) { 47*e82d89ccSAlex Lorenz errs() << "error: 64 bit binary expected\n"; 48*e82d89ccSAlex Lorenz return 1; 49*e82d89ccSAlex Lorenz } 50*e82d89ccSAlex Lorenz 51*e82d89ccSAlex Lorenz // Look for the sections that we are interested in. 52*e82d89ccSAlex Lorenz int FoundSectionCount = 0; 53*e82d89ccSAlex Lorenz SectionRef ProfileNames, CoverageMapping; 54*e82d89ccSAlex Lorenz for (const auto &Section : OF->sections()) { 55*e82d89ccSAlex Lorenz StringRef Name; 56*e82d89ccSAlex Lorenz if (Section.getName(Name)) 57*e82d89ccSAlex Lorenz return 1; 58*e82d89ccSAlex Lorenz if (Name == "__llvm_prf_names") { 59*e82d89ccSAlex Lorenz ProfileNames = Section; 60*e82d89ccSAlex Lorenz } else if (Name == "__llvm_covmap") { 61*e82d89ccSAlex Lorenz CoverageMapping = Section; 62*e82d89ccSAlex Lorenz } else 63*e82d89ccSAlex Lorenz continue; 64*e82d89ccSAlex Lorenz ++FoundSectionCount; 65*e82d89ccSAlex Lorenz } 66*e82d89ccSAlex Lorenz if (FoundSectionCount != 2) 67*e82d89ccSAlex Lorenz return 1; 68*e82d89ccSAlex Lorenz 69*e82d89ccSAlex Lorenz // Get the contents of the given sections. 70*e82d89ccSAlex Lorenz StringRef CoverageMappingData; 71*e82d89ccSAlex Lorenz uint64_t ProfileNamesAddress; 72*e82d89ccSAlex Lorenz StringRef ProfileNamesData; 73*e82d89ccSAlex Lorenz if (CoverageMapping.getContents(CoverageMappingData) || 74*e82d89ccSAlex Lorenz ProfileNames.getAddress(ProfileNamesAddress) || 75*e82d89ccSAlex Lorenz ProfileNames.getContents(ProfileNamesData)) 76*e82d89ccSAlex Lorenz return 1; 77*e82d89ccSAlex Lorenz 78*e82d89ccSAlex Lorenz int FD; 79*e82d89ccSAlex Lorenz if (auto Err = 80*e82d89ccSAlex Lorenz sys::fs::openFileForWrite(OutputFilename, FD, sys::fs::F_None)) { 81*e82d89ccSAlex Lorenz errs() << "error: " << Err.message() << "\n"; 82*e82d89ccSAlex Lorenz return 1; 83*e82d89ccSAlex Lorenz } 84*e82d89ccSAlex Lorenz 85*e82d89ccSAlex Lorenz raw_fd_ostream OS(FD, true); 86*e82d89ccSAlex Lorenz OS << "llvmcovmtestdata"; 87*e82d89ccSAlex Lorenz encodeULEB128(ProfileNamesData.size(), OS); 88*e82d89ccSAlex Lorenz encodeULEB128(ProfileNamesAddress, OS); 89*e82d89ccSAlex Lorenz OS << ProfileNamesData << CoverageMappingData; 90*e82d89ccSAlex Lorenz 91*e82d89ccSAlex Lorenz return 0; 92*e82d89ccSAlex Lorenz } 93