[PATCH] D36548: [llvm-dlltool] Fix creating stdcall/fastcall import libraries for i386

Martin Storsjö via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 12 13:06:31 PDT 2017


mstorsjo updated this revision to Diff 110850.
mstorsjo added a comment.

Updated to set the right name type for C++ symbols as well, including a testcase for it.


https://reviews.llvm.org/D36548

Files:
  lib/Object/COFFModuleDefinition.cpp
  lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp
  lib/ToolDrivers/llvm-dlltool/Options.td
  test/DllTool/coff-decorated.def


Index: test/DllTool/coff-decorated.def
===================================================================
--- /dev/null
+++ 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 at 4
+ at FastcallFunction@4
+StdcallAlias at 4=StdcallFunction at 4
+??_7exception@@6B@
+
+; CHECK: Name type: noprefix
+; CHECK: Symbol: __imp__CdeclFunction
+; CHECK: Symbol: _CdeclFunction
+; CHECK: Name type: undecorate
+; CHECK: Symbol: __imp__StdcallFunction at 4
+; CHECK: Symbol: _StdcallFunction at 4
+; CHECK: Name type: undecorate
+; CHECK: Symbol: __imp_ at FastcallFunction@4
+; CHECK: Symbol: @FastcallFunction at 4
+; CHECK: Name type: name
+; CHECK: Symbol: __imp_??_7exception@@6B@
+; CHECK: Symbol: ??_7exception@@6B@
+; CHECK-NM: w _StdcallAlias at 4
+; CHECK-NM: U _StdcallFunction at 4
Index: lib/ToolDrivers/llvm-dlltool/Options.td
===================================================================
--- lib/ToolDrivers/llvm-dlltool/Options.td
+++ lib/ToolDrivers/llvm-dlltool/Options.td
@@ -12,13 +12,13 @@
 def d: JoinedOrSeparate<["-"], "d">, HelpText<"Input .def File">;
 def d_long : JoinedOrSeparate<["--"], "input-def">, Alias<d>;
 
+def k: Flag<["-"], "k">, HelpText<"Kill @n Symbol from export">;
+def k_alias: Flag<["--"], "kill-at">, Alias<k>;
+
 //==============================================================================
 // 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<k>;
-
 def S: JoinedOrSeparate<["-"], "S">, HelpText<"Assembler">;
 def S_alias: JoinedOrSeparate<["--"], "as">, Alias<S>;
 
Index: lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp
===================================================================
--- lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp
+++ lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp
@@ -155,6 +155,22 @@
   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;
Index: lib/Object/COFFModuleDefinition.cpp
===================================================================
--- lib/Object/COFFModuleDefinition.cpp
+++ lib/Object/COFFModuleDefinition.cpp
@@ -232,7 +232,14 @@
     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();
+          break;
+        }
         read();
         if (Tok.K == KwNoname) {
           E.Noname = true;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D36548.110850.patch
Type: text/x-patch
Size: 3851 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170812/77b369e6/attachment.bin>


More information about the llvm-commits mailing list