diff --git a/llvm/lib/Object/OffloadBinary.cpp b/llvm/lib/Object/OffloadBinary.cpp --- a/llvm/lib/Object/OffloadBinary.cpp +++ b/llvm/lib/Object/OffloadBinary.cpp @@ -17,6 +17,7 @@ #include "llvm/Object/Archive.h" #include "llvm/Object/ArchiveWriter.h" #include "llvm/Object/Binary.h" +#include "llvm/Object/COFF.h" #include "llvm/Object/ELFObjectFile.h" #include "llvm/Object/Error.h" #include "llvm/Object/IRObjectFile.h" @@ -66,12 +67,26 @@ } // Extract offloading binaries from an Object file \p Obj. -Error extractFromBinary(const ObjectFile &Obj, +Error extractFromObject(const ObjectFile &Obj, SmallVectorImpl &Binaries) { - for (ELFSectionRef Sec : Obj.sections()) { - if (Sec.getType() != ELF::SHT_LLVM_OFFLOADING) + assert((Obj.isELF() || Obj.isCOFF()) && "Invalid file type"); + + for (SectionRef Sec : Obj.sections()) { + // ELF files contain a section with the LLVM_OFFLOADING type. + if (Obj.isELF() && + static_cast(Sec).getType() != ELF::SHT_LLVM_OFFLOADING) continue; + // COFF has no section types so we rely on the name of the section. + if (Obj.isCOFF()) { + Expected NameOrErr = Sec.getName(); + if (!NameOrErr) + return NameOrErr.takeError(); + + if (!NameOrErr->equals(".llvm.offloading")) + continue; + } + Expected Buffer = Sec.getContents(); if (!Buffer) return Buffer.takeError(); @@ -260,12 +275,13 @@ return extractFromBitcode(Buffer, Binaries); case file_magic::elf_relocatable: case file_magic::elf_executable: - case file_magic::elf_shared_object: { + case file_magic::elf_shared_object: + case file_magic::coff_object: { Expected> ObjFile = ObjectFile::createObjectFile(Buffer, Type); if (!ObjFile) return ObjFile.takeError(); - return extractFromBinary(*ObjFile->get(), Binaries); + return extractFromObject(*ObjFile->get(), Binaries); } case file_magic::archive: { Expected> LibFile = diff --git a/llvm/test/tools/llvm-objdump/Offloading/coff.test b/llvm/test/tools/llvm-objdump/Offloading/coff.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-objdump/Offloading/coff.test @@ -0,0 +1,42 @@ +# RUN: yaml2obj %S/Inputs/binary.yaml -o %t.bin +# RUN: yaml2obj %s -o %t.coff +# RUN: llvm-objcopy --add-section .llvm.offloading=%t.bin %t.coff +# RUN: llvm-objdump --offloading %t.coff | FileCheck %s --match-full-lines --strict-whitespace --implicit-check-not={{.}} + +--- !COFF +header: + Machine: IMAGE_FILE_MACHINE_AMD64 + Characteristics: [] +sections: + - Name: .rdata + Characteristics: [] + - Name: .llvm.offloading + Characteristics: [ IMAGE_SCN_LNK_REMOVE, IMAGE_SCN_MEM_DISCARDABLE ] + Alignment: 8 +symbols: + +# CHECK:{{.*}}file format coff-x86-64 +# CHECK-EMPTY: +# CHECK-NEXT:OFFLOADING IMAGE [0]: +# CHECK-NEXT:kind llvm ir +# CHECK-NEXT:arch gfx908 +# CHECK-NEXT:triple amdgcn-amd-amdhsa +# CHECK-NEXT:producer openmp +# CHECK-EMPTY: +# CHECK-NEXT:OFFLOADING IMAGE [1]: +# CHECK-NEXT:kind llvm ir +# CHECK-NEXT:arch gfx90a +# CHECK-NEXT:triple amdgcn-amd-amdhsa +# CHECK-NEXT:producer openmp +# CHECK-EMPTY: +# CHECK-NEXT:OFFLOADING IMAGE [2]: +# CHECK-NEXT:kind cubin +# CHECK-NEXT:arch sm_52 +# CHECK-NEXT:triple nvptx64-nvidia-cuda +# CHECK-NEXT:producer openmp +# CHECK-EMPTY: +# CHECK-NEXT:OFFLOADING IMAGE [3]: +# CHECK-NEXT:kind +# CHECK-NEXT:arch sm_70 +# CHECK-NEXT:triple nvptx64-nvidia-cuda +# CHECK-NEXT:producer none diff --git a/llvm/test/tools/llvm-objdump/Offloading/non-elf.test b/llvm/test/tools/llvm-objdump/Offloading/non-elf.test --- a/llvm/test/tools/llvm-objdump/Offloading/non-elf.test +++ b/llvm/test/tools/llvm-objdump/Offloading/non-elf.test @@ -1,14 +1,14 @@ # RUN: yaml2obj %s -o %t # RUN: llvm-objdump --offloading %t 2>&1 | FileCheck -DFILENAME=%t %s ---- !COFF -header: - Machine: IMAGE_FILE_MACHINE_AMD64 - Characteristics: [] -sections: - - Name: .rdata - Characteristics: [] - SectionData: 00 -symbols: +--- !mach-o +FileHeader: + magic: 0xFEEDFACE + cputype: 0x00000007 + cpusubtype: 0x00000003 + filetype: 0x00000001 + ncmds: 0 + sizeofcmds: 0 + flags: 0x00002000 -# CHECK: warning: '[[FILENAME]]': --offloading is currently only supported for ELF targets +# CHECK: warning: '[[FILENAME]]': --offloading is currently only supported for COFF and ELF targets diff --git a/llvm/tools/llvm-objdump/OffloadDump.cpp b/llvm/tools/llvm-objdump/OffloadDump.cpp --- a/llvm/tools/llvm-objdump/OffloadDump.cpp +++ b/llvm/tools/llvm-objdump/OffloadDump.cpp @@ -49,9 +49,10 @@ /// 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()); + if (!O.isELF() && !O.isCOFF()) { + reportWarning( + "--offloading is currently only supported for COFF and ELF targets", + O.getFileName()); return; }