]> granicus.if.org Git - llvm/commitdiff
[COFF] Improve the check for functions that should get an extra underscore
authorMartin Storsjo <martin@martin.st>
Mon, 23 Oct 2017 09:08:13 +0000 (09:08 +0000)
committerMartin Storsjo <martin@martin.st>
Mon, 23 Oct 2017 09:08:13 +0000 (09:08 +0000)
This fixes exporting functions starting with an underscore, and
fully decorated fastcall/vectorcall functions.

Tests will be added in the lld repo.

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

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

lib/Object/COFFModuleDefinition.cpp
lib/ToolDrivers/llvm-dlltool/DlltoolDriver.cpp

index 510eac8b239ba93d0808acec02aa5f867c8d5fb5..6ea6015eabcac80d0f7406807794ba43e8261479 100644 (file)
@@ -57,9 +57,27 @@ struct Token {
 };
 
 static bool isDecorated(StringRef Sym, bool MingwDef) {
-  // mingw does not prepend "_".
-  return (!MingwDef && Sym.startswith("_")) || Sym.startswith("@") ||
-         Sym.startswith("?");
+  // In def files, the symbols can either be listed decorated or undecorated.
+  //
+  // - For cdecl symbols, only the undecorated form is allowed.
+  // - For fastcall and vectorcall symbols, both fully decorated or
+  //   undecorated forms can be present.
+  // - For stdcall symbols in non-MinGW environments, the decorated form is
+  //   fully decorated with leading underscore and trailing stack argument
+  //   size - like "_Func@0".
+  // - In MinGW def files, a decorated stdcall symbol does not include the
+  //   leading underscore though, like "Func@0".
+
+  // This function controls whether a leading underscore should be added to
+  // the given symbol name or not. For MinGW, treat a stdcall symbol name such
+  // as "Func@0" as undecorated, i.e. a leading underscore must be added.
+  // For non-MinGW, look for '@' in the whole string and consider "_Func@0"
+  // as decorated, i.e. don't add any more leading underscores.
+  // We can't check for a leading underscore here, since function names
+  // themselves can start with an underscore, while a second one still needs
+  // to be added.
+  return Sym.startswith("@") || Sym.contains("@@") || Sym.startswith("?") ||
+         (!MingwDef && Sym.contains('@'));
 }
 
 static Error createError(const Twine &Err) {
index eb9b9c3b264d3e611fb2e806281e58ac3c2f6e6c..3891efae57bb47f5a9232c1f8888b6588bb2624f 100644 (file)
@@ -165,8 +165,9 @@ int llvm::dlltoolDriverMain(llvm::ArrayRef<const char *> ArgsArr) {
       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.)
+      // or ? for C++ functions). Vectorcall functions won't have any
+      // fixed prefix, but the function base name will still be at least
+      // one char.
       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