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