[lld] [LLD][COFF] Use EC load config for ARM64X relocations of load config directory (PR #121337)
Jacek Caban via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 30 05:58:10 PST 2024
https://github.com/cjacek created https://github.com/llvm/llvm-project/pull/121337
This change ensures the load config in the hybrid image view is handled correctly. It introduces a new Arm64XRelocVal class to abstract relocation values, allowing them to be relative to a symbol. This class will also be useful for managing ARM64X relocation offsets in the future.
>From 1c0185eaec70d67121785b162196cd8c60b47623 Mon Sep 17 00:00:00 2001
From: Jacek Caban <jacek at codeweavers.com>
Date: Sun, 8 Dec 2024 17:53:27 +0100
Subject: [PATCH] [LLD][COFF] Use EC load config for ARM64X relocations in load
config directory
This change ensures the load config in the hybrid image view is handled correctly.
It introduces a new Arm64XRelocVal class to abstract relocation values, allowing
them to be relative to a symbol. This class will also be useful for managing ARM64X
relocation offsets in the future.
---
lld/COFF/Chunks.cpp | 10 ++++++---
lld/COFF/Chunks.h | 18 ++++++++++++---
lld/COFF/Writer.cpp | 7 +++---
lld/test/COFF/arm64x-loadconfig.s | 37 +++++++++++++++++++++++++++----
4 files changed, 58 insertions(+), 14 deletions(-)
diff --git a/lld/COFF/Chunks.cpp b/lld/COFF/Chunks.cpp
index ec0fdf0b67b38b..cac581ec0dbbe2 100644
--- a/lld/COFF/Chunks.cpp
+++ b/lld/COFF/Chunks.cpp
@@ -1150,6 +1150,10 @@ uint32_t ImportThunkChunkARM64EC::extendRanges() {
return sizeof(arm64Thunk) - sizeof(uint32_t);
}
+uint64_t Arm64XRelocVal::get() const {
+ return (sym ? sym->getRVA() : 0) + value;
+}
+
size_t Arm64XDynamicRelocEntry::getSize() const {
switch (type) {
case IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE:
@@ -1169,13 +1173,13 @@ void Arm64XDynamicRelocEntry::writeTo(uint8_t *buf) const {
*out |= ((bit_width(size) - 1) << 14); // Encode the size.
switch (size) {
case 2:
- out[1] = value;
+ out[1] = value.get();
break;
case 4:
- *reinterpret_cast<ulittle32_t *>(out + 1) = value;
+ *reinterpret_cast<ulittle32_t *>(out + 1) = value.get();
break;
case 8:
- *reinterpret_cast<ulittle64_t *>(out + 1) = value;
+ *reinterpret_cast<ulittle64_t *>(out + 1) = value.get();
break;
default:
llvm_unreachable("invalid size");
diff --git a/lld/COFF/Chunks.h b/lld/COFF/Chunks.h
index 0d2b2ac0f15ea9..6adc751c214ab7 100644
--- a/lld/COFF/Chunks.h
+++ b/lld/COFF/Chunks.h
@@ -835,18 +835,30 @@ class ECExportThunkChunk : public NonSectionCodeChunk {
Defined *target;
};
+// ARM64X relocation value, potentially relative to a symbol.
+class Arm64XRelocVal {
+public:
+ Arm64XRelocVal(int64_t value = 0) : value(value) {}
+ Arm64XRelocVal(Defined *sym, int32_t offset = 0) : sym(sym), value(offset) {}
+ uint64_t get() const;
+
+private:
+ Defined *sym = nullptr;
+ uint64_t value;
+};
+
// ARM64X entry for dynamic relocations.
class Arm64XDynamicRelocEntry {
public:
Arm64XDynamicRelocEntry(llvm::COFF::Arm64XFixupType type, uint8_t size,
- uint32_t offset, uint64_t value)
+ uint32_t offset, Arm64XRelocVal value)
: offset(offset), value(value), type(type), size(size) {}
size_t getSize() const;
void writeTo(uint8_t *buf) const;
uint32_t offset;
- uint64_t value;
+ Arm64XRelocVal value;
private:
llvm::COFF::Arm64XFixupType type;
@@ -862,7 +874,7 @@ class DynamicRelocsChunk : public NonSectionChunk {
void finalize();
void add(llvm::COFF::Arm64XFixupType type, uint8_t size, uint32_t offset,
- uint64_t value) {
+ Arm64XRelocVal value) {
arm64xRelocs.emplace_back(type, size, offset, value);
}
diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp
index b3dd5f6cf49265..156f051901c892 100644
--- a/lld/COFF/Writer.cpp
+++ b/lld/COFF/Writer.cpp
@@ -2582,18 +2582,17 @@ void Writer::createDynamicRelocs() {
coffHeaderOffset + offsetof(coff_file_header, Machine),
AMD64);
- // Clear the load config directory.
- // FIXME: Use the hybrid load config value instead.
+ // Set the hybrid load config to the EC load config.
ctx.dynamicRelocs->add(IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof(uint32_t),
dataDirOffset64 +
LOAD_CONFIG_TABLE * sizeof(data_directory) +
offsetof(data_directory, RelativeVirtualAddress),
- 0);
+ ctx.hybridSymtab->loadConfigSym);
ctx.dynamicRelocs->add(IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof(uint32_t),
dataDirOffset64 +
LOAD_CONFIG_TABLE * sizeof(data_directory) +
offsetof(data_directory, Size),
- 0);
+ ctx.hybridSymtab->loadConfigSize);
}
PartialSection *Writer::createPartialSection(StringRef name,
diff --git a/lld/test/COFF/arm64x-loadconfig.s b/lld/test/COFF/arm64x-loadconfig.s
index 8d2ab555546341..2b550864b77f15 100644
--- a/lld/test/COFF/arm64x-loadconfig.s
+++ b/lld/test/COFF/arm64x-loadconfig.s
@@ -87,20 +87,49 @@
// LOADCFG-NEXT: RVA: 0x150
// LOADCFG-NEXT: Type: VALUE
// LOADCFG-NEXT: Size: 0x4
-// LOADCFG-NEXT: Value: 0x0
+// LOADCFG-NEXT: Value: 0x1140
// LOADCFG-NEXT: ]
// LOADCFG-NEXT: Entry [
// LOADCFG-NEXT: RVA: 0x154
// LOADCFG-NEXT: Type: VALUE
// LOADCFG-NEXT: Size: 0x4
-// LOADCFG-NEXT: Value: 0x0
+// LOADCFG-NEXT: Value: 0x140
// LOADCFG-NEXT: ]
// LOADCFG-NEXT: ]
// LOADCFG-NEXT: ]
// LOADCFG-NEXT: HybridObject {
-// LOADCFG-NEXT: Format: COFF-x86-64
-// LOADCFG-NEXT: Arch: x86_64
+// LOADCFG-NEXT: Format: COFF-ARM64EC
+// LOADCFG-NEXT: Arch: aarch64
// LOADCFG-NEXT: AddressSize: 64bit
+// LOADCFG-NEXT: LoadConfig [
+// LOADCFG-NEXT: Size: 0x140
+// LOADCFG: CHPEMetadata [
+// LOADCFG-NEXT: Version: 0x2
+// LOADCFG: ]
+// LOADCFG-NEXT: DynamicRelocations [
+// LOADCFG-NEXT: Version: 0x1
+// LOADCFG-NEXT: Arm64X [
+// LOADCFG-NEXT: Entry [
+// LOADCFG-NEXT: RVA: 0x7C
+// LOADCFG-NEXT: Type: VALUE
+// LOADCFG-NEXT: Size: 0x2
+// LOADCFG-NEXT: Value: 0x8664
+// LOADCFG-NEXT: ]
+// LOADCFG-NEXT: Entry [
+// LOADCFG-NEXT: RVA: 0x150
+// LOADCFG-NEXT: Type: VALUE
+// LOADCFG-NEXT: Size: 0x4
+// LOADCFG-NEXT: Value: 0x1140
+// LOADCFG-NEXT: ]
+// LOADCFG-NEXT: Entry [
+// LOADCFG-NEXT: RVA: 0x154
+// LOADCFG-NEXT: Type: VALUE
+// LOADCFG-NEXT: Size: 0x4
+// LOADCFG-NEXT: Value: 0x140
+// LOADCFG-NEXT: ]
+// LOADCFG-NEXT: ]
+// LOADCFG-NEXT: ]
+// LOADCFG-NEXT: }
// RUN: llvm-readobj --coff-basereloc out-hyb.dll | FileCheck --check-prefix=BASERELOC %s
// BASERELOC: BaseReloc [
More information about the llvm-commits
mailing list