Skip to content

Commit 659e66e

Browse files
authored
[LLD][COFF] Implement ARM64X relocations for the exception table (#123723)
1 parent e2d9e99 commit 659e66e

File tree

4 files changed

+54
-7
lines changed

4 files changed

+54
-7
lines changed

lld/COFF/Chunks.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1167,7 +1167,7 @@ uint32_t ImportThunkChunkARM64EC::extendRanges() {
11671167
}
11681168

11691169
uint64_t Arm64XRelocVal::get() const {
1170-
return (sym ? sym->getRVA() : 0) + value;
1170+
return (sym ? sym->getRVA() : 0) + (chunk ? chunk->getRVA() : 0) + value;
11711171
}
11721172

11731173
size_t Arm64XDynamicRelocEntry::getSize() const {
@@ -1230,6 +1230,17 @@ void DynamicRelocsChunk::finalize() {
12301230
size = alignTo(size, sizeof(uint32_t));
12311231
}
12321232

1233+
// Set the reloc value. The reloc entry must be allocated beforehand.
1234+
void DynamicRelocsChunk::set(uint32_t rva, Arm64XRelocVal value) {
1235+
auto entry =
1236+
llvm::find_if(arm64xRelocs, [rva](const Arm64XDynamicRelocEntry &e) {
1237+
return e.offset.get() == rva;
1238+
});
1239+
assert(entry != arm64xRelocs.end());
1240+
assert(!entry->value.get());
1241+
entry->value = value;
1242+
}
1243+
12331244
void DynamicRelocsChunk::writeTo(uint8_t *buf) const {
12341245
auto table = reinterpret_cast<coff_dynamic_reloc_table *>(buf);
12351246
table->Version = 1;

lld/COFF/Chunks.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -840,10 +840,13 @@ class Arm64XRelocVal {
840840
public:
841841
Arm64XRelocVal(uint64_t value = 0) : value(value) {}
842842
Arm64XRelocVal(Defined *sym, int32_t offset = 0) : sym(sym), value(offset) {}
843+
Arm64XRelocVal(Chunk *chunk, int32_t offset = 0)
844+
: chunk(chunk), value(offset) {}
843845
uint64_t get() const;
844846

845847
private:
846848
Defined *sym = nullptr;
849+
Chunk *chunk = nullptr;
847850
uint64_t value;
848851
};
849852

@@ -874,10 +877,12 @@ class DynamicRelocsChunk : public NonSectionChunk {
874877
void finalize();
875878

876879
void add(llvm::COFF::Arm64XFixupType type, uint8_t size,
877-
Arm64XRelocVal offset, Arm64XRelocVal value) {
880+
Arm64XRelocVal offset, Arm64XRelocVal value = Arm64XRelocVal()) {
878881
arm64xRelocs.emplace_back(type, size, offset, value);
879882
}
880883

884+
void set(uint32_t rva, Arm64XRelocVal value);
885+
881886
private:
882887
std::vector<Arm64XDynamicRelocEntry> arm64xRelocs;
883888
size_t size;

lld/COFF/Writer.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2392,6 +2392,13 @@ void Writer::setECSymbols() {
23922392
symtab->findUnderscore("__arm64x_native_entrypoint")
23932393
->replaceKeepingName(altEntrySym, sizeof(SymbolUnion));
23942394
}
2395+
2396+
if (hybridPdata.first)
2397+
ctx.dynamicRelocs->set(
2398+
dataDirOffset64 + EXCEPTION_TABLE * sizeof(data_directory) +
2399+
offsetof(data_directory, Size),
2400+
hybridPdata.last->getRVA() - hybridPdata.first->getRVA() +
2401+
hybridPdata.last->getSize());
23952402
}
23962403
}
23972404

@@ -2644,6 +2651,19 @@ void Writer::createDynamicRelocs() {
26442651
Warn(ctx) << "'__chpe_metadata' is missing for ARM64X target";
26452652
}
26462653

2654+
if (pdata.first != hybridPdata.first) {
2655+
ctx.dynamicRelocs->add(IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof(uint32_t),
2656+
dataDirOffset64 +
2657+
EXCEPTION_TABLE * sizeof(data_directory) +
2658+
offsetof(data_directory, RelativeVirtualAddress),
2659+
hybridPdata.first);
2660+
// The Size value is assigned after addresses are finalized.
2661+
ctx.dynamicRelocs->add(IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof(uint32_t),
2662+
dataDirOffset64 +
2663+
EXCEPTION_TABLE * sizeof(data_directory) +
2664+
offsetof(data_directory, Size));
2665+
}
2666+
26472667
// Set the hybrid load config to the EC load config.
26482668
ctx.dynamicRelocs->add(IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof(uint32_t),
26492669
dataDirOffset64 +

lld/test/COFF/pdata-arm64ec.test

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Test handlign of hybrid .pdata section on ARM64EC target.
66
RUN: llvm-mc -filetype=obj -triple=arm64-windows arm64-func-sym.s -o arm64-func-sym.obj
77
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows arm64ec-func-sym.s -o arm64ec-func-sym.obj
88
RUN: llvm-mc -filetype=obj -triple=x86_64-windows x86_64-func-sym.s -o x86_64-func-sym.obj
9+
RUN: llvm-mc -filetype=obj -triple=aarch64-windows %S/Inputs/loadconfig-arm64.s -o loadconfig-arm64.obj
910
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows %p/Inputs/loadconfig-arm64ec.s -o loadconfig-arm64ec.obj
1011

1112
Only arm64ec code:
@@ -55,11 +56,21 @@ DATA3: 180005000 00100000 11000001 00200000 0e200000
5556
Mixed arm64x code:
5657

5758
RUN: lld-link -out:test4.dll -machine:arm64x arm64-func-sym.obj arm64ec-func-sym.obj \
58-
RUN: x86_64-func-sym.obj loadconfig-arm64ec.obj -dll -noentry
59+
RUN: x86_64-func-sym.obj loadconfig-arm64.obj loadconfig-arm64ec.obj -dll -noentry
5960

6061
RUN: llvm-readobj --headers test4.dll | FileCheck -check-prefix=DIR3 %s
61-
DIR3: ExceptionTableRVA: 0x6000
62-
DIR3-NEXT: ExceptionTableSize: 0x10
62+
DIR3: ImageOptionalHeader {
63+
DIR3: DataDirectory {
64+
DIR3: ExceptionTableRVA: 0x6000
65+
DIR3-NEXT: ExceptionTableSize: 0x10
66+
DIR3: }
67+
DIR3: }
68+
DIR3: HybridObject {
69+
DIR3: ImageOptionalHeader {
70+
DIR3: ExceptionTableRVA: 0x6010
71+
DIR3-NEXT: ExceptionTableSize: 0xC
72+
DIR3: }
73+
DIR3: }
6374

6475
RUN: llvm-objdump -s --section=.pdata test4.dll | FileCheck -check-prefix=DATA4 %s
6576
DATA4: 180006000 00100000 11000001 00200000 11000001 ......... ......
@@ -74,12 +85,12 @@ RUN: llvm-readobj --headers test5.dll | FileCheck -check-prefix=DIR2 %s
7485
RUN: llvm-objdump -s --section=.pdata test5.dll | FileCheck -check-prefix=DATA3 %s
7586

7687
RUN: lld-link -out:test6.dll -machine:arm64x arm64ec-func-sym.obj x86_64-func-sym.obj \
77-
RUN: arm64-func-sym.obj loadconfig-arm64ec.obj -dll -noentry
88+
RUN: arm64-func-sym.obj loadconfig-arm64.obj loadconfig-arm64ec.obj -dll -noentry
7889
RUN: llvm-readobj --headers test6.dll | FileCheck -check-prefix=DIR3 %s
7990
RUN: llvm-objdump -s --section=.pdata test6.dll | FileCheck -check-prefix=DATA4 %s
8091

8192
RUN: lld-link -out:test7.dll -machine:arm64x x86_64-func-sym.obj arm64ec-func-sym.obj \
82-
RUN: arm64-func-sym.obj loadconfig-arm64ec.obj -dll -noentry
93+
RUN: arm64-func-sym.obj loadconfig-arm64.obj loadconfig-arm64ec.obj -dll -noentry
8394
RUN: llvm-readobj --headers test7.dll | FileCheck -check-prefix=DIR3 %s
8495
RUN: llvm-objdump -s --section=.pdata test7.dll | FileCheck -check-prefix=DATA4 %s
8596

0 commit comments

Comments
 (0)