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