-
Notifications
You must be signed in to change notification settings - Fork 12.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[LLD][COFF] Use EC load config for ARM64X relocations of load config directory #121337
base: main
Are you sure you want to change the base?
Conversation
…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.
@llvm/pr-subscribers-lld-coff @llvm/pr-subscribers-lld Author: Jacek Caban (cjacek) ChangesThis 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. Full diff: https://github.com/llvm/llvm-project/pull/121337.diff 4 Files Affected:
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 [
|
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.