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