Skip to content

Commit 8a933e3

Browse files
committed
[LLD][COFF] Add support for EXPORTAS import name type.
1 parent 9d242f5 commit 8a933e3

File tree

4 files changed

+101
-6
lines changed

4 files changed

+101
-6
lines changed

lld/COFF/Config.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ enum class EmitKind { Obj, LLVM, ASM };
5454
struct Export {
5555
StringRef name; // N in /export:N or /export:E=N
5656
StringRef extName; // E in /export:E=N
57+
StringRef exportAs; // E in /export:N,EXPORTAS,E
5758
StringRef aliasTarget; // GNU specific: N in "alias == N"
5859
Symbol *sym = nullptr;
5960
uint16_t ordinal = 0;
@@ -73,10 +74,9 @@ struct Export {
7374
StringRef exportName; // Name in DLL
7475

7576
bool operator==(const Export &e) const {
76-
return (name == e.name && extName == e.extName &&
77-
aliasTarget == e.aliasTarget &&
78-
ordinal == e.ordinal && noname == e.noname &&
79-
data == e.data && isPrivate == e.isPrivate);
77+
return (name == e.name && extName == e.extName && exportAs == e.exportAs &&
78+
aliasTarget == e.aliasTarget && ordinal == e.ordinal &&
79+
noname == e.noname && data == e.data && isPrivate == e.isPrivate);
8080
}
8181
};
8282

lld/COFF/Driver.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,7 @@ void LinkerDriver::createImportLibrary(bool asLib) {
945945
e2.Name = std::string(e1.name);
946946
e2.SymbolName = std::string(e1.symbolName);
947947
e2.ExtName = std::string(e1.extName);
948+
e2.ExportAs = std::string(e1.exportAs);
948949
e2.AliasTarget = std::string(e1.aliasTarget);
949950
e2.Ordinal = e1.ordinal;
950951
e2.Noname = e1.noname;
@@ -1039,12 +1040,14 @@ void LinkerDriver::parseModuleDefs(StringRef path) {
10391040
if (!e1.ExtName.empty() && e1.ExtName != e1.Name &&
10401041
StringRef(e1.Name).contains('.')) {
10411042
e2.name = saver().save(e1.ExtName);
1043+
e2.exportAs = saver().save(e1.ExportAs);
10421044
e2.forwardTo = saver().save(e1.Name);
10431045
ctx.config.exports.push_back(e2);
10441046
continue;
10451047
}
10461048
e2.name = saver().save(e1.Name);
10471049
e2.extName = saver().save(e1.ExtName);
1050+
e2.exportAs = saver().save(e1.ExportAs);
10481051
e2.aliasTarget = saver().save(e1.AliasTarget);
10491052
e2.ordinal = e1.Ordinal;
10501053
e2.noname = e1.Noname;

lld/COFF/DriverUtils.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,8 @@ Export LinkerDriver::parseExport(StringRef arg) {
585585
}
586586
}
587587

588-
// Optional parameters "[,@ordinal[,NONAME]][,DATA][,PRIVATE]"
588+
// Optional parameters
589+
// "[,@ordinal[,NONAME]][,DATA][,PRIVATE][,EXPORTAS,exportname]"
589590
while (!rest.empty()) {
590591
StringRef tok;
591592
std::tie(tok, rest) = rest.split(",");
@@ -607,6 +608,12 @@ Export LinkerDriver::parseExport(StringRef arg) {
607608
e.isPrivate = true;
608609
continue;
609610
}
611+
if (tok.equals_insensitive("exportas")) {
612+
if (rest.empty() || rest.contains(','))
613+
goto err;
614+
e.exportAs = rest;
615+
break;
616+
}
610617
if (tok.starts_with("@")) {
611618
int32_t ord;
612619
if (tok.substr(1).getAsInteger(0, ord))
@@ -683,7 +690,9 @@ void LinkerDriver::fixupExports() {
683690
}
684691

685692
for (Export &e : ctx.config.exports) {
686-
if (!e.forwardTo.empty()) {
693+
if (!e.exportAs.empty()) {
694+
e.exportName = e.exportAs;
695+
} else if (!e.forwardTo.empty()) {
687696
e.exportName = undecorate(ctx, e.name);
688697
} else {
689698
e.exportName = undecorate(ctx, e.extName.empty() ? e.name : e.extName);

lld/test/COFF/exportas.test

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,72 @@ RUN: lld-link -out:out1.dll -dll -noentry test.obj test.lib
99
RUN: llvm-readobj --coff-imports out1.dll | FileCheck --check-prefix=IMPORT %s
1010
IMPORT: Symbol: expfunc
1111

12+
Pass -export argument with EXPORTAS.
13+
14+
RUN: llvm-mc -filetype=obj -triple=x86_64-windows func.s -o func.obj
15+
RUN: lld-link -out:out2.dll -dll -noentry func.obj -export:func,EXPORTAS,expfunc
16+
RUN: llvm-readobj --coff-exports out2.dll | FileCheck --check-prefix=EXPORT %s
17+
EXPORT: Name: expfunc
18+
19+
RUN: llvm-readobj out2.lib | FileCheck --check-prefix=IMPLIB %s
20+
IMPLIB: Name type: export as
21+
IMPLIB-NEXT: Export name: expfunc
22+
IMPLIB-NEXT: Symbol: __imp_func
23+
IMPLIB-NEXT: Symbol: func
24+
25+
Use .drectve section with EXPORTAS.
26+
27+
RUN: llvm-mc -filetype=obj -triple=x86_64-windows drectve.s -o drectve.obj
28+
RUN: lld-link -out:out3.dll -dll -noentry func.obj drectve.obj
29+
RUN: llvm-readobj --coff-exports out3.dll | FileCheck --check-prefix=EXPORT %s
30+
RUN: llvm-readobj out3.lib | FileCheck --check-prefix=IMPLIB %s
31+
32+
Use a .def file with EXPORTAS.
33+
34+
RUN: lld-link -out:out4.dll -dll -noentry func.obj -def:test.def
35+
RUN: llvm-readobj --coff-exports out4.dll | FileCheck --check-prefix=EXPORT %s
36+
RUN: llvm-readobj out4.lib | FileCheck --check-prefix=IMPLIB %s
37+
38+
Use a .def file with EXPORTAS in a forwarding export.
39+
40+
RUN: lld-link -out:out5.dll -dll -noentry func.obj -def:test2.def
41+
RUN: llvm-readobj --coff-exports out5.dll | FileCheck --check-prefix=FORWARD-EXPORT %s
42+
FORWARD-EXPORT: Export {
43+
FORWARD-EXPORT-NEXT: Ordinal: 1
44+
FORWARD-EXPORT-NEXT: Name: expfunc
45+
FORWARD-EXPORT-NEXT: ForwardedTo: otherdll.otherfunc
46+
FORWARD-EXPORT-NEXT: }
47+
48+
RUN: llvm-readobj out5.lib | FileCheck --check-prefix=FORWARD-IMPLIB %s
49+
FORWARD-IMPLIB: Name type: export as
50+
FORWARD-IMPLIB-NEXT: Export name: expfunc
51+
FORWARD-IMPLIB-NEXT: Symbol: __imp_func
52+
FORWARD-IMPLIB-NEXT: Symbol: func
53+
54+
Pass -export argument with EXPORTAS in a forwarding export.
55+
56+
RUN: lld-link -out:out6.dll -dll -noentry func.obj -export:func=otherdll.otherfunc,EXPORTAS,expfunc
57+
RUN: llvm-readobj --coff-exports out6.dll | FileCheck --check-prefix=FORWARD-EXPORT %s
58+
RUN: llvm-readobj out6.lib | FileCheck --check-prefix=FORWARD-IMPLIB %s
59+
60+
Pass -export argument with EXPORTAS in a data export.
61+
62+
RUN: lld-link -out:out7.dll -dll -noentry func.obj -export:func,DATA,@5,EXPORTAS,expfunc
63+
RUN: llvm-readobj --coff-exports out7.dll | FileCheck --check-prefix=ORD %s
64+
ORD: Ordinal: 5
65+
ORD-NEXT: Name: expfunc
66+
67+
RUN: llvm-readobj out7.lib | FileCheck --check-prefix=ORD-IMPLIB %s
68+
ORD-IMPLIB: Type: data
69+
ORD-IMPLIB-NEXT: Name type: export as
70+
ORD-IMPLIB-NEXT: Export name: expfunc
71+
ORD-IMPLIB-NEXT: Symbol: __imp_func
72+
73+
Check invalid EXPORTAS syntax.
74+
75+
RUN: not lld-link -out:err1.dll -dll -noentry func.obj -export:func,EXPORTAS,
76+
RUN: not lld-link -out:err2.dll -dll -noentry func.obj -export:func,EXPORTAS,expfunc,DATA
77+
1278
#--- test.s
1379
.section ".test", "rd"
1480
.rva __imp_func
@@ -17,3 +83,20 @@ IMPORT: Symbol: expfunc
1783
LIBRARY test.dll
1884
EXPORTS
1985
func EXPORTAS expfunc
86+
87+
#--- test2.def
88+
LIBRARY test.dll
89+
EXPORTS
90+
func=otherdll.otherfunc EXPORTAS expfunc
91+
92+
#--- func.s
93+
.text
94+
.globl func
95+
.p2align 2, 0x0
96+
func:
97+
movl $1, %eax
98+
retq
99+
100+
#--- drectve.s
101+
.section .drectve, "yn"
102+
.ascii " -export:func,EXPORTAS,expfunc"

0 commit comments

Comments
 (0)