Skip to content

Commit 704f342

Browse files
committed
[LLD][COFF] Emit ARM64X relocations for CHPE ExtraRFETable entries
In the native view, ExtraEFRTable references the x86 exception table. The EC view references the ARM exception table, as it did before this change.
1 parent a058741 commit 704f342

File tree

2 files changed

+51
-12
lines changed

2 files changed

+51
-12
lines changed

lld/COFF/Writer.cpp

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,9 @@ class Writer {
343343
// x86_64 .pdata sections on ARM64EC/ARM64X targets.
344344
ChunkRange hybridPdata;
345345

346+
// CHPE metadata symbol on ARM64C target.
347+
DefinedRegular *chpeSym = nullptr;
348+
346349
COFFLinkerContext &ctx;
347350
};
348351
} // anonymous namespace
@@ -2360,16 +2363,17 @@ void Writer::setECSymbols() {
23602363
return a.first->getRVA() < b.first->getRVA();
23612364
});
23622365

2366+
ChunkRange &chpePdata = ctx.hybridSymtab ? hybridPdata : pdata;
23632367
Symbol *rfeTableSym = symtab->findUnderscore("__arm64x_extra_rfe_table");
23642368
replaceSymbol<DefinedSynthetic>(rfeTableSym, "__arm64x_extra_rfe_table",
2365-
pdata.first);
2369+
chpePdata.first);
23662370

2367-
if (pdata.first) {
2371+
if (chpePdata.first) {
23682372
Symbol *rfeSizeSym =
23692373
symtab->findUnderscore("__arm64x_extra_rfe_table_size");
23702374
cast<DefinedAbsolute>(rfeSizeSym)
2371-
->setVA(pdata.last->getRVA() + pdata.last->getSize() -
2372-
pdata.first->getRVA());
2375+
->setVA(chpePdata.last->getRVA() + chpePdata.last->getSize() -
2376+
chpePdata.first->getRVA());
23732377
}
23742378

23752379
Symbol *rangesCountSym =
@@ -2423,12 +2427,22 @@ void Writer::setECSymbols() {
24232427
offsetof(data_directory, Size),
24242428
symtab->edataEnd->getRVA() - symtab->edataStart->getRVA() +
24252429
symtab->edataEnd->getSize());
2426-
if (hybridPdata.first)
2430+
if (hybridPdata.first) {
24272431
ctx.dynamicRelocs->set(
24282432
dataDirOffset64 + EXCEPTION_TABLE * sizeof(data_directory) +
24292433
offsetof(data_directory, Size),
24302434
hybridPdata.last->getRVA() - hybridPdata.first->getRVA() +
24312435
hybridPdata.last->getSize());
2436+
if (chpeSym) {
2437+
size_t size = 0;
2438+
if (pdata.first)
2439+
size = pdata.last->getRVA() - pdata.first->getRVA() +
2440+
pdata.last->getSize();
2441+
ctx.dynamicRelocs->set(chpeSym->getRVA() +
2442+
offsetof(chpe_metadata, ExtraRFETableSize),
2443+
size);
2444+
}
2445+
}
24322446
}
24332447
}
24342448

@@ -2664,21 +2678,26 @@ void Writer::createDynamicRelocs() {
26642678
coffHeaderOffset + offsetof(coff_file_header, Machine),
26652679
AMD64);
26662680

2681+
if (ctx.symtab.entry != ctx.hybridSymtab->entry ||
2682+
pdata.first != hybridPdata.first) {
2683+
chpeSym = cast_or_null<DefinedRegular>(
2684+
ctx.hybridSymtab->findUnderscore("__chpe_metadata"));
2685+
if (!chpeSym)
2686+
Warn(ctx) << "'__chpe_metadata' is missing for ARM64X target";
2687+
}
2688+
26672689
if (ctx.symtab.entry != ctx.hybridSymtab->entry) {
26682690
ctx.dynamicRelocs->add(IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof(uint32_t),
26692691
peHeaderOffset +
26702692
offsetof(pe32plus_header, AddressOfEntryPoint),
26712693
cast_or_null<Defined>(ctx.hybridSymtab->entry));
26722694

26732695
// Swap the alternate entry point in the CHPE metadata.
2674-
Symbol *s = ctx.hybridSymtab->findUnderscore("__chpe_metadata");
2675-
if (auto chpeSym = cast_or_null<DefinedRegular>(s))
2696+
if (chpeSym)
26762697
ctx.dynamicRelocs->add(
26772698
IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof(uint32_t),
26782699
Arm64XRelocVal(chpeSym, offsetof(chpe_metadata, AlternateEntryPoint)),
26792700
cast_or_null<Defined>(ctx.symtab.entry));
2680-
else
2681-
Warn(ctx) << "'__chpe_metadata' is missing for ARM64X target";
26822701
}
26832702

26842703
if (ctx.symtab.edataStart != ctx.hybridSymtab->edataStart) {
@@ -2705,6 +2724,18 @@ void Writer::createDynamicRelocs() {
27052724
dataDirOffset64 +
27062725
EXCEPTION_TABLE * sizeof(data_directory) +
27072726
offsetof(data_directory, Size));
2727+
2728+
// Swap ExtraRFETable in the CHPE metadata.
2729+
if (chpeSym) {
2730+
ctx.dynamicRelocs->add(
2731+
IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof(uint32_t),
2732+
Arm64XRelocVal(chpeSym, offsetof(chpe_metadata, ExtraRFETable)),
2733+
pdata.first);
2734+
// The Size value is assigned after addresses are finalized.
2735+
ctx.dynamicRelocs->add(
2736+
IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof(uint32_t),
2737+
Arm64XRelocVal(chpeSym, offsetof(chpe_metadata, ExtraRFETableSize)));
2738+
}
27082739
}
27092740

27102741
// Set the hybrid load config to the EC load config.

lld/test/COFF/pdata-arm64ec.test

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,18 +58,26 @@ Mixed arm64x code:
5858
RUN: lld-link -out:test4.dll -machine:arm64x arm64-func-sym.obj arm64ec-func-sym.obj \
5959
RUN: x86_64-func-sym.obj loadconfig-arm64.obj loadconfig-arm64ec.obj -dll -noentry
6060

61-
RUN: llvm-readobj --headers test4.dll | FileCheck -check-prefix=DIR3 %s
61+
RUN: llvm-readobj --headers --coff-load-config test4.dll | FileCheck -check-prefix=DIR3 %s
6262
DIR3: ImageOptionalHeader {
6363
DIR3: DataDirectory {
6464
DIR3: ExceptionTableRVA: 0x6000
6565
DIR3-NEXT: ExceptionTableSize: 0x10
6666
DIR3: }
6767
DIR3: }
68+
DIR3: CHPEMetadata [
69+
DIR3: ExtraRFETable: 0x6010
70+
DIR3-NEXT: ExtraRFETableSize: 0xC
71+
DIR3: ]
6872
DIR3: HybridObject {
6973
DIR3: ImageOptionalHeader {
7074
DIR3: ExceptionTableRVA: 0x6010
7175
DIR3-NEXT: ExceptionTableSize: 0xC
7276
DIR3: }
77+
DIR3: CHPEMetadata [
78+
DIR3: ExtraRFETable: 0x6000
79+
DIR3-NEXT: ExtraRFETableSize: 0x10
80+
DIR3: ]
7381
DIR3: }
7482

7583
RUN: llvm-objdump -s --section=.pdata test4.dll | FileCheck -check-prefix=DATA4 %s
@@ -86,12 +94,12 @@ RUN: llvm-objdump -s --section=.pdata test5.dll | FileCheck -check-prefix=DATA3
8694

8795
RUN: lld-link -out:test6.dll -machine:arm64x arm64ec-func-sym.obj x86_64-func-sym.obj \
8896
RUN: arm64-func-sym.obj loadconfig-arm64.obj loadconfig-arm64ec.obj -dll -noentry
89-
RUN: llvm-readobj --headers test6.dll | FileCheck -check-prefix=DIR3 %s
97+
RUN: llvm-readobj --headers --coff-load-config test6.dll | FileCheck -check-prefix=DIR3 %s
9098
RUN: llvm-objdump -s --section=.pdata test6.dll | FileCheck -check-prefix=DATA4 %s
9199

92100
RUN: lld-link -out:test7.dll -machine:arm64x x86_64-func-sym.obj arm64ec-func-sym.obj \
93101
RUN: arm64-func-sym.obj loadconfig-arm64.obj loadconfig-arm64ec.obj -dll -noentry
94-
RUN: llvm-readobj --headers test7.dll | FileCheck -check-prefix=DIR3 %s
102+
RUN: llvm-readobj --headers --coff-load-config test7.dll | FileCheck -check-prefix=DIR3 %s
95103
RUN: llvm-objdump -s --section=.pdata test7.dll | FileCheck -check-prefix=DATA4 %s
96104

97105
#--- arm64-func-sym.s

0 commit comments

Comments
 (0)