[LLD][COFF] Emit ARM64X relocations for CHPE ExtraRFETable entries (#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.
This commit is contained in:
parent
7d9a12cec2
commit
8252e0ef82
@ -343,6 +343,9 @@ private:
|
||||
// x86_64 .pdata sections on ARM64EC/ARM64X targets.
|
||||
ChunkRange hybridPdata;
|
||||
|
||||
// CHPE metadata symbol on ARM64C target.
|
||||
DefinedRegular *chpeSym = nullptr;
|
||||
|
||||
COFFLinkerContext &ctx;
|
||||
};
|
||||
} // anonymous namespace
|
||||
@ -2362,16 +2365,17 @@ void Writer::setECSymbols() {
|
||||
return a.first->getRVA() < b.first->getRVA();
|
||||
});
|
||||
|
||||
ChunkRange &chpePdata = ctx.hybridSymtab ? hybridPdata : pdata;
|
||||
Symbol *rfeTableSym = symtab->findUnderscore("__arm64x_extra_rfe_table");
|
||||
replaceSymbol<DefinedSynthetic>(rfeTableSym, "__arm64x_extra_rfe_table",
|
||||
pdata.first);
|
||||
chpePdata.first);
|
||||
|
||||
if (pdata.first) {
|
||||
if (chpePdata.first) {
|
||||
Symbol *rfeSizeSym =
|
||||
symtab->findUnderscore("__arm64x_extra_rfe_table_size");
|
||||
cast<DefinedAbsolute>(rfeSizeSym)
|
||||
->setVA(pdata.last->getRVA() + pdata.last->getSize() -
|
||||
pdata.first->getRVA());
|
||||
->setVA(chpePdata.last->getRVA() + chpePdata.last->getSize() -
|
||||
chpePdata.first->getRVA());
|
||||
}
|
||||
|
||||
Symbol *rangesCountSym =
|
||||
@ -2425,12 +2429,22 @@ void Writer::setECSymbols() {
|
||||
offsetof(data_directory, Size),
|
||||
symtab->edataEnd->getRVA() - symtab->edataStart->getRVA() +
|
||||
symtab->edataEnd->getSize());
|
||||
if (hybridPdata.first)
|
||||
if (hybridPdata.first) {
|
||||
ctx.dynamicRelocs->set(
|
||||
dataDirOffset64 + EXCEPTION_TABLE * sizeof(data_directory) +
|
||||
offsetof(data_directory, Size),
|
||||
hybridPdata.last->getRVA() - hybridPdata.first->getRVA() +
|
||||
hybridPdata.last->getSize());
|
||||
if (chpeSym) {
|
||||
size_t size = 0;
|
||||
if (pdata.first)
|
||||
size = pdata.last->getRVA() + pdata.last->getSize() -
|
||||
pdata.first->getRVA();
|
||||
ctx.dynamicRelocs->set(chpeSym->getRVA() +
|
||||
offsetof(chpe_metadata, ExtraRFETableSize),
|
||||
size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2666,6 +2680,14 @@ void Writer::createDynamicRelocs() {
|
||||
coffHeaderOffset + offsetof(coff_file_header, Machine),
|
||||
AMD64);
|
||||
|
||||
if (ctx.symtab.entry != ctx.hybridSymtab->entry ||
|
||||
pdata.first != hybridPdata.first) {
|
||||
chpeSym = cast_or_null<DefinedRegular>(
|
||||
ctx.hybridSymtab->findUnderscore("__chpe_metadata"));
|
||||
if (!chpeSym)
|
||||
Warn(ctx) << "'__chpe_metadata' is missing for ARM64X target";
|
||||
}
|
||||
|
||||
if (ctx.symtab.entry != ctx.hybridSymtab->entry) {
|
||||
ctx.dynamicRelocs->add(IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof(uint32_t),
|
||||
peHeaderOffset +
|
||||
@ -2673,14 +2695,11 @@ void Writer::createDynamicRelocs() {
|
||||
cast_or_null<Defined>(ctx.hybridSymtab->entry));
|
||||
|
||||
// Swap the alternate entry point in the CHPE metadata.
|
||||
Symbol *s = ctx.hybridSymtab->findUnderscore("__chpe_metadata");
|
||||
if (auto chpeSym = cast_or_null<DefinedRegular>(s))
|
||||
if (chpeSym)
|
||||
ctx.dynamicRelocs->add(
|
||||
IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof(uint32_t),
|
||||
Arm64XRelocVal(chpeSym, offsetof(chpe_metadata, AlternateEntryPoint)),
|
||||
cast_or_null<Defined>(ctx.symtab.entry));
|
||||
else
|
||||
Warn(ctx) << "'__chpe_metadata' is missing for ARM64X target";
|
||||
}
|
||||
|
||||
if (ctx.symtab.edataStart != ctx.hybridSymtab->edataStart) {
|
||||
@ -2707,6 +2726,18 @@ void Writer::createDynamicRelocs() {
|
||||
dataDirOffset64 +
|
||||
EXCEPTION_TABLE * sizeof(data_directory) +
|
||||
offsetof(data_directory, Size));
|
||||
|
||||
// Swap ExtraRFETable in the CHPE metadata.
|
||||
if (chpeSym) {
|
||||
ctx.dynamicRelocs->add(
|
||||
IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof(uint32_t),
|
||||
Arm64XRelocVal(chpeSym, offsetof(chpe_metadata, ExtraRFETable)),
|
||||
pdata.first);
|
||||
// The Size value is assigned after addresses are finalized.
|
||||
ctx.dynamicRelocs->add(
|
||||
IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof(uint32_t),
|
||||
Arm64XRelocVal(chpeSym, offsetof(chpe_metadata, ExtraRFETableSize)));
|
||||
}
|
||||
}
|
||||
|
||||
// Set the hybrid load config to the EC load config.
|
||||
|
@ -58,18 +58,26 @@ Mixed arm64x code:
|
||||
RUN: lld-link -out:test4.dll -machine:arm64x arm64-func-sym.obj arm64ec-func-sym.obj \
|
||||
RUN: x86_64-func-sym.obj loadconfig-arm64.obj loadconfig-arm64ec.obj -dll -noentry
|
||||
|
||||
RUN: llvm-readobj --headers test4.dll | FileCheck -check-prefix=DIR3 %s
|
||||
RUN: llvm-readobj --headers --coff-load-config test4.dll | FileCheck -check-prefix=DIR3 %s
|
||||
DIR3: ImageOptionalHeader {
|
||||
DIR3: DataDirectory {
|
||||
DIR3: ExceptionTableRVA: 0x6000
|
||||
DIR3-NEXT: ExceptionTableSize: 0x10
|
||||
DIR3: }
|
||||
DIR3: }
|
||||
DIR3: CHPEMetadata [
|
||||
DIR3: ExtraRFETable: 0x6010
|
||||
DIR3-NEXT: ExtraRFETableSize: 0xC
|
||||
DIR3: ]
|
||||
DIR3: HybridObject {
|
||||
DIR3: ImageOptionalHeader {
|
||||
DIR3: ExceptionTableRVA: 0x6010
|
||||
DIR3-NEXT: ExceptionTableSize: 0xC
|
||||
DIR3: }
|
||||
DIR3: CHPEMetadata [
|
||||
DIR3: ExtraRFETable: 0x6000
|
||||
DIR3-NEXT: ExtraRFETableSize: 0x10
|
||||
DIR3: ]
|
||||
DIR3: }
|
||||
|
||||
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
|
||||
|
||||
RUN: lld-link -out:test6.dll -machine:arm64x arm64ec-func-sym.obj x86_64-func-sym.obj \
|
||||
RUN: arm64-func-sym.obj loadconfig-arm64.obj loadconfig-arm64ec.obj -dll -noentry
|
||||
RUN: llvm-readobj --headers test6.dll | FileCheck -check-prefix=DIR3 %s
|
||||
RUN: llvm-readobj --headers --coff-load-config test6.dll | FileCheck -check-prefix=DIR3 %s
|
||||
RUN: llvm-objdump -s --section=.pdata test6.dll | FileCheck -check-prefix=DATA4 %s
|
||||
|
||||
RUN: lld-link -out:test7.dll -machine:arm64x x86_64-func-sym.obj arm64ec-func-sym.obj \
|
||||
RUN: arm64-func-sym.obj loadconfig-arm64.obj loadconfig-arm64ec.obj -dll -noentry
|
||||
RUN: llvm-readobj --headers test7.dll | FileCheck -check-prefix=DIR3 %s
|
||||
RUN: llvm-readobj --headers --coff-load-config test7.dll | FileCheck -check-prefix=DIR3 %s
|
||||
RUN: llvm-objdump -s --section=.pdata test7.dll | FileCheck -check-prefix=DATA4 %s
|
||||
|
||||
#--- arm64-func-sym.s
|
||||
|
Loading…
x
Reference in New Issue
Block a user