1e82d89ccSAlex Lorenz //===- TestingSupport.cpp - Convert objects files into test files --------===// 2e82d89ccSAlex Lorenz // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6e82d89ccSAlex Lorenz // 7e82d89ccSAlex Lorenz //===----------------------------------------------------------------------===// 8e82d89ccSAlex Lorenz 9e82d89ccSAlex Lorenz #include "llvm/Object/ObjectFile.h" 105c3ff137SVedant Kumar #include "llvm/ProfileData/InstrProf.h" 11e82d89ccSAlex Lorenz #include "llvm/Support/CommandLine.h" 12d9903888SChandler Carruth #include "llvm/Support/LEB128.h" 13d9903888SChandler Carruth #include "llvm/Support/raw_ostream.h" 14e82d89ccSAlex Lorenz #include <functional> 15d9903888SChandler Carruth #include <system_error> 16e82d89ccSAlex Lorenz 17e82d89ccSAlex Lorenz using namespace llvm; 18e82d89ccSAlex Lorenz using namespace object; 19e82d89ccSAlex Lorenz 20d249a3b3SJustin Bogner int convertForTestingMain(int argc, const char *argv[]) { 21e82d89ccSAlex Lorenz cl::opt<std::string> InputSourceFile(cl::Positional, cl::Required, 22e82d89ccSAlex Lorenz cl::desc("<Source file>")); 23e82d89ccSAlex Lorenz 24e82d89ccSAlex Lorenz cl::opt<std::string> OutputFilename( 25e82d89ccSAlex Lorenz "o", cl::Required, 26e82d89ccSAlex Lorenz cl::desc( 27e82d89ccSAlex Lorenz "File with the profile data obtained after an instrumented run")); 28e82d89ccSAlex Lorenz 29e82d89ccSAlex Lorenz cl::ParseCommandLineOptions(argc, argv, "LLVM code coverage tool\n"); 30e82d89ccSAlex Lorenz 31e82d89ccSAlex Lorenz auto ObjErr = llvm::object::ObjectFile::createObjectFile(InputSourceFile); 323fcdf6aeSKevin Enderby if (!ObjErr) { 333fcdf6aeSKevin Enderby std::string Buf; 343fcdf6aeSKevin Enderby raw_string_ostream OS(Buf); 3545eb84f3SJonas Devlieghere logAllUnhandledErrors(ObjErr.takeError(), OS); 363fcdf6aeSKevin Enderby OS.flush(); 373fcdf6aeSKevin Enderby errs() << "error: " << Buf; 38e82d89ccSAlex Lorenz return 1; 39e82d89ccSAlex Lorenz } 40f04de6ecSLang Hames ObjectFile *OF = ObjErr.get().getBinary(); 41e82d89ccSAlex Lorenz auto BytesInAddress = OF->getBytesInAddress(); 42e82d89ccSAlex Lorenz if (BytesInAddress != 8) { 43e82d89ccSAlex Lorenz errs() << "error: 64 bit binary expected\n"; 44e82d89ccSAlex Lorenz return 1; 45e82d89ccSAlex Lorenz } 46e82d89ccSAlex Lorenz 47e82d89ccSAlex Lorenz // Look for the sections that we are interested in. 48e82d89ccSAlex Lorenz int FoundSectionCount = 0; 49e82d89ccSAlex Lorenz SectionRef ProfileNames, CoverageMapping; 501a6a2b64SVedant Kumar auto ObjFormat = OF->getTripleObjectFormat(); 51e82d89ccSAlex Lorenz for (const auto &Section : OF->sections()) { 52e82d89ccSAlex Lorenz StringRef Name; 53e82d89ccSAlex Lorenz if (Section.getName(Name)) 54e82d89ccSAlex Lorenz return 1; 551a6a2b64SVedant Kumar if (Name == llvm::getInstrProfSectionName(IPSK_name, ObjFormat, 561a6a2b64SVedant Kumar /*AddSegmentInfo=*/false)) { 57e82d89ccSAlex Lorenz ProfileNames = Section; 581a6a2b64SVedant Kumar } else if (Name == llvm::getInstrProfSectionName( 591a6a2b64SVedant Kumar IPSK_covmap, ObjFormat, /*AddSegmentInfo=*/false)) { 60e82d89ccSAlex Lorenz CoverageMapping = Section; 61e82d89ccSAlex Lorenz } else 62e82d89ccSAlex Lorenz continue; 63e82d89ccSAlex Lorenz ++FoundSectionCount; 64e82d89ccSAlex Lorenz } 65e82d89ccSAlex Lorenz if (FoundSectionCount != 2) 66e82d89ccSAlex Lorenz return 1; 67e82d89ccSAlex Lorenz 68e82d89ccSAlex Lorenz // Get the contents of the given sections. 6980291274SRafael Espindola uint64_t ProfileNamesAddress = ProfileNames.getAddress(); 70e82d89ccSAlex Lorenz StringRef CoverageMappingData; 71e82d89ccSAlex Lorenz StringRef ProfileNamesData; 72*e183340cSFangrui Song if (Expected<StringRef> E = CoverageMapping.getContents()) 73*e183340cSFangrui Song CoverageMappingData = *E; 74*e183340cSFangrui Song else { 75*e183340cSFangrui Song consumeError(E.takeError()); 76e82d89ccSAlex Lorenz return 1; 77*e183340cSFangrui Song } 78*e183340cSFangrui Song if (Expected<StringRef> E = ProfileNames.getContents()) 79*e183340cSFangrui Song ProfileNamesData = *E; 80*e183340cSFangrui Song else { 81*e183340cSFangrui Song consumeError(E.takeError()); 82*e183340cSFangrui Song return 1; 83*e183340cSFangrui Song } 84e82d89ccSAlex Lorenz 85e82d89ccSAlex Lorenz int FD; 861f67a3cbSZachary Turner if (auto Err = sys::fs::openFileForWrite(OutputFilename, FD)) { 87e82d89ccSAlex Lorenz errs() << "error: " << Err.message() << "\n"; 88e82d89ccSAlex Lorenz return 1; 89e82d89ccSAlex Lorenz } 90e82d89ccSAlex Lorenz 91e82d89ccSAlex Lorenz raw_fd_ostream OS(FD, true); 92e82d89ccSAlex Lorenz OS << "llvmcovmtestdata"; 93e82d89ccSAlex Lorenz encodeULEB128(ProfileNamesData.size(), OS); 94e82d89ccSAlex Lorenz encodeULEB128(ProfileNamesAddress, OS); 95eb103073SIgor Kudrin OS << ProfileNamesData; 96eb103073SIgor Kudrin // Coverage mapping data is expected to have an alignment of 8. 97eb103073SIgor Kudrin for (unsigned Pad = OffsetToAlignment(OS.tell(), 8); Pad; --Pad) 98eb103073SIgor Kudrin OS.write(uint8_t(0)); 99eb103073SIgor Kudrin OS << CoverageMappingData; 100e82d89ccSAlex Lorenz 101e82d89ccSAlex Lorenz return 0; 102e82d89ccSAlex Lorenz } 103