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" 12d9903888SChandler Carruth #include "llvm/Support/LEB128.h" 13e82d89ccSAlex Lorenz #include "llvm/Support/ManagedStatic.h" 14e82d89ccSAlex Lorenz #include "llvm/Support/PrettyStackTrace.h" 15d9903888SChandler Carruth #include "llvm/Support/Signals.h" 16d9903888SChandler Carruth #include "llvm/Support/raw_ostream.h" 17e82d89ccSAlex Lorenz #include <functional> 18d9903888SChandler 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); 393fcdf6aeSKevin Enderby if (!ObjErr) { 403fcdf6aeSKevin Enderby std::string Buf; 413fcdf6aeSKevin Enderby raw_string_ostream OS(Buf); 423fcdf6aeSKevin Enderby logAllUnhandledErrors(ObjErr.takeError(), OS, ""); 433fcdf6aeSKevin Enderby OS.flush(); 443fcdf6aeSKevin Enderby errs() << "error: " << Buf; 45e82d89ccSAlex Lorenz return 1; 46e82d89ccSAlex Lorenz } 47f04de6ecSLang Hames ObjectFile *OF = ObjErr.get().getBinary(); 48e82d89ccSAlex Lorenz auto BytesInAddress = OF->getBytesInAddress(); 49e82d89ccSAlex Lorenz if (BytesInAddress != 8) { 50e82d89ccSAlex Lorenz errs() << "error: 64 bit binary expected\n"; 51e82d89ccSAlex Lorenz return 1; 52e82d89ccSAlex Lorenz } 53e82d89ccSAlex Lorenz 54e82d89ccSAlex Lorenz // Look for the sections that we are interested in. 55e82d89ccSAlex Lorenz int FoundSectionCount = 0; 56e82d89ccSAlex Lorenz SectionRef ProfileNames, CoverageMapping; 57e82d89ccSAlex Lorenz for (const auto &Section : OF->sections()) { 58e82d89ccSAlex Lorenz StringRef Name; 59e82d89ccSAlex Lorenz if (Section.getName(Name)) 60e82d89ccSAlex Lorenz return 1; 61e82d89ccSAlex Lorenz if (Name == "__llvm_prf_names") { 62e82d89ccSAlex Lorenz ProfileNames = Section; 63e82d89ccSAlex Lorenz } else if (Name == "__llvm_covmap") { 64e82d89ccSAlex Lorenz CoverageMapping = Section; 65e82d89ccSAlex Lorenz } else 66e82d89ccSAlex Lorenz continue; 67e82d89ccSAlex Lorenz ++FoundSectionCount; 68e82d89ccSAlex Lorenz } 69e82d89ccSAlex Lorenz if (FoundSectionCount != 2) 70e82d89ccSAlex Lorenz return 1; 71e82d89ccSAlex Lorenz 72e82d89ccSAlex Lorenz // Get the contents of the given sections. 7380291274SRafael Espindola uint64_t ProfileNamesAddress = ProfileNames.getAddress(); 74e82d89ccSAlex Lorenz StringRef CoverageMappingData; 75e82d89ccSAlex Lorenz StringRef ProfileNamesData; 76e82d89ccSAlex Lorenz if (CoverageMapping.getContents(CoverageMappingData) || 77e82d89ccSAlex Lorenz ProfileNames.getContents(ProfileNamesData)) 78e82d89ccSAlex Lorenz return 1; 79e82d89ccSAlex Lorenz 80e82d89ccSAlex Lorenz int FD; 81e82d89ccSAlex Lorenz if (auto Err = 82e82d89ccSAlex Lorenz sys::fs::openFileForWrite(OutputFilename, FD, sys::fs::F_None)) { 83e82d89ccSAlex Lorenz errs() << "error: " << Err.message() << "\n"; 84e82d89ccSAlex Lorenz return 1; 85e82d89ccSAlex Lorenz } 86e82d89ccSAlex Lorenz 87e82d89ccSAlex Lorenz raw_fd_ostream OS(FD, true); 88e82d89ccSAlex Lorenz OS << "llvmcovmtestdata"; 89e82d89ccSAlex Lorenz encodeULEB128(ProfileNamesData.size(), OS); 90e82d89ccSAlex Lorenz encodeULEB128(ProfileNamesAddress, OS); 91*eb103073SIgor Kudrin OS << ProfileNamesData; 92*eb103073SIgor Kudrin // Coverage mapping data is expected to have an alignment of 8. 93*eb103073SIgor Kudrin for (unsigned Pad = OffsetToAlignment(OS.tell(), 8); Pad; --Pad) 94*eb103073SIgor Kudrin OS.write(uint8_t(0)); 95*eb103073SIgor Kudrin OS << CoverageMappingData; 96e82d89ccSAlex Lorenz 97e82d89ccSAlex Lorenz return 0; 98e82d89ccSAlex Lorenz } 99