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