diff --git a/clang/test/Driver/linker-wrapper-image.c b/clang/test/Driver/linker-wrapper-image.c index a2a1996f66430..40dde2e029180 100644 --- a/clang/test/Driver/linker-wrapper-image.c +++ b/clang/test/Driver/linker-wrapper-image.c @@ -19,8 +19,8 @@ // OPENMP-COFF: @__start_omp_offloading_entries = hidden constant [0 x %struct.__tgt_offload_entry] zeroinitializer, section "omp_offloading_entries$OA" // OPENMP-COFF-NEXT: @__stop_omp_offloading_entries = hidden constant [0 x %struct.__tgt_offload_entry] zeroinitializer, section "omp_offloading_entries$OZ" -// OPENMP: @.omp_offloading.device_image = internal unnamed_addr constant [[[SIZE:[0-9]+]] x i8] c"\10\FF\10\AD{{.*}}" -// OPENMP-NEXT: @.omp_offloading.device_images = internal unnamed_addr constant [1 x %__tgt_device_image] [%__tgt_device_image { ptr @.omp_offloading.device_image, ptr getelementptr inbounds ([[[SIZE]] x i8], ptr @.omp_offloading.device_image, i64 1, i64 0), ptr @__start_omp_offloading_entries, ptr @__stop_omp_offloading_entries }] +// OPENMP-NEXT: @.omp_offloading.device_image = internal unnamed_addr constant [[[SIZE:[0-9]+]] x i8] c"\10\FF\10\AD\01{{.*}}", section ".llvm.offloading", align 8 +// OPENMP-NEXT: @.omp_offloading.device_images = internal unnamed_addr constant [1 x %__tgt_device_image] [%__tgt_device_image { ptr getelementptr inbounds ([[[BEGIN:[0-9]+]] x i8], ptr @.omp_offloading.device_image, i64 1, i64 0), ptr getelementptr inbounds ([[[END:[0-9]+]] x i8], ptr @.omp_offloading.device_image, i64 1, i64 0), ptr @__start_omp_offloading_entries, ptr @__stop_omp_offloading_entries }] // OPENMP-NEXT: @.omp_offloading.descriptor = internal constant %__tgt_bin_desc { i32 1, ptr @.omp_offloading.device_images, ptr @__start_omp_offloading_entries, ptr @__stop_omp_offloading_entries } // OPENMP-NEXT: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 1, ptr @.omp_offloading.descriptor_reg, ptr null }] // OPENMP-NEXT: @llvm.global_dtors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 1, ptr @.omp_offloading.descriptor_unreg, ptr null }] diff --git a/clang/tools/clang-linker-wrapper/OffloadWrapper.cpp b/clang/tools/clang-linker-wrapper/OffloadWrapper.cpp index f4f500b173572..161374ae55523 100644 --- a/clang/tools/clang-linker-wrapper/OffloadWrapper.cpp +++ b/clang/tools/clang-linker-wrapper/OffloadWrapper.cpp @@ -8,6 +8,7 @@ #include "OffloadWrapper.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/BinaryFormat/Magic.h" #include "llvm/Frontend/Offloading/Utility.h" #include "llvm/IR/Constants.h" #include "llvm/IR/GlobalVariable.h" @@ -121,19 +122,36 @@ GlobalVariable *createBinDesc(Module &M, ArrayRef> Bufs) { SmallVector ImagesInits; ImagesInits.reserve(Bufs.size()); for (ArrayRef Buf : Bufs) { + // We embed the full offloading entry so the binary utilities can parse it. auto *Data = ConstantDataArray::get(C, Buf); - auto *Image = new GlobalVariable(M, Data->getType(), /*isConstant*/ true, + auto *Image = new GlobalVariable(M, Data->getType(), /*isConstant=*/true, GlobalVariable::InternalLinkage, Data, ".omp_offloading.device_image"); Image->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); Image->setSection(".llvm.offloading"); Image->setAlignment(Align(object::OffloadBinary::getAlignment())); - auto *Size = ConstantInt::get(getSizeTTy(M), Buf.size()); + StringRef Binary(Buf.data(), Buf.size()); + assert(identify_magic(Binary) == file_magic::offload_binary && + "Invalid binary format"); + + // The device image struct contains the pointer to the beginning and end of + // the image stored inside of the offload binary. There should only be one + // of these for each buffer so we parse it out manually. + const auto *Header = + reinterpret_cast( + Binary.bytes_begin()); + const auto *Entry = reinterpret_cast( + Binary.bytes_begin() + Header->EntryOffset); + + auto *Begin = ConstantInt::get(getSizeTTy(M), Entry->ImageOffset); + auto *Size = + ConstantInt::get(getSizeTTy(M), Entry->ImageOffset + Entry->ImageSize); + Constant *ZeroBegin[] = {Zero, Begin}; Constant *ZeroSize[] = {Zero, Size}; auto *ImageB = - ConstantExpr::getGetElementPtr(Image->getValueType(), Image, ZeroZero); + ConstantExpr::getGetElementPtr(Image->getValueType(), Image, ZeroBegin); auto *ImageE = ConstantExpr::getGetElementPtr(Image->getValueType(), Image, ZeroSize);