113 lines
4.0 KiB
C++
113 lines
4.0 KiB
C++
//===-- 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/Support/Alignment.h"
|
|
|
|
using namespace llvm;
|
|
using namespace llvm::object;
|
|
using namespace llvm::objdump;
|
|
|
|
/// 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";
|
|
}
|
|
|
|
static Error visitAllBinaries(const OffloadBinary &OB) {
|
|
uint64_t Offset = 0;
|
|
uint64_t Index = 0;
|
|
while (Offset < OB.getMemoryBufferRef().getBufferSize()) {
|
|
MemoryBufferRef Buffer =
|
|
MemoryBufferRef(OB.getData().drop_front(Offset), OB.getFileName());
|
|
auto BinaryOrErr = OffloadBinary::create(Buffer);
|
|
if (!BinaryOrErr)
|
|
return BinaryOrErr.takeError();
|
|
|
|
OffloadBinary &Binary = **BinaryOrErr;
|
|
printBinary(Binary, Index++);
|
|
|
|
Offset += Binary.getSize();
|
|
}
|
|
return Error::success();
|
|
}
|
|
|
|
/// Print the embedded offloading contents of an ObjectFile \p O.
|
|
void llvm::dumpOffloadBinary(const ObjectFile &O) {
|
|
if (!O.isELF()) {
|
|
reportWarning("--offloading is currently only supported for ELF targets",
|
|
O.getFileName());
|
|
return;
|
|
}
|
|
|
|
for (ELFSectionRef Sec : O.sections()) {
|
|
if (Sec.getType() != ELF::SHT_LLVM_OFFLOADING)
|
|
continue;
|
|
|
|
Expected<StringRef> Contents = Sec.getContents();
|
|
if (!Contents)
|
|
reportError(Contents.takeError(), O.getFileName());
|
|
|
|
std::unique_ptr<MemoryBuffer> Buffer =
|
|
MemoryBuffer::getMemBuffer(*Contents, O.getFileName(), false);
|
|
if (!isAddrAligned(Align(OffloadBinary::getAlignment()),
|
|
Buffer->getBufferStart()))
|
|
Buffer = MemoryBuffer::getMemBufferCopy(Buffer->getBuffer(),
|
|
Buffer->getBufferIdentifier());
|
|
auto BinaryOrErr = OffloadBinary::create(*Buffer);
|
|
if (!BinaryOrErr)
|
|
reportError(O.getFileName(), "while extracting offloading files: " +
|
|
toString(BinaryOrErr.takeError()));
|
|
OffloadBinary &Binary = **BinaryOrErr;
|
|
|
|
// Print out all the binaries that are contained in this buffer. If we fail
|
|
// to parse a binary before reaching the end of the buffer emit a warning.
|
|
if (Error Err = visitAllBinaries(Binary))
|
|
reportWarning("while parsing offloading files: " +
|
|
toString(std::move(Err)),
|
|
O.getFileName());
|
|
}
|
|
}
|
|
|
|
/// 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) {
|
|
// Print out all the binaries that are contained at this buffer. If we fail to
|
|
// parse a binary before reaching the end of the buffer emit a warning.
|
|
if (Error Err = visitAllBinaries(OB))
|
|
reportWarning("while parsing offloading files: " + toString(std::move(Err)),
|
|
OB.getFileName());
|
|
}
|