summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Storsjo <martin@martin.st>2017-08-16 05:18:36 +0000
committerMartin Storsjo <martin@martin.st>2017-08-16 05:18:36 +0000
commit4c13451fc9fc0a128fb8bb3e9531acb075b2106b (patch)
tree317fe87507ca85f87d2ecb291b03eac8db443316
parent9c571e912046e9587fee4bca15bd92c9d8bd659a (diff)
[llvm-dlltool] Fix creating stdcall/fastcall import libraries for i386
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
-rw-r--r--lib/Object/COFFModuleDefinition.cpp8
-rw-r--r--lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp16
-rw-r--r--lib/ToolDrivers/llvm-dlltool/Options.td6
-rw-r--r--test/DllTool/coff-decorated.def26
4 files changed, 52 insertions, 4 deletions
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<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;
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<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
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