From 8298f0b7b92e5e2ff8d547cd93863f094d13cb06 Mon Sep 17 00:00:00 2001 From: Joseph Huber Date: Thu, 27 Oct 2022 16:13:22 +0000 Subject: [PATCH] [Binary] Support extracting offloading files from COFF This patch adds initial support for extracting offloading binaries from `COFF` objects. This is a first step to allow building offloading files on Windows targets with the new driver. Depends on D136796 Reviewed By: rnk Differential Revision: https://reviews.llvm.org/D136855 --- llvm/lib/Object/OffloadBinary.cpp | 26 +++++++++--- .../tools/llvm-objdump/Offloading/coff.test | 42 +++++++++++++++++++ .../llvm-objdump/Offloading/non-elf.test | 20 ++++----- llvm/tools/llvm-objdump/OffloadDump.cpp | 7 ++-- 4 files changed, 77 insertions(+), 18 deletions(-) create mode 100644 llvm/test/tools/llvm-objdump/Offloading/coff.test diff --git a/llvm/lib/Object/OffloadBinary.cpp b/llvm/lib/Object/OffloadBinary.cpp index 3f7a60d89c27d..d8cdcdc21d39c 100644 --- 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 @@ Error extractOffloadFiles(MemoryBufferRef Contents, } // 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 @@ Error object::extractOffloadBinaries(MemoryBufferRef Buffer, 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 index 0000000000000..022277d137bd4 --- /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 index 955556f0567b5..a2eb377bb35d1 100644 --- 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 index fdef373279b39..4ac6b99e79bbb 100644 --- a/llvm/tools/llvm-objdump/OffloadDump.cpp +++ b/llvm/tools/llvm-objdump/OffloadDump.cpp @@ -49,9 +49,10 @@ static void printBinary(const OffloadBinary &OB, uint64_t Index) { /// 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; }