diff --git a/lib/Object/COFFModuleDefinition.cpp b/lib/Object/COFFModuleDefinition.cpp index ed9140d1fe0..510eac8b239 100644 --- a/lib/Object/COFFModuleDefinition.cpp +++ b/lib/Object/COFFModuleDefinition.cpp @@ -232,7 +232,13 @@ private: for (;;) { read(); if (Tok.K == Identifier && Tok.Value[0] == '@') { - Tok.Value.drop_front().getAsInteger(10, E.Ordinal); + if (Tok.Value.drop_front().getAsInteger(10, E.Ordinal)) { + // Not an ordinal modifier at all, but the next export (fastcall + // decorated) - complete the current one. + unget(); + Info.Exports.push_back(E); + return Error::success(); + } read(); if (Tok.K == KwNoname) { E.Noname = true; diff --git a/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp b/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp index c929c9061c5..c0b09ca106f 100644 --- a/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp +++ b/lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp @@ -155,6 +155,22 @@ int llvm::dlltoolDriverMain(llvm::ArrayRef ArgsArr) { if (Path.empty()) Path = getImplibPath(Def->OutputFile); + if (Machine == IMAGE_FILE_MACHINE_I386 && Args.getLastArg(OPT_k)) { + for (COFFShortExport& E : Def->Exports) { + if (E.isWeak() || (!E.Name.empty() && E.Name[0] == '?')) + continue; + E.SymbolName = E.Name; + // Trim off the trailing decoration. Symbols will always have a + // starting prefix here (either _ for cdecl/stdcall, @ for fastcall + // or ? for C++ functions). (Vectorcall functions also will end up having + // a prefix here, even if they shouldn't.) + E.Name = E.Name.substr(0, E.Name.find('@', 1)); + // By making sure E.SymbolName != E.Name for decorated symbols, + // writeImportLibrary writes these symbols with the type + // IMPORT_NAME_UNDECORATE. + } + } + if (writeImportLibrary(Def->OutputFile, Path, Def->Exports, Machine)) return 1; return 0; diff --git a/lib/ToolDrivers/llvm-dlltool/Options.td b/lib/ToolDrivers/llvm-dlltool/Options.td index 213c6a4d767..e78182ab813 100644 --- a/lib/ToolDrivers/llvm-dlltool/Options.td +++ b/lib/ToolDrivers/llvm-dlltool/Options.td @@ -12,13 +12,13 @@ def D_long : JoinedOrSeparate<["--"], "dllname">, Alias; def d: JoinedOrSeparate<["-"], "d">, HelpText<"Input .def File">; def d_long : JoinedOrSeparate<["--"], "input-def">, Alias; +def k: Flag<["-"], "k">, HelpText<"Kill @n Symbol from export">; +def k_alias: Flag<["--"], "kill-at">, Alias; + //============================================================================== // The flags below do nothing. They are defined only for dlltool compatibility. //============================================================================== -def k: Flag<["-"], "k">, HelpText<"Kill @n Symbol from export">; -def k_alias: Flag<["--"], "kill-at">, Alias; - def S: JoinedOrSeparate<["-"], "S">, HelpText<"Assembler">; def S_alias: JoinedOrSeparate<["--"], "as">, Alias; diff --git a/test/DllTool/coff-decorated.def b/test/DllTool/coff-decorated.def new file mode 100644 index 00000000000..5a908f38848 --- /dev/null +++ b/test/DllTool/coff-decorated.def @@ -0,0 +1,26 @@ +; RUN: llvm-dlltool -k -m i386 --input-def %s --output-lib %t.a +; RUN: llvm-readobj %t.a | FileCheck %s +; RUN: llvm-nm %t.a | FileCheck %s -check-prefix=CHECK-NM + +LIBRARY test.dll +EXPORTS +CdeclFunction +StdcallFunction@4 +@FastcallFunction@4 +StdcallAlias@4=StdcallFunction@4 +??_7exception@@6B@ + +; CHECK: Name type: noprefix +; CHECK: Symbol: __imp__CdeclFunction +; CHECK: Symbol: _CdeclFunction +; CHECK: Name type: undecorate +; CHECK: Symbol: __imp__StdcallFunction@4 +; CHECK: Symbol: _StdcallFunction@4 +; CHECK: Name type: undecorate +; CHECK: Symbol: __imp_@FastcallFunction@4 +; CHECK: Symbol: @FastcallFunction@4 +; CHECK: Name type: name +; CHECK: Symbol: __imp_??_7exception@@6B@ +; CHECK: Symbol: ??_7exception@@6B@ +; CHECK-NM: w _StdcallAlias@4 +; CHECK-NM: U _StdcallFunction@4