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" 115c3ff137SVedant Kumar #include "llvm/ProfileData/InstrProf.h" 12e82d89ccSAlex Lorenz #include "llvm/Support/CommandLine.h" 13d9903888SChandler Carruth #include "llvm/Support/LEB128.h" 14d9903888SChandler Carruth #include "llvm/Support/raw_ostream.h" 15e82d89ccSAlex Lorenz #include <functional> 16d9903888SChandler Carruth #include <system_error> 17e82d89ccSAlex Lorenz 18e82d89ccSAlex Lorenz using namespace llvm; 19e82d89ccSAlex Lorenz using namespace object; 20e82d89ccSAlex Lorenz 21d249a3b3SJustin Bogner int convertForTestingMain(int argc, const char *argv[]) { 22e82d89ccSAlex Lorenz cl::opt<std::string> InputSourceFile(cl::Positional, cl::Required, 23e82d89ccSAlex Lorenz cl::desc("<Source file>")); 24e82d89ccSAlex Lorenz 25e82d89ccSAlex Lorenz cl::opt<std::string> OutputFilename( 26e82d89ccSAlex Lorenz "o", cl::Required, 27e82d89ccSAlex Lorenz cl::desc( 28e82d89ccSAlex Lorenz "File with the profile data obtained after an instrumented run")); 29e82d89ccSAlex Lorenz 30e82d89ccSAlex Lorenz cl::ParseCommandLineOptions(argc, argv, "LLVM code coverage tool\n"); 31e82d89ccSAlex Lorenz 32e82d89ccSAlex Lorenz auto ObjErr = llvm::object::ObjectFile::createObjectFile(InputSourceFile); 333fcdf6aeSKevin Enderby if (!ObjErr) { 343fcdf6aeSKevin Enderby std::string Buf; 353fcdf6aeSKevin Enderby raw_string_ostream OS(Buf); 363fcdf6aeSKevin Enderby logAllUnhandledErrors(ObjErr.takeError(), OS, ""); 373fcdf6aeSKevin Enderby OS.flush(); 383fcdf6aeSKevin Enderby errs() << "error: " << Buf; 39e82d89ccSAlex Lorenz return 1; 40e82d89ccSAlex Lorenz } 41f04de6ecSLang Hames ObjectFile *OF = ObjErr.get().getBinary(); 42e82d89ccSAlex Lorenz auto BytesInAddress = OF->getBytesInAddress(); 43e82d89ccSAlex Lorenz if (BytesInAddress != 8) { 44e82d89ccSAlex Lorenz errs() << "error: 64 bit binary expected\n"; 45e82d89ccSAlex Lorenz return 1; 46e82d89ccSAlex Lorenz } 47e82d89ccSAlex Lorenz 48e82d89ccSAlex Lorenz // Look for the sections that we are interested in. 49e82d89ccSAlex Lorenz int FoundSectionCount = 0; 50e82d89ccSAlex Lorenz SectionRef ProfileNames, CoverageMapping; 51*1a6a2b64SVedant Kumar auto ObjFormat = OF->getTripleObjectFormat(); 52e82d89ccSAlex Lorenz for (const auto &Section : OF->sections()) { 53e82d89ccSAlex Lorenz StringRef Name; 54e82d89ccSAlex Lorenz if (Section.getName(Name)) 55e82d89ccSAlex Lorenz return 1; 56*1a6a2b64SVedant Kumar if (Name == llvm::getInstrProfSectionName(IPSK_name, ObjFormat, 57*1a6a2b64SVedant Kumar /*AddSegmentInfo=*/false)) { 58e82d89ccSAlex Lorenz ProfileNames = Section; 59*1a6a2b64SVedant Kumar } else if (Name == llvm::getInstrProfSectionName( 60*1a6a2b64SVedant Kumar IPSK_covmap, ObjFormat, /*AddSegmentInfo=*/false)) { 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); 88eb103073SIgor Kudrin OS << ProfileNamesData; 89eb103073SIgor Kudrin // Coverage mapping data is expected to have an alignment of 8. 90eb103073SIgor Kudrin for (unsigned Pad = OffsetToAlignment(OS.tell(), 8); Pad; --Pad) 91eb103073SIgor Kudrin OS.write(uint8_t(0)); 92eb103073SIgor Kudrin OS << CoverageMappingData; 93e82d89ccSAlex Lorenz 94e82d89ccSAlex Lorenz return 0; 95e82d89ccSAlex Lorenz } 96