Skip to content

Commit ce2e663

Browse files
cjacekSquallATF
authored andcommitted
[LLD][COFF] Emit ARM64X relocations for CHPE ExtraRFETable entries (llvm#126713)
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 86a94dc commit ce2e663

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)