]> granicus.if.org Git - llvm/commitdiff
[llvm-dlltool] Fix creating stdcall/fastcall import libraries for i386
authorMartin Storsjo <martin@martin.st>
Wed, 16 Aug 2017 05:18:36 +0000 (05:18 +0000)
committerMartin Storsjo <martin@martin.st>
Wed, 16 Aug 2017 05:18:36 +0000 (05:18 +0000)
Hook up the -k option (that in the original GNU dlltool removes the
@n suffix from the symbol that the final executable ends up linked to).

In llvm-dlltool, make sure that functions end up with the undecorate
name type if this option is set and they are decorated. In mingw, when
creating import libraries from def files instead of creating an import
library as a side effect of linking a DLL, the symbol names in the def
contain the stdcall/fastcall decoration (but no leading underscore).

By setting the undecorate name type, a linker linking to the import
library will omit the decoration from the DLL import entry.

With this in place, mingw-w64 for i386 built with llvm-dlltool/clang
produces import libraries that actually work.

Differential Revision: https://reviews.llvm.org/D36548

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@310990 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Object/COFFModuleDefinition.cpp
lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp
lib/ToolDrivers/llvm-dlltool/Options.td
test/DllTool/coff-decorated.def [new file with mode: 0644]

index ed9140d1fe08b00426384b8be9c0997940de89b5..510eac8b239ba93d0808acec02aa5f867c8d5fb5 100644 (file)
@@ -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;
index c929c9061c50af74c14e66e319da47a3235a5659..c0b09ca106fdd444cb110a1448565fe063ab9d8d 100644 (file)
@@ -155,6 +155,22 @@ int llvm::dlltoolDriverMain(llvm::ArrayRef<const char *> 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;
index 213c6a4d76749040d7dd2bafd5a7398aa5200f6f..e78182ab8130b0ce7e63d104e9f88ed8acd90361 100644 (file)
@@ -12,13 +12,13 @@ def D_long : JoinedOrSeparate<["--"], "dllname">, Alias<D>;
 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>;
 
diff --git a/test/DllTool/coff-decorated.def b/test/DllTool/coff-decorated.def
new file mode 100644 (file)
index 0000000..5a908f3
--- /dev/null
@@ -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