xref: /llvm-project/llvm/tools/llvm-objdump/OffloadDump.cpp (revision 82a0adf0f78d5be8a727d9537627e2a6f7e8e105)
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 #include "OffloadDump.h"
14 #include "llvm-objdump.h"
15 #include "llvm/Object/ELFObjectFile.h"
16 
17 using namespace llvm;
18 using namespace llvm::object;
19 using namespace llvm::objdump;
20 
21 /// Get the printable name of the image kind.
22 static StringRef getImageName(const OffloadBinary &OB) {
23   switch (OB.getImageKind()) {
24   case IMG_Object:
25     return "elf";
26   case IMG_Bitcode:
27     return "llvm ir";
28   case IMG_Cubin:
29     return "cubin";
30   case IMG_Fatbinary:
31     return "fatbinary";
32   case IMG_PTX:
33     return "ptx";
34   default:
35     return "<none>";
36   }
37 }
38 
39 static void printBinary(const OffloadBinary &OB, uint64_t Index) {
40   outs() << "\nOFFLOADING IMAGE [" << Index << "]:\n";
41   outs() << left_justify("kind", 16) << getImageName(OB) << "\n";
42   outs() << left_justify("arch", 16) << OB.getArch() << "\n";
43   outs() << left_justify("triple", 16) << OB.getTriple() << "\n";
44   outs() << left_justify("producer", 16)
45          << getOffloadKindName(OB.getOffloadKind()) << "\n";
46 }
47 
48 static Error visitAllBinaries(const OffloadBinary &OB) {
49   uint64_t Offset = 0;
50   uint64_t Index = 0;
51   while (Offset < OB.getMemoryBufferRef().getBufferSize()) {
52     MemoryBufferRef Buffer =
53         MemoryBufferRef(OB.getData().drop_front(Offset), OB.getFileName());
54     auto BinaryOrErr = OffloadBinary::create(Buffer);
55     if (!BinaryOrErr)
56       return BinaryOrErr.takeError();
57 
58     OffloadBinary &Binary = **BinaryOrErr;
59     printBinary(Binary, Index++);
60 
61     Offset += Binary.getSize();
62   }
63   return Error::success();
64 }
65 
66 /// Print the embedded offloading contents of an ObjectFile \p O.
67 void llvm::dumpOffloadBinary(const ObjectFile &O) {
68   if (!O.isELF()) {
69     reportWarning("--offloading is currently only supported for ELF targets",
70                   O.getFileName());
71     return;
72   }
73 
74   for (ELFSectionRef Sec : O.sections()) {
75     if (Sec.getType() != ELF::SHT_LLVM_OFFLOADING)
76       continue;
77 
78     Expected<StringRef> Contents = Sec.getContents();
79     if (!Contents)
80       reportError(Contents.takeError(), O.getFileName());
81 
82     MemoryBufferRef Buffer = MemoryBufferRef(*Contents, O.getFileName());
83     auto BinaryOrErr = OffloadBinary::create(Buffer);
84     if (!BinaryOrErr)
85       reportError(O.getFileName(), "while extracting offloading files: " +
86                                        toString(BinaryOrErr.takeError()));
87     OffloadBinary &Binary = **BinaryOrErr;
88 
89     // Print out all the binaries that are contained in this buffer. If we fail
90     // to parse a binary before reaching the end of the buffer emit a warning.
91     if (Error Err = visitAllBinaries(Binary))
92       reportWarning("while parsing offloading files: " +
93                         toString(std::move(Err)),
94                     O.getFileName());
95   }
96 }
97 
98 /// Print the contents of an offload binary file \p OB. This may contain
99 /// multiple binaries stored in the same buffer.
100 void llvm::dumpOffloadSections(const OffloadBinary &OB) {
101   // Print out all the binaries that are contained at this buffer. If we fail to
102   // parse a binary before reaching the end of the buffer emit a warning.
103   if (Error Err = visitAllBinaries(OB))
104     reportWarning("while parsing offloading files: " + toString(std::move(Err)),
105                   OB.getFileName());
106 }
107