-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[LLD][COFF] Preserve all attributes from forwarding exports from parsed .def files. #86564
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-lld @llvm/pr-subscribers-lld-coff Author: Jacek Caban (cjacek) ChangesThis depends on #86535. It similar to #86535, but for export specified in .def files. Full diff: https://github.com/llvm/llvm-project/pull/86564.diff 3 Files Affected:
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index 1b075389325a91..181492913c0d98 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -1032,19 +1032,18 @@ void LinkerDriver::parseModuleDefs(StringRef path) {
for (COFFShortExport e1 : m.Exports) {
Export e2;
- // In simple cases, only Name is set. Renamed exports are parsed
- // and set as "ExtName = Name". If Name has the form "OtherDll.Func",
- // it shouldn't be a normal exported function but a forward to another
- // DLL instead. This is supported by both MS and GNU linkers.
+ // Renamed exports are parsed and set as "ExtName = Name". If Name has
+ // the form "OtherDll.Func", it shouldn't be a normal exported
+ // function but a forward to another DLL instead. This is supported
+ // by both MS and GNU linkers.
if (!e1.ExtName.empty() && e1.ExtName != e1.Name &&
StringRef(e1.Name).contains('.')) {
e2.name = saver().save(e1.ExtName);
e2.forwardTo = saver().save(e1.Name);
- ctx.config.exports.push_back(e2);
- continue;
+ } else {
+ e2.name = saver().save(e1.Name);
+ e2.extName = saver().save(e1.ExtName);
}
- e2.name = saver().save(e1.Name);
- e2.extName = saver().save(e1.ExtName);
e2.aliasTarget = saver().save(e1.AliasTarget);
e2.ordinal = e1.Ordinal;
e2.noname = e1.Noname;
diff --git a/lld/COFF/DriverUtils.cpp b/lld/COFF/DriverUtils.cpp
index fc8eb327be49bd..0fa4769bab19db 100644
--- a/lld/COFF/DriverUtils.cpp
+++ b/lld/COFF/DriverUtils.cpp
@@ -577,16 +577,15 @@ Export LinkerDriver::parseExport(StringRef arg) {
if (y.contains(".")) {
e.name = x;
e.forwardTo = y;
- return e;
+ } else {
+ e.extName = x;
+ e.name = y;
+ if (e.name.empty())
+ goto err;
}
-
- e.extName = x;
- e.name = y;
- if (e.name.empty())
- goto err;
}
- // If "<name>=<internalname>[,@ordinal[,NONAME]][,DATA][,PRIVATE]"
+ // Optional parameters "[,@ordinal[,NONAME]][,DATA][,PRIVATE]"
while (!rest.empty()) {
StringRef tok;
std::tie(tok, rest) = rest.split(",");
diff --git a/lld/test/COFF/export.test b/lld/test/COFF/export.test
index d340e0174b563e..49577704e6897f 100644
--- a/lld/test/COFF/export.test
+++ b/lld/test/COFF/export.test
@@ -76,18 +76,55 @@ SYMTAB: exportfn3 in export.test.tmp.DLL
# RUN: lld-link /out:%t.dll /dll %t.obj /export:foo=kernel32.foobar
# RUN: llvm-objdump -p %t.dll | FileCheck --check-prefix=FORWARDER %s
+# RUN: llvm-nm -M %t.lib | FileCheck --check-prefix=SYMTAB-FWD %s
# RUN: echo "EXPORTS foo=kernel32.foobar" > %t.def
-# RUN: lld-link /out:%t.dll /dll %t.obj /def:%t.def
-# RUN: llvm-objdump -p %t.dll | FileCheck --check-prefix=FORWARDER %s
+# RUN: lld-link /out:%t-def.dll /dll %t.obj /def:%t.def
+# RUN: llvm-objdump -p %t-def.dll | FileCheck --check-prefix=FORWARDER %s
+# RUN: llvm-nm -M %t-def.lib | FileCheck --check-prefix=SYMTAB-FWD %s
FORWARDER: Export Table:
-FORWARDER: DLL name: export.test.tmp.dll
+FORWARDER: DLL name: export.test.tmp
FORWARDER: Ordinal base: 1
FORWARDER: Ordinal RVA Name
FORWARDER: 1 0x1010 exportfn
FORWARDER: 2 foo (forwarded to kernel32.foobar)
+SYMTAB-FWD: __imp_exportfn3 in export.test.tmp
+SYMTAB-FWD: __imp_foo in export.test.tmp
+SYMTAB-FWD: exportfn3 in export.test.tmp
+SYMTAB-FWD: foo in export.test.tmp
+
+# RUN: lld-link /out:%t-fwd-priv.dll /dll %t.obj /export:foo=kernel32.foobar,DATA,PRIVATE
+# RUN: llvm-objdump -p %t-fwd-priv.dll | FileCheck --check-prefix=FORWARDER %s
+# RUN: llvm-nm -M %t-fwd-priv.lib | FileCheck --check-prefix=SYMTAB-FWD-PRIV %s
+
+SYMTAB-FWD-PRIV: __imp_exportfn3 in export.test.tmp-fwd-priv
+SYMTAB-FWD-PRIV-NOT: __imp_foo
+SYMTAB-FWD-PRIV: exportfn3 in export.test.tmp-fwd-priv
+SYMTAB-FWD-PRIV-NOT: foo
+
+# RUN: echo "EXPORTS foo=kernel32.foobar DATA PRIVATE" > %t-fwd-priv.def
+# RUN: lld-link /out:%t-fwd-priv-def.dll /dll %t.obj /def:%t-fwd-priv.def
+# RUN: llvm-objdump -p %t-fwd-priv-def.dll | FileCheck --check-prefix=FORWARDER %s
+# RUN: llvm-nm -M %t-fwd-priv-def.lib | FileCheck --check-prefix=SYMTAB-FWD-PRIV %s
+
+# RUN: lld-link /out:%t-fwd-ord.dll /dll %t.obj /export:foo=kernel32.foobar,@3,NONAME
+# RUN: llvm-objdump -p %t-fwd-ord.dll | FileCheck --check-prefix=FORWARDER-ORD %s
+# RUN: llvm-nm -M %t-fwd-ord.lib | FileCheck --check-prefix=SYMTAB-FWD %s
+
+FORWARDER-ORD: Export Table:
+FORWARDER-ORD: DLL name: export.test.tmp-fwd-ord
+FORWARDER-ORD: Ordinal base: 3
+FORWARDER-ORD: Ordinal RVA Name
+FORWARDER-ORD: 3 (forwarded to kernel32.foobar)
+FORWARDER-ORD: 4 0x1010 exportfn3
+
+# RUN: echo "EXPORTS foo=kernel32.foobar @3 NONAME" > %t-fwd-ord.def
+# RUN: lld-link /out:%t-fwd-ord-def.dll /dll %t.obj /def:%t-fwd-ord.def
+# RUN: llvm-objdump -p %t-fwd-ord-def.dll | FileCheck --check-prefix=FORWARDER-ORD %s
+# RUN: llvm-nm -M %t-fwd-ord-def.lib | FileCheck --check-prefix=SYMTAB-FWD %s
+
# RUN: lld-link /out:%t.dll /dll %t.obj /merge:.rdata=.text /export:exportfn1 /export:exportfn2
# RUN: llvm-objdump -p %t.dll | FileCheck --check-prefix=MERGE --match-full-lines %s
|
@llvm/pr-subscribers-platform-windows Author: Jacek Caban (cjacek) ChangesThis depends on #86535. It similar to #86535, but for export specified in .def files. Full diff: https://github.com/llvm/llvm-project/pull/86564.diff 3 Files Affected:
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index 1b075389325a91..181492913c0d98 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -1032,19 +1032,18 @@ void LinkerDriver::parseModuleDefs(StringRef path) {
for (COFFShortExport e1 : m.Exports) {
Export e2;
- // In simple cases, only Name is set. Renamed exports are parsed
- // and set as "ExtName = Name". If Name has the form "OtherDll.Func",
- // it shouldn't be a normal exported function but a forward to another
- // DLL instead. This is supported by both MS and GNU linkers.
+ // Renamed exports are parsed and set as "ExtName = Name". If Name has
+ // the form "OtherDll.Func", it shouldn't be a normal exported
+ // function but a forward to another DLL instead. This is supported
+ // by both MS and GNU linkers.
if (!e1.ExtName.empty() && e1.ExtName != e1.Name &&
StringRef(e1.Name).contains('.')) {
e2.name = saver().save(e1.ExtName);
e2.forwardTo = saver().save(e1.Name);
- ctx.config.exports.push_back(e2);
- continue;
+ } else {
+ e2.name = saver().save(e1.Name);
+ e2.extName = saver().save(e1.ExtName);
}
- e2.name = saver().save(e1.Name);
- e2.extName = saver().save(e1.ExtName);
e2.aliasTarget = saver().save(e1.AliasTarget);
e2.ordinal = e1.Ordinal;
e2.noname = e1.Noname;
diff --git a/lld/COFF/DriverUtils.cpp b/lld/COFF/DriverUtils.cpp
index fc8eb327be49bd..0fa4769bab19db 100644
--- a/lld/COFF/DriverUtils.cpp
+++ b/lld/COFF/DriverUtils.cpp
@@ -577,16 +577,15 @@ Export LinkerDriver::parseExport(StringRef arg) {
if (y.contains(".")) {
e.name = x;
e.forwardTo = y;
- return e;
+ } else {
+ e.extName = x;
+ e.name = y;
+ if (e.name.empty())
+ goto err;
}
-
- e.extName = x;
- e.name = y;
- if (e.name.empty())
- goto err;
}
- // If "<name>=<internalname>[,@ordinal[,NONAME]][,DATA][,PRIVATE]"
+ // Optional parameters "[,@ordinal[,NONAME]][,DATA][,PRIVATE]"
while (!rest.empty()) {
StringRef tok;
std::tie(tok, rest) = rest.split(",");
diff --git a/lld/test/COFF/export.test b/lld/test/COFF/export.test
index d340e0174b563e..49577704e6897f 100644
--- a/lld/test/COFF/export.test
+++ b/lld/test/COFF/export.test
@@ -76,18 +76,55 @@ SYMTAB: exportfn3 in export.test.tmp.DLL
# RUN: lld-link /out:%t.dll /dll %t.obj /export:foo=kernel32.foobar
# RUN: llvm-objdump -p %t.dll | FileCheck --check-prefix=FORWARDER %s
+# RUN: llvm-nm -M %t.lib | FileCheck --check-prefix=SYMTAB-FWD %s
# RUN: echo "EXPORTS foo=kernel32.foobar" > %t.def
-# RUN: lld-link /out:%t.dll /dll %t.obj /def:%t.def
-# RUN: llvm-objdump -p %t.dll | FileCheck --check-prefix=FORWARDER %s
+# RUN: lld-link /out:%t-def.dll /dll %t.obj /def:%t.def
+# RUN: llvm-objdump -p %t-def.dll | FileCheck --check-prefix=FORWARDER %s
+# RUN: llvm-nm -M %t-def.lib | FileCheck --check-prefix=SYMTAB-FWD %s
FORWARDER: Export Table:
-FORWARDER: DLL name: export.test.tmp.dll
+FORWARDER: DLL name: export.test.tmp
FORWARDER: Ordinal base: 1
FORWARDER: Ordinal RVA Name
FORWARDER: 1 0x1010 exportfn
FORWARDER: 2 foo (forwarded to kernel32.foobar)
+SYMTAB-FWD: __imp_exportfn3 in export.test.tmp
+SYMTAB-FWD: __imp_foo in export.test.tmp
+SYMTAB-FWD: exportfn3 in export.test.tmp
+SYMTAB-FWD: foo in export.test.tmp
+
+# RUN: lld-link /out:%t-fwd-priv.dll /dll %t.obj /export:foo=kernel32.foobar,DATA,PRIVATE
+# RUN: llvm-objdump -p %t-fwd-priv.dll | FileCheck --check-prefix=FORWARDER %s
+# RUN: llvm-nm -M %t-fwd-priv.lib | FileCheck --check-prefix=SYMTAB-FWD-PRIV %s
+
+SYMTAB-FWD-PRIV: __imp_exportfn3 in export.test.tmp-fwd-priv
+SYMTAB-FWD-PRIV-NOT: __imp_foo
+SYMTAB-FWD-PRIV: exportfn3 in export.test.tmp-fwd-priv
+SYMTAB-FWD-PRIV-NOT: foo
+
+# RUN: echo "EXPORTS foo=kernel32.foobar DATA PRIVATE" > %t-fwd-priv.def
+# RUN: lld-link /out:%t-fwd-priv-def.dll /dll %t.obj /def:%t-fwd-priv.def
+# RUN: llvm-objdump -p %t-fwd-priv-def.dll | FileCheck --check-prefix=FORWARDER %s
+# RUN: llvm-nm -M %t-fwd-priv-def.lib | FileCheck --check-prefix=SYMTAB-FWD-PRIV %s
+
+# RUN: lld-link /out:%t-fwd-ord.dll /dll %t.obj /export:foo=kernel32.foobar,@3,NONAME
+# RUN: llvm-objdump -p %t-fwd-ord.dll | FileCheck --check-prefix=FORWARDER-ORD %s
+# RUN: llvm-nm -M %t-fwd-ord.lib | FileCheck --check-prefix=SYMTAB-FWD %s
+
+FORWARDER-ORD: Export Table:
+FORWARDER-ORD: DLL name: export.test.tmp-fwd-ord
+FORWARDER-ORD: Ordinal base: 3
+FORWARDER-ORD: Ordinal RVA Name
+FORWARDER-ORD: 3 (forwarded to kernel32.foobar)
+FORWARDER-ORD: 4 0x1010 exportfn3
+
+# RUN: echo "EXPORTS foo=kernel32.foobar @3 NONAME" > %t-fwd-ord.def
+# RUN: lld-link /out:%t-fwd-ord-def.dll /dll %t.obj /def:%t-fwd-ord.def
+# RUN: llvm-objdump -p %t-fwd-ord-def.dll | FileCheck --check-prefix=FORWARDER-ORD %s
+# RUN: llvm-nm -M %t-fwd-ord-def.lib | FileCheck --check-prefix=SYMTAB-FWD %s
+
# RUN: lld-link /out:%t.dll /dll %t.obj /merge:.rdata=.text /export:exportfn1 /export:exportfn2
# RUN: llvm-objdump -p %t.dll | FileCheck --check-prefix=MERGE --match-full-lines %s
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
✅ With the latest revision this PR passed the Python code formatter. |
This depends on #86535.
It similar to #86535, but for export specified in .def files.