Skip to content

Commit 1c9a99f

Browse files
cjacekSquallATF
authored andcommitted
[LLD][COFF] Add support for MinGW auto-export on ARM64X (llvm#125862)
Export all symbols from both EC and native symbol tables. If an explicit export is present in either symbol table, auto-export is disabled for both.
1 parent c654c7a commit 1c9a99f

File tree

4 files changed

+129
-34
lines changed

4 files changed

+129
-34
lines changed

lld/COFF/Driver.cpp

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1388,43 +1388,46 @@ void LinkerDriver::maybeExportMinGWSymbols(const opt::InputArgList &args) {
13881388
if (!ctx.config.dll)
13891389
return;
13901390

1391-
if (!ctx.symtab.exports.empty())
1391+
if (ctx.symtab.hadExplicitExports ||
1392+
(ctx.hybridSymtab && ctx.hybridSymtab->hadExplicitExports))
13921393
return;
13931394
if (args.hasArg(OPT_exclude_all_symbols))
13941395
return;
13951396
}
13961397

1397-
AutoExporter exporter(ctx, excludedSymbols);
1398+
ctx.forEachSymtab([&](SymbolTable &symtab) {
1399+
AutoExporter exporter(symtab, excludedSymbols);
13981400

1399-
for (auto *arg : args.filtered(OPT_wholearchive_file))
1400-
if (std::optional<StringRef> path = findFile(arg->getValue()))
1401-
exporter.addWholeArchive(*path);
1401+
for (auto *arg : args.filtered(OPT_wholearchive_file))
1402+
if (std::optional<StringRef> path = findFile(arg->getValue()))
1403+
exporter.addWholeArchive(*path);
14021404

1403-
for (auto *arg : args.filtered(OPT_exclude_symbols)) {
1404-
SmallVector<StringRef, 2> vec;
1405-
StringRef(arg->getValue()).split(vec, ',');
1406-
for (StringRef sym : vec)
1407-
exporter.addExcludedSymbol(ctx.symtab.mangle(sym));
1408-
}
1405+
for (auto *arg : args.filtered(OPT_exclude_symbols)) {
1406+
SmallVector<StringRef, 2> vec;
1407+
StringRef(arg->getValue()).split(vec, ',');
1408+
for (StringRef sym : vec)
1409+
exporter.addExcludedSymbol(symtab.mangle(sym));
1410+
}
14091411

1410-
ctx.symtab.forEachSymbol([&](Symbol *s) {
1411-
auto *def = dyn_cast<Defined>(s);
1412-
if (!exporter.shouldExport(def))
1413-
return;
1412+
symtab.forEachSymbol([&](Symbol *s) {
1413+
auto *def = dyn_cast<Defined>(s);
1414+
if (!exporter.shouldExport(def))
1415+
return;
14141416

1415-
if (!def->isGCRoot) {
1416-
def->isGCRoot = true;
1417-
ctx.config.gcroot.push_back(def);
1418-
}
1417+
if (!def->isGCRoot) {
1418+
def->isGCRoot = true;
1419+
ctx.config.gcroot.push_back(def);
1420+
}
14191421

1420-
Export e;
1421-
e.name = def->getName();
1422-
e.sym = def;
1423-
if (Chunk *c = def->getChunk())
1424-
if (!(c->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE))
1425-
e.data = true;
1426-
s->isUsedInRegularObj = true;
1427-
ctx.symtab.exports.push_back(e);
1422+
Export e;
1423+
e.name = def->getName();
1424+
e.sym = def;
1425+
if (Chunk *c = def->getChunk())
1426+
if (!(c->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE))
1427+
e.data = true;
1428+
s->isUsedInRegularObj = true;
1429+
symtab.exports.push_back(e);
1430+
});
14281431
});
14291432
}
14301433

lld/COFF/MinGW.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,8 @@ using namespace lld;
2525
using namespace lld::coff;
2626

2727
AutoExporter::AutoExporter(
28-
COFFLinkerContext &ctx,
29-
const llvm::DenseSet<StringRef> &manualExcludeSymbols)
30-
: manualExcludeSymbols(manualExcludeSymbols), ctx(ctx) {
28+
SymbolTable &symtab, const llvm::DenseSet<StringRef> &manualExcludeSymbols)
29+
: manualExcludeSymbols(manualExcludeSymbols), symtab(symtab) {
3130
excludeLibs = {
3231
"libgcc",
3332
"libgcc_s",
@@ -89,7 +88,7 @@ AutoExporter::AutoExporter(
8988
"_NULL_THUNK_DATA",
9089
};
9190

92-
if (ctx.config.machine == I386) {
91+
if (symtab.machine == I386) {
9392
excludeSymbols = {
9493
"__NULL_IMPORT_DESCRIPTOR",
9594
"__pei386_runtime_relocator",
@@ -156,7 +155,7 @@ bool AutoExporter::shouldExport(Defined *sym) const {
156155
return false;
157156

158157
// If a corresponding __imp_ symbol exists and is defined, don't export it.
159-
if (ctx.symtab.find(("__imp_" + sym->getName()).str()))
158+
if (symtab.find(("__imp_" + sym->getName()).str()))
160159
return false;
161160

162161
// Check that file is non-null before dereferencing it, symbols not

lld/COFF/MinGW.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class COFFLinkerContext;
2525
// symbols for MinGW.
2626
class AutoExporter {
2727
public:
28-
AutoExporter(COFFLinkerContext &ctx,
28+
AutoExporter(SymbolTable &symtab,
2929
const llvm::DenseSet<StringRef> &manualExcludeSymbols);
3030

3131
void addWholeArchive(StringRef path);
@@ -42,7 +42,7 @@ class AutoExporter {
4242
bool shouldExport(Defined *sym) const;
4343

4444
private:
45-
COFFLinkerContext &ctx;
45+
SymbolTable &symtab;
4646
};
4747

4848
void writeDefFile(COFFLinkerContext &, StringRef name,

lld/test/COFF/arm64x-export-all.s

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// REQUIRES: aarch64
2+
3+
// RUN: llvm-mc -filetype=obj -triple=aarch64-windows %s -o %t.arm64.obj
4+
// RUN: llvm-mc -filetype=obj -triple=arm64ec-windows %s -o %t.arm64ec.obj
5+
// RUN: llvm-mc -filetype=obj -triple=arm64ec-windows %S/Inputs/loadconfig-arm64ec.s -o %t-loadconfig-arm64ec.obj
6+
// RUN: llvm-mc -filetype=obj -triple=aarch64-windows %S/Inputs/loadconfig-arm64.s -o %t-loadconfig-arm64.obj
7+
8+
// Check that all symbols are exported in both EC and native views.
9+
10+
// RUN: lld-link -machine:arm64x -lldmingw -dll -noentry -out:%t.dll %t.arm64.obj %t.arm64ec.obj %t-loadconfig-arm64.obj %t-loadconfig-arm64ec.obj
11+
12+
// RUN: llvm-readobj --coff-exports %t.dll | FileCheck --check-prefix=EXP %s
13+
// EXP: Format: COFF-ARM64X
14+
// EXP-NEXT: Arch: aarch64
15+
// EXP-NEXT: AddressSize: 64bit
16+
// EXP-NEXT: Export {
17+
// EXP-NEXT: Ordinal: 1
18+
// EXP-NEXT: Name: _load_config_used
19+
// EXP-NEXT: RVA:
20+
// EXP-NEXT: }
21+
// EXP-NEXT: Export {
22+
// EXP-NEXT: Ordinal: 2
23+
// EXP-NEXT: Name: sym
24+
// EXP-NEXT: RVA: 0x2000
25+
// EXP-NEXT: }
26+
// EXP-NEXT: Export {
27+
// EXP-NEXT: Ordinal: 3
28+
// EXP-NEXT: Name: sym2
29+
// EXP-NEXT: RVA: 0x2004
30+
// EXP-NEXT: }
31+
// EXP-NEXT: HybridObject {
32+
// EXP-NEXT: Format: COFF-ARM64EC
33+
// EXP-NEXT: Arch: aarch64
34+
// EXP-NEXT: AddressSize: 64bit
35+
// EXP-NEXT: Export {
36+
// EXP-NEXT: Ordinal: 1
37+
// EXP-NEXT: Name: __chpe_metadata
38+
// EXP-NEXT: RVA:
39+
// EXP-NEXT: }
40+
// EXP-NEXT: Export {
41+
// EXP-NEXT: Ordinal: 2
42+
// EXP-NEXT: Name: __os_arm64x_dispatch_icall
43+
// EXP-NEXT: RVA: 0x12B0
44+
// EXP-NEXT: }
45+
// EXP-NEXT: Export {
46+
// EXP-NEXT: Ordinal: 3
47+
// EXP-NEXT: Name: __os_arm64x_dispatch_ret
48+
// EXP-NEXT: RVA:
49+
// EXP-NEXT: }
50+
// EXP-NEXT: Export {
51+
// EXP-NEXT: Ordinal: 4
52+
// EXP-NEXT: Name: _load_config_used
53+
// EXP-NEXT: RVA:
54+
// EXP-NEXT: }
55+
// EXP-NEXT: Export {
56+
// EXP-NEXT: Ordinal: 5
57+
// EXP-NEXT: Name: sym
58+
// EXP-NEXT: RVA: 0x2008
59+
// EXP-NEXT: }
60+
// EXP-NEXT: Export {
61+
// EXP-NEXT: Ordinal: 6
62+
// EXP-NEXT: Name: sym2
63+
// EXP-NEXT: RVA: 0x200C
64+
// EXP-NEXT: }
65+
// EXP-NEXT: }
66+
67+
// Check that an explicit export in the EC view is respected, preventing symbols from being auto-exported in both EC and native views.
68+
69+
// RUN: lld-link -machine:arm64x -lldmingw -dll -noentry -out:%t2.dll %t.arm64.obj %t.arm64ec.obj -export:sym \
70+
// RUN: %t-loadconfig-arm64.obj %t-loadconfig-arm64ec.obj
71+
72+
// RUN: llvm-readobj --coff-exports %t2.dll | FileCheck --check-prefix=EXP2 %s
73+
// EXP2: Format: COFF-ARM64X
74+
// EXP2-NEXT: Arch: aarch64
75+
// EXP2-NEXT: AddressSize: 64bit
76+
// EXP2-NEXT: HybridObject {
77+
// EXP2-NEXT: Format: COFF-ARM64EC
78+
// EXP2-NEXT: Arch: aarch64
79+
// EXP2-NEXT: AddressSize: 64bit
80+
// EXP2-NEXT: Export {
81+
// EXP2-NEXT: Ordinal: 1
82+
// EXP2-NEXT: Name: sym
83+
// EXP2-NEXT: RVA: 0x2008
84+
// EXP2-NEXT: }
85+
// EXP2-NEXT: }
86+
87+
.data
88+
.globl sym
89+
sym:
90+
.word 0
91+
.globl sym2
92+
sym2:
93+
.word 0

0 commit comments

Comments
 (0)