Skip to content

Commit

Permalink
[Binary] Support extracting offloading files from COFF
Browse files Browse the repository at this point in the history
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
  • Loading branch information
jhuber6 committed Nov 3, 2022
1 parent 3384f05 commit 8298f0b
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 18 deletions.
26 changes: 21 additions & 5 deletions llvm/lib/Object/OffloadBinary.cpp
Expand Up @@ -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"
Expand Down Expand Up @@ -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<OffloadFile> &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<ELFSectionRef>(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<StringRef> NameOrErr = Sec.getName();
if (!NameOrErr)
return NameOrErr.takeError();

if (!NameOrErr->equals(".llvm.offloading"))
continue;
}

Expected<StringRef> Buffer = Sec.getContents();
if (!Buffer)
return Buffer.takeError();
Expand Down Expand Up @@ -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<std::unique_ptr<ObjectFile>> 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<std::unique_ptr<llvm::object::Archive>> LibFile =
Expand Down
42 changes: 42 additions & 0 deletions 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 <none>
# CHECK-NEXT:arch sm_70
# CHECK-NEXT:triple nvptx64-nvidia-cuda
# CHECK-NEXT:producer none
20 changes: 10 additions & 10 deletions 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
7 changes: 4 additions & 3 deletions llvm/tools/llvm-objdump/OffloadDump.cpp
Expand Up @@ -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;
}

Expand Down

0 comments on commit 8298f0b

Please sign in to comment.