Skip to content

Commit feeca77

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 c52fbab commit feeca77

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
@@ -2362,16 +2365,17 @@ void Writer::setECSymbols() {
23622365
return a.first->getRVA() < b.first->getRVA();
23632366
});
23642367

2368+
ChunkRange &chpePdata = ctx.hybridSymtab ? hybridPdata : pdata;
23652369
Symbol *rfeTableSym = symtab->findUnderscore("__arm64x_extra_rfe_table");
23662370
replaceSymbol<DefinedSynthetic>(rfeTableSym, "__arm64x_extra_rfe_table",
2367-
pdata.first);
2371+
chpePdata.first);
23682372

2369-
if (pdata.first) {
2373+
if (chpePdata.first) {
23702374
Symbol *rfeSizeSym =
23712375
symtab->findUnderscore("__arm64x_extra_rfe_table_size");
23722376
cast<DefinedAbsolute>(rfeSizeSym)
2373-
->setVA(pdata.last->getRVA() + pdata.last->getSize() -
2374-
pdata.first->getRVA());
2377+
->setVA(chpePdata.last->getRVA() + chpePdata.last->getSize() -
2378+
chpePdata.first->getRVA());
23752379
}
23762380

23772381
Symbol *rangesCountSym =
@@ -2425,12 +2429,22 @@ void Writer::setECSymbols() {
24252429
offsetof(data_directory, Size),
24262430
symtab->edataEnd->getRVA() - symtab->edataStart->getRVA() +
24272431
symtab->edataEnd->getSize());
2428-
if (hybridPdata.first)
2432+
if (hybridPdata.first) {
24292433
ctx.dynamicRelocs->set(
24302434
dataDirOffset64 + EXCEPTION_TABLE * sizeof(data_directory) +
24312435
offsetof(data_directory, Size),
24322436
hybridPdata.last->getRVA() - hybridPdata.first->getRVA() +
24332437
hybridPdata.last->getSize());
2438+
if (chpeSym) {
2439+
size_t size = 0;
2440+
if (pdata.first)
2441+
size = pdata.last->getRVA() + pdata.last->getSize() -
2442+
pdata.first->getRVA();
2443+
ctx.dynamicRelocs->set(chpeSym->getRVA() +
2444+
offsetof(chpe_metadata, ExtraRFETableSize),
2445+
size);
2446+
}
2447+
}
24342448
}
24352449
}
24362450

@@ -2666,21 +2680,26 @@ void Writer::createDynamicRelocs() {
26662680
coffHeaderOffset + offsetof(coff_file_header, Machine),
26672681
AMD64);
26682682

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

26752697
// Swap the alternate entry point in the CHPE metadata.
2676-
Symbol *s = ctx.hybridSymtab->findUnderscore("__chpe_metadata");
2677-
if (auto chpeSym = cast_or_null<DefinedRegular>(s))
2698+
if (chpeSym)
26782699
ctx.dynamicRelocs->add(
26792700
IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof(uint32_t),
26802701
Arm64XRelocVal(chpeSym, offsetof(chpe_metadata, AlternateEntryPoint)),
26812702
cast_or_null<Defined>(ctx.symtab.entry));
2682-
else
2683-
Warn(ctx) << "'__chpe_metadata' is missing for ARM64X target";
26842703
}
26852704

26862705
if (ctx.symtab.edataStart != ctx.hybridSymtab->edataStart) {
@@ -2707,6 +2726,18 @@ void Writer::createDynamicRelocs() {
27072726
dataDirOffset64 +
27082727
EXCEPTION_TABLE * sizeof(data_directory) +
27092728
offsetof(data_directory, Size));
2729+
2730+
// Swap ExtraRFETable in the CHPE metadata.
2731+
if (chpeSym) {
2732+
ctx.dynamicRelocs->add(
2733+
IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof(uint32_t),
2734+
Arm64XRelocVal(chpeSym, offsetof(chpe_metadata, ExtraRFETable)),
2735+
pdata.first);
2736+
// The Size value is assigned after addresses are finalized.
2737+
ctx.dynamicRelocs->add(
2738+
IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof(uint32_t),
2739+
Arm64XRelocVal(chpeSym, offsetof(chpe_metadata, ExtraRFETableSize)));
2740+
}
27102741
}
27112742

27122743
// 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)