Skip to content

Commit e7f8cac

Browse files
committed
[LLD][COFF] Use EC load config in load config directory ARM64X relocations
1 parent 990b779 commit e7f8cac

File tree

4 files changed

+56
-14
lines changed

4 files changed

+56
-14
lines changed

lld/COFF/Chunks.cpp

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

1152+
uint64_t Arm64XRelocVal::get() const {
1153+
return (sym ? sym->getRVA() : 0) + value;
1154+
}
1155+
11521156
size_t Arm64XDynamicRelocEntry::getSize() const {
11531157
switch (type) {
11541158
case IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE:
@@ -1168,13 +1172,13 @@ void Arm64XDynamicRelocEntry::writeTo(uint8_t *buf) const {
11681172
*out |= ((bit_width(size) - 1) << 14); // Encode the size.
11691173
switch (size) {
11701174
case 2:
1171-
out[1] = value;
1175+
out[1] = value.get();
11721176
break;
11731177
case 4:
1174-
*reinterpret_cast<ulittle32_t *>(out + 1) = value;
1178+
*reinterpret_cast<ulittle32_t *>(out + 1) = value.get();
11751179
break;
11761180
case 8:
1177-
*reinterpret_cast<ulittle64_t *>(out + 1) = value;
1181+
*reinterpret_cast<ulittle64_t *>(out + 1) = value.get();
11781182
break;
11791183
default:
11801184
llvm_unreachable("invalid size");

lld/COFF/Chunks.h

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

838+
class Arm64XRelocVal {
839+
public:
840+
Arm64XRelocVal(int64_t value = 0) : value(value) {}
841+
Arm64XRelocVal(Defined *sym, int32_t offset = 0) : sym(sym), value(offset) {}
842+
uint64_t get() const;
843+
844+
private:
845+
Defined *sym = nullptr;
846+
uint64_t value;
847+
};
848+
838849
// ARM64X entry for dynamic relocations.
839850
class Arm64XDynamicRelocEntry {
840851
public:
841852
Arm64XDynamicRelocEntry(llvm::COFF::Arm64XFixupType type, uint8_t size,
842-
uint32_t offset, uint64_t value)
853+
uint32_t offset, Arm64XRelocVal value)
843854
: offset(offset), value(value), type(type), size(size) {}
844855

845856
size_t getSize() const;
846857
void writeTo(uint8_t *buf) const;
847858

848859
uint32_t offset;
849-
uint64_t value;
860+
Arm64XRelocVal value;
850861

851862
private:
852863
llvm::COFF::Arm64XFixupType type;
@@ -862,7 +873,7 @@ class DynamicRelocsChunk : public NonSectionChunk {
862873
void finalize();
863874

864875
void add(llvm::COFF::Arm64XFixupType type, uint8_t size, uint32_t offset,
865-
uint64_t value) {
876+
Arm64XRelocVal value) {
866877
arm64xRelocs.emplace_back(type, size, offset, value);
867878
}
868879

lld/COFF/Writer.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2582,18 +2582,16 @@ 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.
25872585
ctx.dynamicRelocs->add(IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof(uint32_t),
25882586
dataDirOffset64 +
25892587
LOAD_CONFIG_TABLE * sizeof(data_directory) +
25902588
offsetof(data_directory, RelativeVirtualAddress),
2591-
0);
2589+
ctx.hybridSymtab->loadConfigSym);
25922590
ctx.dynamicRelocs->add(IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof(uint32_t),
25932591
dataDirOffset64 +
25942592
LOAD_CONFIG_TABLE * sizeof(data_directory) +
25952593
offsetof(data_directory, Size),
2596-
0);
2594+
ctx.hybridSymtab->loadConfigSize);
25972595
}
25982596

25992597
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
@@ -73,20 +73,49 @@
7373
// LOADCFG-NEXT: RVA: 0x150
7474
// LOADCFG-NEXT: Type: VALUE
7575
// LOADCFG-NEXT: Size: 0x4
76-
// LOADCFG-NEXT: Value: 0x0
76+
// LOADCFG-NEXT: Value: 0x1140
7777
// LOADCFG-NEXT: ]
7878
// LOADCFG-NEXT: Entry [
7979
// LOADCFG-NEXT: RVA: 0x154
8080
// LOADCFG-NEXT: Type: VALUE
8181
// LOADCFG-NEXT: Size: 0x4
82-
// LOADCFG-NEXT: Value: 0x0
82+
// LOADCFG-NEXT: Value: 0x140
8383
// LOADCFG-NEXT: ]
8484
// LOADCFG-NEXT: ]
8585
// LOADCFG-NEXT: ]
8686
// LOADCFG-NEXT: HybridObject {
87-
// LOADCFG-NEXT: Format: COFF-x86-64
88-
// LOADCFG-NEXT: Arch: x86_64
87+
// LOADCFG-NEXT: Format: COFF-ARM64EC
88+
// LOADCFG-NEXT: Arch: aarch64
8989
// LOADCFG-NEXT: AddressSize: 64bit
90+
// LOADCFG-NEXT: LoadConfig [
91+
// LOADCFG-NEXT: Size: 0x140
92+
// LOADCFG: CHPEMetadata [
93+
// LOADCFG-NEXT: Version: 0x2
94+
// LOADCFG: ]
95+
// LOADCFG-NEXT: DynamicRelocations [
96+
// LOADCFG-NEXT: Version: 0x1
97+
// LOADCFG-NEXT: Arm64X [
98+
// LOADCFG-NEXT: Entry [
99+
// LOADCFG-NEXT: RVA: 0x7C
100+
// LOADCFG-NEXT: Type: VALUE
101+
// LOADCFG-NEXT: Size: 0x2
102+
// LOADCFG-NEXT: Value: 0x8664
103+
// LOADCFG-NEXT: ]
104+
// LOADCFG-NEXT: Entry [
105+
// LOADCFG-NEXT: RVA: 0x150
106+
// LOADCFG-NEXT: Type: VALUE
107+
// LOADCFG-NEXT: Size: 0x4
108+
// LOADCFG-NEXT: Value: 0x1140
109+
// LOADCFG-NEXT: ]
110+
// LOADCFG-NEXT: Entry [
111+
// LOADCFG-NEXT: RVA: 0x154
112+
// LOADCFG-NEXT: Type: VALUE
113+
// LOADCFG-NEXT: Size: 0x4
114+
// LOADCFG-NEXT: Value: 0x140
115+
// LOADCFG-NEXT: ]
116+
// LOADCFG-NEXT: ]
117+
// LOADCFG-NEXT: ]
118+
// LOADCFG-NEXT: }
90119

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

0 commit comments

Comments
 (0)