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/Support/raw_ostream.h" 12 #include "llvm/Support/LEB128.h" 13 #include "llvm/Support/CommandLine.h" 14 #include "llvm/Support/ManagedStatic.h" 15 #include "llvm/Support/MemoryObject.h" 16 #include "llvm/Support/Signals.h" 17 #include "llvm/Support/PrettyStackTrace.h" 18 #include <system_error> 19 #include <functional> 20 21 using namespace llvm; 22 using namespace object; 23 24 int convert_for_testing_main(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 (auto Err = ObjErr.getError()) { 41 errs() << "error: " << Err.message() << "\n"; 42 return 1; 43 } 44 ObjectFile *OF = ObjErr.get().getBinary().get(); 45 auto BytesInAddress = OF->getBytesInAddress(); 46 if (BytesInAddress != 8) { 47 errs() << "error: 64 bit binary expected\n"; 48 return 1; 49 } 50 51 // Look for the sections that we are interested in. 52 int FoundSectionCount = 0; 53 SectionRef ProfileNames, CoverageMapping; 54 for (const auto &Section : OF->sections()) { 55 StringRef Name; 56 if (Section.getName(Name)) 57 return 1; 58 if (Name == "__llvm_prf_names") { 59 ProfileNames = Section; 60 } else if (Name == "__llvm_covmap") { 61 CoverageMapping = Section; 62 } else 63 continue; 64 ++FoundSectionCount; 65 } 66 if (FoundSectionCount != 2) 67 return 1; 68 69 // Get the contents of the given sections. 70 StringRef CoverageMappingData; 71 uint64_t ProfileNamesAddress; 72 StringRef ProfileNamesData; 73 if (CoverageMapping.getContents(CoverageMappingData) || 74 ProfileNames.getAddress(ProfileNamesAddress) || 75 ProfileNames.getContents(ProfileNamesData)) 76 return 1; 77 78 int FD; 79 if (auto Err = 80 sys::fs::openFileForWrite(OutputFilename, FD, sys::fs::F_None)) { 81 errs() << "error: " << Err.message() << "\n"; 82 return 1; 83 } 84 85 raw_fd_ostream OS(FD, true); 86 OS << "llvmcovmtestdata"; 87 encodeULEB128(ProfileNamesData.size(), OS); 88 encodeULEB128(ProfileNamesAddress, OS); 89 OS << ProfileNamesData << CoverageMappingData; 90 91 return 0; 92 } 93