Skip to content

Commit 1c0185e

Browse files
committed
[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.
1 parent 60d2060 commit 1c0185e

File tree

4 files changed

+58
-14
lines changed

4 files changed

+58
-14
lines changed

lld/COFF/Chunks.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,6 +1150,10 @@ uint32_t ImportThunkChunkARM64EC::extendRanges() {
11501150
return sizeof(arm64Thunk) - sizeof(uint32_t);
11511151
}
11521152

1153+
uint64_t Arm64XRelocVal::get() const {
1154+
return (sym ? sym->getRVA() : 0) + value;
1155+
}
1156+
11531157
size_t Arm64XDynamicRelocEntry::getSize() const {
11541158
switch (type) {
11551159
case IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE:
@@ -1169,13 +1173,13 @@ void Arm64XDynamicRelocEntry::writeTo(uint8_t *buf) const {
11691173
*out |= ((bit_width(size) - 1) << 14); // Encode the size.
11701174
switch (size) {
11711175
case 2:
1172-
out[1] = value;
1176+
out[1] = value.get();
11731177
break;
11741178
case 4:
1175-
*reinterpret_cast<ulittle32_t *>(out + 1) = value;
1179+
*reinterpret_cast<ulittle32_t *>(out + 1) = value.get();
11761180
break;
11771181
case 8:
1178-
*reinterpret_cast<ulittle64_t *>(out + 1) = value;
1182+
*reinterpret_cast<ulittle64_t *>(out + 1) = value.get();
11791183
break;
11801184
default:
11811185
llvm_unreachable("invalid size");

lld/COFF/Chunks.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -835,18 +835,30 @@ class ECExportThunkChunk : public NonSectionCodeChunk {
835835
Defined *target;
836836
};
837837

838+
// ARM64X relocation value, potentially relative to a symbol.
839+
class Arm64XRelocVal {
840+
public:
841+
Arm64XRelocVal(int64_t value = 0) : value(value) {}
842+
Arm64XRelocVal(Defined *sym, int32_t offset = 0) : sym(sym), value(offset) {}
843+
uint64_t get() const;
844+
845+
private:
846+
Defined *sym = nullptr;
847+
uint64_t value;
848+
};
849+
838850
// ARM64X entry for dynamic relocations.
839851
class Arm64XDynamicRelocEntry {
840852
public:
841853
Arm64XDynamicRelocEntry(llvm::COFF::Arm64XFixupType type, uint8_t size,
842-
uint32_t offset, uint64_t value)
854+
uint32_t offset, Arm64XRelocVal value)
843855
: offset(offset), value(value), type(type), size(size) {}
844856

845857
size_t getSize() const;
846858
void writeTo(uint8_t *buf) const;
847859

848860
uint32_t offset;
849-
uint64_t value;
861+
Arm64XRelocVal value;
850862

851863
private:
852864
llvm::COFF::Arm64XFixupType type;
@@ -862,7 +874,7 @@ class DynamicRelocsChunk : public NonSectionChunk {
862874
void finalize();
863875

864876
void add(llvm::COFF::Arm64XFixupType type, uint8_t size, uint32_t offset,
865-
uint64_t value) {
877+
Arm64XRelocVal value) {
866878
arm64xRelocs.emplace_back(type, size, offset, value);
867879
}
868880

lld/COFF/Writer.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2582,18 +2582,17 @@ void Writer::createDynamicRelocs() {
25822582
coffHeaderOffset + offsetof(coff_file_header, Machine),
25832583
AMD64);
25842584

2585-
// Clear the load config directory.
2586-
// FIXME: Use the hybrid load config value instead.
2585+
// Set the hybrid load config to the EC load config.
25872586
ctx.dynamicRelocs->add(IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof(uint32_t),
25882587
dataDirOffset64 +
25892588
LOAD_CONFIG_TABLE * sizeof(data_directory) +
25902589
offsetof(data_directory, RelativeVirtualAddress),
2591-
0);
2590+
ctx.hybridSymtab->loadConfigSym);
25922591
ctx.dynamicRelocs->add(IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof(uint32_t),
25932592
dataDirOffset64 +
25942593
LOAD_CONFIG_TABLE * sizeof(data_directory) +
25952594
offsetof(data_directory, Size),
2596-
0);
2595+
ctx.hybridSymtab->loadConfigSize);
25972596
}
25982597

25992598
PartialSection *Writer::createPartialSection(StringRef name,

lld/test/COFF/arm64x-loadconfig.s

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,20 +87,49 @@
8787
// LOADCFG-NEXT: RVA: 0x150
8888
// LOADCFG-NEXT: Type: VALUE
8989
// LOADCFG-NEXT: Size: 0x4
90-
// LOADCFG-NEXT: Value: 0x0
90+
// LOADCFG-NEXT: Value: 0x1140
9191
// LOADCFG-NEXT: ]
9292
// LOADCFG-NEXT: Entry [
9393
// LOADCFG-NEXT: RVA: 0x154
9494
// LOADCFG-NEXT: Type: VALUE
9595
// LOADCFG-NEXT: Size: 0x4
96-
// LOADCFG-NEXT: Value: 0x0
96+
// LOADCFG-NEXT: Value: 0x140
9797
// LOADCFG-NEXT: ]
9898
// LOADCFG-NEXT: ]
9999
// LOADCFG-NEXT: ]
100100
// LOADCFG-NEXT: HybridObject {
101-
// LOADCFG-NEXT: Format: COFF-x86-64
102-
// LOADCFG-NEXT: Arch: x86_64
101+
// LOADCFG-NEXT: Format: COFF-ARM64EC
102+
// LOADCFG-NEXT: Arch: aarch64
103103
// LOADCFG-NEXT: AddressSize: 64bit
104+
// LOADCFG-NEXT: LoadConfig [
105+
// LOADCFG-NEXT: Size: 0x140
106+
// LOADCFG: CHPEMetadata [
107+
// LOADCFG-NEXT: Version: 0x2
108+
// LOADCFG: ]
109+
// LOADCFG-NEXT: DynamicRelocations [
110+
// LOADCFG-NEXT: Version: 0x1
111+
// LOADCFG-NEXT: Arm64X [
112+
// LOADCFG-NEXT: Entry [
113+
// LOADCFG-NEXT: RVA: 0x7C
114+
// LOADCFG-NEXT: Type: VALUE
115+
// LOADCFG-NEXT: Size: 0x2
116+
// LOADCFG-NEXT: Value: 0x8664
117+
// LOADCFG-NEXT: ]
118+
// LOADCFG-NEXT: Entry [
119+
// LOADCFG-NEXT: RVA: 0x150
120+
// LOADCFG-NEXT: Type: VALUE
121+
// LOADCFG-NEXT: Size: 0x4
122+
// LOADCFG-NEXT: Value: 0x1140
123+
// LOADCFG-NEXT: ]
124+
// LOADCFG-NEXT: Entry [
125+
// LOADCFG-NEXT: RVA: 0x154
126+
// LOADCFG-NEXT: Type: VALUE
127+
// LOADCFG-NEXT: Size: 0x4
128+
// LOADCFG-NEXT: Value: 0x140
129+
// LOADCFG-NEXT: ]
130+
// LOADCFG-NEXT: ]
131+
// LOADCFG-NEXT: ]
132+
// LOADCFG-NEXT: }
104133

105134
// RUN: llvm-readobj --coff-basereloc out-hyb.dll | FileCheck --check-prefix=BASERELOC %s
106135
// BASERELOC: BaseReloc [

0 commit comments

Comments
 (0)