Index: COFF/Driver.cpp =================================================================== --- COFF/Driver.cpp +++ COFF/Driver.cpp @@ -628,6 +628,16 @@ 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. + if (E1.ExtName != E1.Name && StringRef(E1.Name).contains('.')) { + E2.Name = E1.ExtName; + E2.ForwardTo = E1.Name; + Config->Exports.push_back(E2); + continue; + } E2.Name = Saver.save(E1.Name); if (E1.isWeak()) E2.ExtName = Saver.save(E1.ExtName); Index: test/COFF/export.test =================================================================== --- test/COFF/export.test +++ test/COFF/export.test @@ -86,6 +86,10 @@ # 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: 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 + FORWARDER: Export Table: FORWARDER: DLL name: export.test.tmp.dll FORWARDER: Ordinal base: 0