Index: COFF/Config.h =================================================================== --- COFF/Config.h +++ COFF/Config.h @@ -45,6 +45,7 @@ bool Data = false; bool Private = false; bool Constant = false; + bool KeepDecoration = false; // If an export is a form of /export:foo=dllname.bar, that means // that foo should be exported as an alias to bar in the DLL. Index: COFF/Driver.cpp =================================================================== --- COFF/Driver.cpp +++ COFF/Driver.cpp @@ -255,6 +255,9 @@ if (!E.ExtName.empty() && !isDecorated(E.ExtName)) E.ExtName = Saver.save("_" + E.ExtName); } + if (Config->Machine == I386 && !Config->MinGW && E.Name.startswith("_") && + E.Name.contains('@')) + E.KeepDecoration = true; E.Directives = true; Config->Exports.push_back(E); break; @@ -526,6 +529,7 @@ E2.Data = E1.Data; E2.Private = E1.Private; E2.Constant = E1.Constant; + E2.KeepDecoration = E1.KeepDecoration; Exports.push_back(E2); } @@ -573,6 +577,7 @@ E2.Data = E1.Data; E2.Private = E1.Private; E2.Constant = E1.Constant; + E2.KeepDecoration = E1.KeepDecoration; Config->Exports.push_back(E2); } } @@ -1116,6 +1121,9 @@ E.Name = Saver.save("_" + E.Name); if (!E.ExtName.empty() && !isDecorated(E.ExtName)) E.ExtName = Saver.save("_" + E.ExtName); + if (Config->Machine == I386 && !Config->MinGW && E.Name.startswith("_") && + E.Name.contains('@')) + E.KeepDecoration = true; } Config->Exports.push_back(E); } Index: COFF/DriverUtils.cpp =================================================================== --- COFF/DriverUtils.cpp +++ COFF/DriverUtils.cpp @@ -555,8 +555,8 @@ fatal("invalid /export: " + Arg); } -static StringRef undecorate(StringRef Sym) { - if (Config->Machine != I386) +static StringRef undecorate(StringRef Sym, bool KeepDecoration = false) { + if (Config->Machine != I386 || KeepDecoration) return Sym; return Sym.startswith("_") ? Sym.substr(1) : Sym; } @@ -589,7 +589,8 @@ if (!E.ForwardTo.empty()) { E.ExportName = undecorate(E.Name); } else { - E.ExportName = undecorate(E.ExtName.empty() ? E.Name : E.ExtName); + E.ExportName = + undecorate(E.ExtName.empty() ? E.Name : E.ExtName, E.KeepDecoration); } } Index: test/COFF/def-export-stdcall.s =================================================================== --- test/COFF/def-export-stdcall.s +++ test/COFF/def-export-stdcall.s @@ -32,8 +32,7 @@ # DECORATED-IMPLIB: Name type: name # DECORATED-IMPLIB-NEXT: __imp_@fastcall@8 # DECORATED-IMPLIB-NEXT: @fastcall@8 -# TODO: To match link.exe, this one should also be Name type: name. -# DECORATED-IMPLIB: Name type: noprefix +# DECORATED-IMPLIB: Name type: name # DECORATED-IMPLIB-NEXT: __imp__stdcall@8 # DECORATED-IMPLIB-NEXT: _stdcall@8 # DECORATED-IMPLIB: Name type: name @@ -41,8 +40,7 @@ # DECORATED-IMPLIB-NEXT: vectorcall@@8 # DECORATED-EXPORTS: Name: @fastcall@8 -# TODO: To match link.exe, this one should actually be _stdcall@8 -# DECORATED-EXPORTS: Name: stdcall@8 +# DECORATED-EXPORTS: Name: _stdcall@8 # DECORATED-EXPORTS: Name: vectorcall@@8 Index: test/COFF/dllexport.s =================================================================== --- test/COFF/dllexport.s +++ test/COFF/dllexport.s @@ -8,21 +8,19 @@ # DECORATED-IMPLIB: Name type: name # DECORATED-IMPLIB-NEXT: __imp_@fastcall@8 # DECORATED-IMPLIB-NEXT: @fastcall@8 +# DECORATED-IMPLIB: Name type: name +# DECORATED-IMPLIB-NEXT: __imp__stdcall@8 +# DECORATED-IMPLIB-NEXT: _stdcall@8 # DECORATED-IMPLIB: Name type: noprefix # DECORATED-IMPLIB-NEXT: __imp___underscored # DECORATED-IMPLIB-NEXT: __underscored -# TODO: To match link.exe, this one should also be Name type: name. -# DECORATED-IMPLIB: Name type: noprefix -# DECORATED-IMPLIB-NEXT: __imp__stdcall@8 -# DECORATED-IMPLIB-NEXT: _stdcall@8 # DECORATED-IMPLIB: Name type: name # DECORATED-IMPLIB-NEXT: __imp_vectorcall@@8 # DECORATED-IMPLIB-NEXT: vectorcall@@8 # DECORATED-EXPORTS: Name: @fastcall@8 +# DECORATED-EXPORTS: Name: _stdcall@8 # DECORATED-EXPORTS: Name: _underscored -# TODO: To match link.exe, this one should actually be _stdcall@8 -# DECORATED-EXPORTS: Name: stdcall@8 # DECORATED-EXPORTS: Name: vectorcall@@8 .def _stdcall@8;