Skip to content

Commit 805267a

Browse files
committed
[LLD][COFF] Add Support for ARM64EC Import Thunks
ARM64EC import thunks function similarly to regular ARM64 thunks but use a mangled name and perform the call through the auxiliary IAT.
1 parent 711278e commit 805267a

File tree

5 files changed

+64
-35
lines changed

5 files changed

+64
-35
lines changed

lld/COFF/Chunks.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -601,13 +601,17 @@ class ImportThunkChunkARM : public ImportThunkChunk {
601601

602602
class ImportThunkChunkARM64 : public ImportThunkChunk {
603603
public:
604-
explicit ImportThunkChunkARM64(COFFLinkerContext &ctx, Defined *s)
605-
: ImportThunkChunk(ctx, s) {
604+
explicit ImportThunkChunkARM64(COFFLinkerContext &ctx, Defined *s,
605+
MachineTypes machine)
606+
: ImportThunkChunk(ctx, s), machine(machine) {
606607
setAlignment(4);
607608
}
608609
size_t getSize() const override { return sizeof(importThunkARM64); }
609610
void writeTo(uint8_t *buf) const override;
610-
MachineTypes getMachine() const override { return ARM64; }
611+
MachineTypes getMachine() const override { return machine; }
612+
613+
private:
614+
MachineTypes machine;
611615
};
612616

613617
// ARM64EC __impchk_* thunk implementation.

lld/COFF/InputFiles.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,7 +1018,7 @@ ImportThunkChunk *ImportFile::makeImportThunk() {
10181018
case I386:
10191019
return make<ImportThunkChunkX86>(ctx, impSym);
10201020
case ARM64:
1021-
return make<ImportThunkChunkARM64>(ctx, impSym);
1021+
return make<ImportThunkChunkARM64>(ctx, impSym, ARM64);
10221022
case ARMNT:
10231023
return make<ImportThunkChunkARM>(ctx, impSym);
10241024
}
@@ -1109,7 +1109,14 @@ void ImportFile::parse() {
11091109
} else {
11101110
thunkSym = ctx.symtab.addImportThunk(
11111111
name, impSym, make<ImportThunkChunkX64>(ctx, impSym));
1112-
// FIXME: Add aux IAT symbols.
1112+
1113+
if (std::optional<std::string> mangledName =
1114+
getArm64ECMangledFunctionName(name)) {
1115+
StringRef auxThunkName = saver().save(*mangledName);
1116+
auxThunkSym = ctx.symtab.addImportThunk(
1117+
auxThunkName, impECSym,
1118+
make<ImportThunkChunkARM64>(ctx, impECSym, ARM64EC));
1119+
}
11131120

11141121
StringRef impChkName = saver().save("__impchk_" + name);
11151122
impchkThunk = make<ImportThunkChunkARM64EC>(this);

lld/COFF/InputFiles.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,7 @@ class ImportFile : public InputFile {
365365
// Auxiliary IAT symbol and chunk on ARM64EC.
366366
DefinedImportData *impECSym = nullptr;
367367
Chunk *auxLocation = nullptr;
368+
Symbol *auxThunkSym = nullptr;
368369

369370
// We want to eliminate dllimported symbols if no one actually refers to them.
370371
// These "Live" bits are used to keep track of which import library members

lld/COFF/Writer.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1252,14 +1252,22 @@ void Writer::appendImportThunks() {
12521252
if (!file->live)
12531253
continue;
12541254

1255-
if (!file->thunkSym)
1256-
continue;
1255+
if (file->thunkSym) {
1256+
if (!isa<DefinedImportThunk>(file->thunkSym))
1257+
fatal(toString(ctx, *file->thunkSym) + " was replaced");
1258+
auto *chunk = cast<DefinedImportThunk>(file->thunkSym)->getChunk();
1259+
if (chunk->live)
1260+
textSec->addChunk(chunk);
1261+
}
1262+
1263+
if (file->auxThunkSym) {
1264+
if (!isa<DefinedImportThunk>(file->auxThunkSym))
1265+
fatal(toString(ctx, *file->auxThunkSym) + " was replaced");
1266+
auto *chunk = cast<DefinedImportThunk>(file->auxThunkSym)->getChunk();
1267+
if (chunk->live)
1268+
textSec->addChunk(chunk);
1269+
}
12571270

1258-
if (!isa<DefinedImportThunk>(file->thunkSym))
1259-
fatal(toString(ctx, *file->thunkSym) + " was replaced");
1260-
DefinedImportThunk *thunk = cast<DefinedImportThunk>(file->thunkSym);
1261-
if (thunk->getChunk()->live)
1262-
textSec->addChunk(thunk->getChunk());
12631271
if (file->impchkThunk)
12641272
textSec->addChunk(file->impchkThunk);
12651273
}

lld/test/COFF/arm64ec-import.test

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -39,33 +39,40 @@ RUN: llvm-objdump -d out2.dll | FileCheck --check-prefix=DISASM %s
3939

4040
DISASM: 180001000: 52800000 mov w0, #0x0 // =0
4141
DISASM-NEXT: 180001004: d65f03c0 ret
42-
DISASM-NEXT: 180001008: d000000b adrp x11, 0x180003000
43-
DISASM-NEXT: 18000100c: f940056b ldr x11, [x11, #0x8]
44-
DISASM-NEXT: 180001010: 9000000a adrp x10, 0x180001000 <.text>
45-
DISASM-NEXT: 180001014: 9101114a add x10, x10, #0x44
46-
DISASM-NEXT: 180001018: 17fffffa b 0x180001000 <.text>
47-
DISASM-NEXT: 18000101c: d000000b adrp x11, 0x180003000
48-
DISASM-NEXT: 180001020: f940096b ldr x11, [x11, #0x10]
49-
DISASM-NEXT: 180001024: f0ffffea adrp x10, 0x180000000
50-
DISASM-NEXT: 180001028: 9100014a add x10, x10, #0x0
51-
DISASM-NEXT: 18000102c: 17fffff5 b 0x180001000 <.text>
52-
DISASM-NEXT: 180001030: d000000b adrp x11, 0x180003000
53-
DISASM-NEXT: 180001034: f940116b ldr x11, [x11, #0x20]
54-
DISASM-NEXT: 180001038: 9000000a adrp x10, 0x180001000 <.text>
55-
DISASM-NEXT: 18000103c: 9101314a add x10, x10, #0x4c
56-
DISASM-NEXT: 180001040: 17fffff0 b 0x180001000 <.text>
57-
DISASM-NEXT: 180001044: 52800020 mov w0, #0x1 // =1
58-
DISASM-NEXT: 180001048: d65f03c0 ret
59-
DISASM-NEXT: 18000104c: 52800040 mov w0, #0x2 // =2
60-
DISASM-NEXT: 180001050: d65f03c0 ret
42+
DISASM-NEXT: 180001008: 90000030 adrp x16, 0x180005000
43+
DISASM-NEXT: 18000100c: f9400610 ldr x16, [x16, #0x8]
44+
DISASM-NEXT: 180001010: d61f0200 br x16
45+
DISASM-NEXT: 180001014: d000000b adrp x11, 0x180003000
46+
DISASM-NEXT: 180001018: f940056b ldr x11, [x11, #0x8]
47+
DISASM-NEXT: 18000101c: 9000000a adrp x10, 0x180001000 <.text>
48+
DISASM-NEXT: 180001020: 9101714a add x10, x10, #0x5c
49+
DISASM-NEXT: 180001024: 17fffff7 b 0x180001000 <.text>
50+
DISASM-NEXT: 180001028: d000000b adrp x11, 0x180003000
51+
DISASM-NEXT: 18000102c: f940096b ldr x11, [x11, #0x10]
52+
DISASM-NEXT: 180001030: f0ffffea adrp x10, 0x180000000
53+
DISASM-NEXT: 180001034: 9100014a add x10, x10, #0x0
54+
DISASM-NEXT: 180001038: 17fffff2 b 0x180001000 <.text>
55+
DISASM-NEXT: 18000103c: 90000030 adrp x16, 0x180005000
56+
DISASM-NEXT: 180001040: f9401210 ldr x16, [x16, #0x20]
57+
DISASM-NEXT: 180001044: d61f0200 br x16
58+
DISASM-NEXT: 180001048: d000000b adrp x11, 0x180003000
59+
DISASM-NEXT: 18000104c: f940116b ldr x11, [x11, #0x20]
60+
DISASM-NEXT: 180001050: 9000000a adrp x10, 0x180001000 <.text>
61+
DISASM-NEXT: 180001054: 9101914a add x10, x10, #0x64
62+
DISASM-NEXT: 180001058: 17ffffea b 0x180001000 <.text>
63+
DISASM-NEXT: 18000105c: 52800020 mov w0, #0x1 // =1
64+
DISASM-NEXT: 180001060: d65f03c0 ret
65+
DISASM-NEXT: 180001064: 52800040 mov w0, #0x2 // =2
66+
DISASM-NEXT: 180001068: d65f03c0 ret
6167
DISASM-NEXT: ...
6268
DISASM-NEXT: 180002000: ff 25 02 10 00 00 jmpq *0x1002(%rip) # 0x180003008
6369

6470
RUN: llvm-readobj --hex-dump=.test out.dll | FileCheck --check-prefix=TESTSEC %s
6571
RUN: llvm-readobj --hex-dump=.test out2.dll | FileCheck --check-prefix=TESTSEC %s
6672
TESTSEC: 0x180007000 08500000 00300000 10500000 20500000
6773
TESTSEC-NEXT: 0x180007010 08300000 00500000 10300000 20300000
68-
TESTSEC-NEXT: 0x180007020 08100000 1c100000 00200000
74+
TESTSEC-NEXT: 0x180007020 14100000 28100000 00200000 08100000
75+
TESTSEC-NEXT: 0x180007030 3c100000
6976

7077
RUN: llvm-readobj --headers out.dll | FileCheck -check-prefix=HEADERS %s
7178
HEADERS: LoadConfigTableRVA: 0x4010
@@ -76,9 +83,9 @@ RUN: llvm-readobj --coff-load-config out.dll | FileCheck -check-prefix=LOADCONFI
7683
LOADCONFIG: AuxiliaryIAT: 0x5000
7784

7885
RUN: llvm-readobj --hex-dump=.rdata out.dll | FileCheck -check-prefix=RDATA %s
79-
RDATA: 0x180005000 00000000 00000000 08100080 01000000
80-
RDATA-NEXT: 0x180005010 1c100080 01000000 00000000 00000000
81-
RDATA-NEXT: 0x180005020 30100080 01000000 00000000 00000000
86+
RDATA: 0x180005000 00000000 00000000 14100080 01000000
87+
RDATA-NEXT: 0x180005010 28100080 01000000 00000000 00000000
88+
RDATA-NEXT: 0x180005020 48100080 01000000 00000000 00000000
8289

8390
RUN: llvm-readobj --coff-basereloc out.dll | FileCheck -check-prefix=BASERELOC %s
8491
BASERELOC: BaseReloc [
@@ -110,6 +117,8 @@ arm64ec_data_sym:
110117
.rva __impchk_func
111118
.rva __impchk_func2
112119
.rva func
120+
.rva "#func"
121+
.rva "#t2func"
113122

114123
#--- icall.s
115124
.text

0 commit comments

Comments
 (0)