Skip to content

Commit 66a3aa5

Browse files
committed
[LLD][COFF] Initial support for ARM64EC importlibs.
Use demangled symbol name for __imp_ symbols and define demangled thunk symbol as AMD64 thunk.
1 parent 46e42d4 commit 66a3aa5

File tree

2 files changed

+86
-4
lines changed

2 files changed

+86
-4
lines changed

lld/COFF/InputFiles.cpp

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
2626
#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
2727
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
28+
#include "llvm/IR/Mangler.h"
2829
#include "llvm/LTO/LTO.h"
2930
#include "llvm/Object/Binary.h"
3031
#include "llvm/Object/COFF.h"
@@ -1019,9 +1020,16 @@ void ImportFile::parse() {
10191020

10201021
// Read names and create an __imp_ symbol.
10211022
StringRef buf = mb.getBuffer().substr(sizeof(*hdr));
1022-
StringRef name = saver().save(buf.split('\0').first);
1023+
StringRef nameBuf = buf.split('\0').first, name;
1024+
if (isArm64EC(hdr->Machine)) {
1025+
if (std::optional<std::string> demangledName =
1026+
getArm64ECDemangledFunctionName(nameBuf))
1027+
name = saver().save(*demangledName);
1028+
}
1029+
if (name.empty())
1030+
name = saver().save(nameBuf);
10231031
StringRef impName = saver().save("__imp_" + name);
1024-
buf = buf.substr(name.size() + 1);
1032+
buf = buf.substr(nameBuf.size() + 1);
10251033
dllName = buf.split('\0').first;
10261034
StringRef extName;
10271035
switch (hdr->getNameType()) {
@@ -1058,8 +1066,14 @@ void ImportFile::parse() {
10581066
// If type is function, we need to create a thunk which jump to an
10591067
// address pointed by the __imp_ symbol. (This allows you to call
10601068
// DLL functions just like regular non-DLL functions.)
1061-
if (hdr->getType() == llvm::COFF::IMPORT_CODE)
1062-
thunkSym = ctx.symtab.addImportThunk(name, impSym, hdr->Machine);
1069+
if (hdr->getType() == llvm::COFF::IMPORT_CODE) {
1070+
if (ctx.config.machine != ARM64EC) {
1071+
thunkSym = ctx.symtab.addImportThunk(name, impSym, hdr->Machine);
1072+
} else {
1073+
thunkSym = ctx.symtab.addImportThunk(name, impSym, AMD64);
1074+
// FIXME: Add aux IAT symbols.
1075+
}
1076+
}
10631077
}
10641078

10651079
BitcodeFile::BitcodeFile(COFFLinkerContext &ctx, MemoryBufferRef mb,

lld/test/COFF/arm64ec-import.test

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
REQUIRES: aarch64, x86
2+
RUN: split-file %s %t.dir && cd %t.dir
3+
4+
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows test.s -o test.obj
5+
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows %S/Inputs/loadconfig-arm64ec.s -o loadconfig-arm64ec.obj
6+
RUN: llvm-lib -machine:arm64ec -def:test.def -out:test-arm64ec.lib
7+
RUN: llvm-lib -machine:arm64ec -def:test2.def -out:test2-arm64ec.lib
8+
RUN: llvm-lib -machine:x64 -def:test.def -out:test-x86_64.lib
9+
10+
Link using ARM64EC import library:
11+
RUN: lld-link -machine:arm64ec -dll -noentry -out:out.dll loadconfig-arm64ec.obj \
12+
RUN: test.obj test-arm64ec.lib test2-arm64ec.lib
13+
14+
Link using x86_64 import library:
15+
RUN: lld-link -machine:arm64ec -dll -noentry -out:out2.dll loadconfig-arm64ec.obj \
16+
RUN: test.obj test-x86_64.lib test2-arm64ec.lib
17+
18+
RUN: llvm-readobj --coff-imports out.dll | FileCheck --check-prefix=IMPORTS %s
19+
RUN: llvm-readobj --coff-imports out2.dll | FileCheck --check-prefix=IMPORTS %s
20+
IMPORTS: Import {
21+
IMPORTS-NEXT: Name: test.dll
22+
IMPORTS-NEXT: ImportLookupTableRVA:
23+
IMPORTS-NEXT: ImportAddressTableRVA: 0x2258
24+
IMPORTS-NEXT: Symbol: data (0)
25+
IMPORTS-NEXT: Symbol: func (0)
26+
IMPORTS-NEXT: Symbol: func2 (0)
27+
IMPORTS-NEXT: }
28+
IMPORTS-NEXT: Import {
29+
IMPORTS-NEXT: Name: test2.dll
30+
IMPORTS-NEXT: ImportLookupTableRVA:
31+
IMPORTS-NEXT: ImportAddressTableRVA: 0x2278
32+
IMPORTS-NEXT: Symbol: t2func (0)
33+
IMPORTS-NEXT: }
34+
35+
RUN: llvm-objdump -d out.dll | FileCheck --check-prefix=DISASM %s
36+
RUN: llvm-objdump -d out2.dll | FileCheck --check-prefix=DISASM %s
37+
38+
DISASM: 0000000180001000 <.text>:
39+
DISASM-NEXT: 180001000: ff 25 5a 12 00 00 jmpq *0x125a(%rip) # 0x180002260
40+
41+
RUN: llvm-readobj --hex-dump=.test out.dll | FileCheck --check-prefix=TESTSEC %s
42+
RUN: llvm-readobj --hex-dump=.test out2.dll | FileCheck --check-prefix=TESTSEC %s
43+
TESTSEC: 0x180004000 60220000 58220000 68220000 78220000
44+
TESTSEC-NEXT: 0x180004010 00100000
45+
46+
#--- test.s
47+
.section .test, "r"
48+
.globl arm64ec_data_sym
49+
.p2align 2, 0x0
50+
arm64ec_data_sym:
51+
.rva __imp_func
52+
.rva __imp_data
53+
.rva __imp_func2
54+
.rva __imp_t2func
55+
.rva func
56+
57+
#--- test.def
58+
NAME test.dll
59+
EXPORTS
60+
data DATA
61+
func
62+
func2
63+
unused_func
64+
65+
#--- test2.def
66+
NAME test2.dll
67+
EXPORTS
68+
t2func

0 commit comments

Comments
 (0)