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