diff --git a/clang/test/Driver/offload-packager.c b/clang/test/Driver/offload-packager.c --- a/clang/test/Driver/offload-packager.c +++ b/clang/test/Driver/offload-packager.c @@ -29,3 +29,25 @@ // RUN: diff *-amdgcn-amd-amdhsa-gfx908.2.o %S/Inputs/dummy-elf.o; rm *-amdgcn-amd-amdhsa-gfx908.2.o // RUN: diff *-amdgcn-amd-amdhsa-gfx90a.3.o %S/Inputs/dummy-elf.o; rm *-amdgcn-amd-amdhsa-gfx90a.3.o // RUN: not diff *-amdgcn-amd-amdhsa-gfx90c.4.o %S/Inputs/dummy-elf.o + +// Check that we can extract from an ELF object file +// RUN: clang-offload-packager -o %t.out \ +// RUN: --image=file=%S/Inputs/dummy-elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908 \ +// RUN: --image=file=%S/Inputs/dummy-elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70 +// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o -fembed-offload-object=%t.out +// RUN: clang-offload-packager %t.out \ +// RUN: --image=file=%t-sm_70.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70 \ +// RUN: --image=file=%t-gfx908.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908 +// RUN: diff %t-sm_70.o %S/Inputs/dummy-elf.o +// RUN: diff %t-gfx908.o %S/Inputs/dummy-elf.o + +// Check that we can extract from a bitcode file +// RUN: clang-offload-packager -o %t.out \ +// RUN: --image=file=%S/Inputs/dummy-elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908 \ +// RUN: --image=file=%S/Inputs/dummy-elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70 +// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-llvm -o %t.bc -fembed-offload-object=%t.out +// RUN: clang-offload-packager %t.out \ +// RUN: --image=file=%t-sm_70.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70 \ +// RUN: --image=file=%t-gfx908.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908 +// RUN: diff %t-sm_70.o %S/Inputs/dummy-elf.o +// RUN: diff %t-gfx908.o %S/Inputs/dummy-elf.o diff --git a/clang/tools/clang-offload-packager/ClangOffloadPackager.cpp b/clang/tools/clang-offload-packager/ClangOffloadPackager.cpp --- a/clang/tools/clang-offload-packager/ClangOffloadPackager.cpp +++ b/clang/tools/clang-offload-packager/ClangOffloadPackager.cpp @@ -14,8 +14,7 @@ #include "clang/Basic/Version.h" -#include "llvm/Object/Binary.h" -#include "llvm/Object/ObjectFile.h" +#include "llvm/BinaryFormat/Magic.h" #include "llvm/Object/OffloadBinary.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileOutputBuffer.h" @@ -123,29 +122,6 @@ return Error::success(); } -static Expected>> -extractOffloadFiles(MemoryBufferRef Contents) { - if (identify_magic(Contents.getBuffer()) != file_magic::offload_binary) - return createStringError(inconvertibleErrorCode(), - "Input buffer not an offloading binary"); - SmallVector> Binaries; - uint64_t Offset = 0; - // There could be multiple offloading binaries stored at this section. - while (Offset < Contents.getBuffer().size()) { - std::unique_ptr Buffer = - MemoryBuffer::getMemBuffer(Contents.getBuffer().drop_front(Offset), "", - /*RequiresNullTerminator*/ false); - auto BinaryOrErr = OffloadBinary::create(*Buffer); - if (!BinaryOrErr) - return BinaryOrErr.takeError(); - - Offset += (*BinaryOrErr)->getSize(); - Binaries.emplace_back(std::move(*BinaryOrErr)); - } - - return std::move(Binaries); -} - static Error unbundleImages() { ErrorOr> BufferOrErr = MemoryBuffer::getFileOrSTDIN(InputFile); @@ -159,9 +135,9 @@ Buffer = MemoryBuffer::getMemBufferCopy(Buffer->getBuffer(), Buffer->getBufferIdentifier()); - auto BinariesOrErr = extractOffloadFiles(*Buffer); - if (!BinariesOrErr) - return BinariesOrErr.takeError(); + SmallVector Binaries; + if (Error Err = extractOffloadBinaries(*Buffer, Binaries)) + return Err; // Try to extract each device image specified by the user from the input file. for (StringRef Image : DeviceImages) { @@ -169,8 +145,8 @@ StringSaver Saver(Alloc); auto Args = getImageArguments(Image, Saver); - for (uint64_t I = 0, E = BinariesOrErr->size(); I != E; ++I) { - const auto &Binary = (*BinariesOrErr)[I]; + for (uint64_t I = 0, E = Binaries.size(); I != E; ++I) { + const auto *Binary = Binaries[I].getBinary(); // We handle the 'file' and 'kind' identifiers differently. bool Match = llvm::all_of(Args, [&](auto &Arg) { const auto [Key, Value] = Arg;