1 //===-- OffloadDump.cpp - Offloading dumper ---------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// 9 /// \file 10 /// This file implements the offloading-specific dumper for llvm-objdump. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "OffloadDump.h" 15 #include "llvm-objdump.h" 16 #include "llvm/Object/ELFObjectFile.h" 17 #include "llvm/Object/OffloadBinary.h" 18 #include "llvm/Object/OffloadBundle.h" 19 20 using namespace llvm; 21 using namespace llvm::object; 22 using namespace llvm::objdump; 23 24 void disassembleObject(llvm::object::ObjectFile *, bool InlineRelocs); 25 26 /// Get the printable name of the image kind. 27 static StringRef getImageName(const OffloadBinary &OB) { 28 switch (OB.getImageKind()) { 29 case IMG_Object: 30 return "elf"; 31 case IMG_Bitcode: 32 return "llvm ir"; 33 case IMG_Cubin: 34 return "cubin"; 35 case IMG_Fatbinary: 36 return "fatbinary"; 37 case IMG_PTX: 38 return "ptx"; 39 default: 40 return "<none>"; 41 } 42 } 43 44 static void printBinary(const OffloadBinary &OB, uint64_t Index) { 45 outs() << "\nOFFLOADING IMAGE [" << Index << "]:\n"; 46 outs() << left_justify("kind", 16) << getImageName(OB) << "\n"; 47 outs() << left_justify("arch", 16) << OB.getArch() << "\n"; 48 outs() << left_justify("triple", 16) << OB.getTriple() << "\n"; 49 outs() << left_justify("producer", 16) 50 << getOffloadKindName(OB.getOffloadKind()) << "\n"; 51 } 52 53 /// Print the embedded offloading contents of an ObjectFile \p O. 54 void llvm::dumpOffloadBinary(const ObjectFile &O, StringRef ArchName) { 55 if (!O.isELF() && !O.isCOFF()) { 56 reportWarning( 57 "--offloading is currently only supported for COFF and ELF targets", 58 O.getFileName()); 59 return; 60 } 61 62 SmallVector<OffloadFile> Binaries; 63 if (Error Err = extractOffloadBinaries(O.getMemoryBufferRef(), Binaries)) 64 reportError(O.getFileName(), "while extracting offloading files: " + 65 toString(std::move(Err))); 66 67 // Print out all the binaries that are contained in this buffer. 68 for (uint64_t I = 0, E = Binaries.size(); I != E; ++I) 69 printBinary(*Binaries[I].getBinary(), I); 70 71 dumpOffloadBundleFatBinary(O, ArchName); 72 } 73 74 // Given an Object file, collect all Bundles of FatBin Binaries 75 // and dump them into Code Object files 76 // if -arch=-name is specified, only dump the Entries that match the target arch 77 void llvm::dumpOffloadBundleFatBinary(const ObjectFile &O, StringRef ArchName) { 78 if (!O.isELF() && !O.isCOFF()) { 79 reportWarning( 80 "--offloading is currently only supported for COFF and ELF targets", 81 O.getFileName()); 82 return; 83 } 84 85 SmallVector<llvm::object::OffloadBundleFatBin> FoundBundles; 86 87 if (Error Err = llvm::object::extractOffloadBundleFatBinary(O, FoundBundles)) 88 reportError(O.getFileName(), "while extracting offload FatBin bundles: " + 89 toString(std::move(Err))); 90 91 for (const auto &[BundleNum, Bundle] : llvm::enumerate(FoundBundles)) { 92 for (OffloadBundleEntry &Entry : Bundle.getEntries()) { 93 if (!ArchName.empty() && !Entry.ID.contains(ArchName)) 94 continue; 95 96 // create file name for this object file: <source-filename>.<Bundle 97 // Number>.<EntryID> 98 std::string str = Bundle.getFileName().str() + "." + itostr(BundleNum) + 99 "." + Entry.ID.str(); 100 if (Error Err = object::extractCodeObject(O, Entry.Offset, Entry.Size, 101 StringRef(str))) 102 reportError(O.getFileName(), 103 "while extracting offload Bundle Entries: " + 104 toString(std::move(Err))); 105 outs() << "Extracting offload bundle: " << str << "\n"; 106 } 107 } 108 } 109 110 /// Print the contents of an offload binary file \p OB. This may contain 111 /// multiple binaries stored in the same buffer. 112 void llvm::dumpOffloadSections(const OffloadBinary &OB) { 113 SmallVector<OffloadFile> Binaries; 114 if (Error Err = extractOffloadBinaries(OB.getMemoryBufferRef(), Binaries)) 115 reportError(OB.getFileName(), "while extracting offloading files: " + 116 toString(std::move(Err))); 117 118 // Print out all the binaries that are contained in this buffer. 119 for (uint64_t I = 0, E = Binaries.size(); I != E; ++I) 120 printBinary(*Binaries[I].getBinary(), I); 121 } 122