Skip to content

Commit f8f01b5

Browse files
authored
[LLD][COFF] Support marking sections as x86_64 code in ARM64EC object files (llvm#135280)
On ARM64EC, the `IMAGE_SCN_GPREL` flag is repurposed to indicate that section code is x86_64. This enables embedding x86_64 code within ARM64EC object files. MSVC uses this for export thunks in .exp files.
1 parent cd85f5d commit f8f01b5

File tree

3 files changed

+54
-2
lines changed

3 files changed

+54
-2
lines changed

lld/COFF/Chunks.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,16 @@ SectionChunk::SectionChunk(ObjFile *f, const coff_section *h, Kind k)
6161
live = true;
6262
}
6363

64+
MachineTypes SectionChunk::getMachine() const {
65+
MachineTypes machine = file->getMachineType();
66+
// On ARM64EC, the IMAGE_SCN_GPREL flag is repurposed to indicate that section
67+
// code is x86_64. This enables embedding x86_64 code within ARM64EC object
68+
// files. MSVC uses this for export thunks in .exp files.
69+
if (isArm64EC(machine) && (header->Characteristics & IMAGE_SCN_GPREL))
70+
machine = AMD64;
71+
return machine;
72+
}
73+
6474
// SectionChunk is one of the most frequently allocated classes, so it is
6575
// important to keep it as compact as possible. As of this writing, the number
6676
// below is the size of this class on x64 platforms.

lld/COFF/Chunks.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,8 +253,7 @@ class SectionChunk : public Chunk {
253253
size_t getSize() const { return header->SizeOfRawData; }
254254
ArrayRef<uint8_t> getContents() const;
255255
void writeTo(uint8_t *buf) const;
256-
257-
MachineTypes getMachine() const { return file->getMachineType(); }
256+
MachineTypes getMachine() const;
258257

259258
// Defend against unsorted relocations. This may be overly conservative.
260259
void sortRelocations();

lld/test/COFF/arm64ec-x86-sec.yaml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# REQUIRES: aarch64, x86
2+
3+
# RUN: yaml2obj %s -o %t.obj
4+
# RUN: llvm-mc -filetype=obj -triple=arm64ec-windows %S/Inputs/loadconfig-arm64ec.s -o %t-loadcfg.obj
5+
# RUN: lld-link -machine:arm64ec -dll -noentry %t.obj %t-loadcfg.obj -out:%t.dll
6+
# RUN: llvm-objdump -d %t.dll | FileCheck %s
7+
8+
# CHECK: Disassembly of section .text:
9+
# CHECK-EMPTY:
10+
# CHECK-NEXT: 0000000180001000 <.text>:
11+
# CHECK-NEXT: 180001000: d503201f nop
12+
# CHECK-NEXT: 180001004: d65f03c0 ret
13+
# CHECK-NEXT: ...
14+
# CHECK-NEXT: 180002000: e9 ff ef ff ff jmp 0x180001004 <.text+0x4>
15+
# CHECK-NEXT: 180002005: c3 retq
16+
# CHECK-NEXT: 180002006: cc int3
17+
18+
--- !COFF
19+
header:
20+
Machine: IMAGE_FILE_MACHINE_ARM64EC
21+
Characteristics: [ ]
22+
sections:
23+
- Name: .text
24+
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
25+
Alignment: 4
26+
SectionData: 1F2003D5C0035FD6
27+
SizeOfRawData: 8
28+
- Name: .text
29+
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_GPREL, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
30+
Alignment: 16
31+
SectionData: E900000000C3CC
32+
SizeOfRawData: 7
33+
Relocations:
34+
- VirtualAddress: 1
35+
SymbolName: func
36+
Type: IMAGE_REL_ARM64_PAGEBASE_REL21 # interpreted as IMAGE_REL_AMD64_REL32
37+
symbols:
38+
- Name: func
39+
Value: 4
40+
SectionNumber: 1
41+
SimpleType: IMAGE_SYM_TYPE_NULL
42+
ComplexType: IMAGE_SYM_DTYPE_NULL
43+
StorageClass: IMAGE_SYM_CLASS_EXTERNAL

0 commit comments

Comments
 (0)