[lld] [LLD][COFF] Emit base relocation for native CHPE metadata pointer on ARM64X (PR #121500)
Jacek Caban via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 2 08:46:16 PST 2025
https://github.com/cjacek created https://github.com/llvm/llvm-project/pull/121500
None
>From 8a369899dea44ed68b6c675644177d12f264b73a Mon Sep 17 00:00:00 2001
From: Jacek Caban <jacek at codeweavers.com>
Date: Mon, 9 Dec 2024 15:19:43 +0100
Subject: [PATCH] [LLD][COFF] Emit base relocation for native CHPE metadata
pointer on ARM64X
---
lld/COFF/Writer.cpp | 32 +++++++++++++++++++++++++++++++
lld/test/COFF/arm64x-loadconfig.s | 6 +++++-
2 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp
index b3dd5f6cf49265..a0ab80f0bf2d16 100644
--- a/lld/COFF/Writer.cpp
+++ b/lld/COFF/Writer.cpp
@@ -2594,6 +2594,38 @@ void Writer::createDynamicRelocs() {
LOAD_CONFIG_TABLE * sizeof(data_directory) +
offsetof(data_directory, Size),
0);
+
+ // Insert a 64-bit relocation for CHPEMetadataPointer. Its value will be set
+ // later in prepareLoadConfig to match the value in the EC load config.
+ // However, a base relocation must be allocated in advance, so we handle it
+ // here.
+ if (ctx.symtab.loadConfigSym && ctx.hybridSymtab->loadConfigSym &&
+ ctx.symtab.loadConfigSize >=
+ offsetof(coff_load_configuration64, CHPEMetadataPointer) +
+ sizeof(coff_load_configuration64::CHPEMetadataPointer)) {
+ DefinedRegular *sym = ctx.symtab.loadConfigSym;
+ SectionChunk *chunk = sym->getChunk();
+ ArrayRef<coff_relocation> curRelocs = chunk->getRelocs();
+ MutableArrayRef<coff_relocation> newRelocs(
+ bAlloc().Allocate<coff_relocation>(curRelocs.size() + 1),
+ curRelocs.size() + 1);
+ size_t chpeOffset = sym->getValue() + offsetof(coff_load_configuration64,
+ CHPEMetadataPointer);
+ size_t i;
+ for (i = 0;
+ i < curRelocs.size() && curRelocs[i].VirtualAddress < chpeOffset; ++i)
+ newRelocs[i] = curRelocs[i];
+ newRelocs[i].VirtualAddress = chpeOffset;
+ // The specific symbol used here is irrelevant as long as it's valid, since
+ // it will be overridden by prepareLoadConfig. Use the load config symbol
+ // itself.
+ newRelocs[i].SymbolTableIndex =
+ chunk->file->getCOFFObj()->getSymbolIndex(sym->getCOFFSymbol());
+ newRelocs[i].Type = IMAGE_REL_ARM64_ADDR64;
+ for (; i < curRelocs.size(); ++i)
+ newRelocs[i + 1] = curRelocs[i];
+ chunk->setRelocs(newRelocs);
+ }
}
PartialSection *Writer::createPartialSection(StringRef name,
diff --git a/lld/test/COFF/arm64x-loadconfig.s b/lld/test/COFF/arm64x-loadconfig.s
index d21f4bfe95b843..3b53d32a9b5492 100644
--- a/lld/test/COFF/arm64x-loadconfig.s
+++ b/lld/test/COFF/arm64x-loadconfig.s
@@ -118,10 +118,14 @@
// BASERELOC: BaseReloc [
// BASERELOC-NEXT: Entry {
// BASERELOC-NEXT: Type: DIR64
+// BASERELOC-NEXT: Address: 0x10C8
+// BASERELOC-NEXT: }
+// BASERELOC-NEXT: Entry {
+// BASERELOC-NEXT: Type: DIR64
// BASERELOC-NEXT: Address: 0x1208
// BASERELOC-NEXT: }
// BASERELOC-NEXT: Entry {
-// BASERELOC: Type: DIR64
+// BASERELOC-NEXT: Type: DIR64
// BASERELOC-NEXT: Address: 0x2074
// BASERELOC-NEXT: }
More information about the llvm-commits
mailing list