xref: /freebsd/contrib/llvm-project/llvm/tools/llvm-objdump/OffloadDump.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
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.
getImageName(const OffloadBinary & OB)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 
printBinary(const OffloadBinary & OB,uint64_t Index)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.
dumpOffloadBinary(const ObjectFile & O,StringRef ArchName)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
dumpOffloadBundleFatBinary(const ObjectFile & O,StringRef ArchName)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.
dumpOffloadSections(const OffloadBinary & OB)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