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