From 195029f730ea0a444c940039555d2c336d21281d Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Fri, 21 Apr 2023 00:39:41 +0200 Subject: [PATCH] [lld] Add support for relocations in x86_64 objects on Arm64EC targets. Since EC targets may combine various object types, we need to pick relocation format based on chunk type instead of global config. --- lld/COFF/Chunks.cpp | 4 ++-- lld/COFF/Chunks.h | 2 ++ lld/test/COFF/arm64ec-reloc.test | 37 ++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 lld/test/COFF/arm64ec-reloc.test diff --git a/lld/COFF/Chunks.cpp b/lld/COFF/Chunks.cpp index e17b64df869fe8..4e845afa8947a5 100644 --- a/lld/COFF/Chunks.cpp +++ b/lld/COFF/Chunks.cpp @@ -437,7 +437,7 @@ void SectionChunk::applyRelocation(uint8_t *off, // Compute the RVA of the relocation for relative relocations. uint64_t p = rva + rel.VirtualAddress; uint64_t imageBase = file->ctx.config.imageBase; - switch (file->ctx.config.machine) { + switch (getMachine()) { case AMD64: applyRelX64(off, rel.Type, os, s, p, imageBase); break; @@ -551,7 +551,7 @@ static uint8_t getBaserelType(const coff_relocation &rel, // Only called when base relocation is enabled. void SectionChunk::getBaserels(std::vector *res) { for (const coff_relocation &rel : getRelocs()) { - uint8_t ty = getBaserelType(rel, file->ctx.config.machine); + uint8_t ty = getBaserelType(rel, getMachine()); if (ty == IMAGE_REL_BASED_ABSOLUTE) continue; Symbol *target = file->getSymbol(rel.SymbolTableIndex); diff --git a/lld/COFF/Chunks.h b/lld/COFF/Chunks.h index 3d605e6ab10c8c..d14a258fc81e12 100644 --- a/lld/COFF/Chunks.h +++ b/lld/COFF/Chunks.h @@ -219,6 +219,8 @@ class SectionChunk final : public Chunk { ArrayRef getContents() const; void writeTo(uint8_t *buf) const; + MachineTypes getMachine() const { return file->getMachineType(); } + // Defend against unsorted relocations. This may be overly conservative. void sortRelocations(); diff --git a/lld/test/COFF/arm64ec-reloc.test b/lld/test/COFF/arm64ec-reloc.test new file mode 100644 index 00000000000000..3060891bfe02e8 --- /dev/null +++ b/lld/test/COFF/arm64ec-reloc.test @@ -0,0 +1,37 @@ +REQUIRES: aarch64, x86 +RUN: split-file %s %t.dir && cd %t.dir + +Link a mix of ARM64EC and x86_64 data and check that relocations work. + +RUN: llvm-mc -filetype=obj -triple=arm64ec-windows arm64ec-data-sym.s -o arm64ec-data-sym.obj +RUN: llvm-mc -filetype=obj -triple=x86_64-windows x86_64-data-sym.s -o x86_64-data-sym.obj +RUN: lld-link -out:test.dll -machine:arm64ec arm64ec-data-sym.obj x86_64-data-sym.obj -dll -noentry + +RUN: llvm-readobj --hex-dump=.data test.dll | FileCheck -check-prefix=ARM64EC-DATA %s +ARM64EC-DATA: 0x180001000 00100080 01000000 08100080 01000000 + +RUN: llvm-readobj --coff-basereloc test.dll | FileCheck -check-prefix=RELOCS %s +RELOCS: BaseReloc [ +RELOCS-NEXT: Entry { +RELOCS-NEXT: Type: DIR64 +RELOCS-NEXT: Address: 0x1000 +RELOCS-NEXT: } +RELOCS-NEXT: Entry { +RELOCS-NEXT: Type: DIR64 +RELOCS-NEXT: Address: 0x1008 +RELOCS-NEXT: } +RELOCS-NEXT: ] + +#--- arm64ec-data-sym.s + .data + .globl arm64ec_data_sym + .p2align 2, 0x0 +arm64ec_data_sym: + .xword arm64ec_data_sym + +#--- x86_64-data-sym.s + .data + .globl x86_64_data_sym + .p2align 2, 0x0 +x86_64_data_sym: + .quad x86_64_data_sym