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