[llvm] 4469650 - [llvm-dlltool] Handle import renaming using other name types, when possible (#98228)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 16 13:17:04 PDT 2024


Author: Martin Storsjö
Date: 2024-07-16T23:17:01+03:00
New Revision: 446965070149d53374ee4d3010789673083fb11c

URL: https://github.com/llvm/llvm-project/commit/446965070149d53374ee4d3010789673083fb11c
DIFF: https://github.com/llvm/llvm-project/commit/446965070149d53374ee4d3010789673083fb11c.diff

LOG: [llvm-dlltool] Handle import renaming using other name types, when possible (#98228)

This avoids needing to use weak aliases for these cases. (Weak
aliases only work if there's another, regular import entry that
provide the desired symbol from the DLL.)

Added: 
    

Modified: 
    llvm/lib/Object/COFFImportFile.cpp
    llvm/test/tools/llvm-dlltool/coff-decorated.def

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Object/COFFImportFile.cpp b/llvm/lib/Object/COFFImportFile.cpp
index 03af4921ddbca..1ddc5d954de68 100644
--- a/llvm/lib/Object/COFFImportFile.cpp
+++ b/llvm/lib/Object/COFFImportFile.cpp
@@ -52,18 +52,12 @@ StringRef COFFImportFile::getFileFormatName() const {
   }
 }
 
-StringRef COFFImportFile::getExportName() const {
-  const coff_import_header *hdr = getCOFFImportHeader();
-  StringRef name = Data.getBuffer().substr(sizeof(*hdr)).split('\0').first;
-
+static StringRef applyNameType(ImportNameType Type, StringRef name) {
   auto ltrim1 = [](StringRef s, StringRef chars) {
     return !s.empty() && chars.contains(s[0]) ? s.substr(1) : s;
   };
 
-  switch (hdr->getNameType()) {
-  case IMPORT_ORDINAL:
-    name = "";
-    break;
+  switch (Type) {
   case IMPORT_NAME_NOPREFIX:
     name = ltrim1(name, "?@_");
     break;
@@ -71,6 +65,24 @@ StringRef COFFImportFile::getExportName() const {
     name = ltrim1(name, "?@_");
     name = name.substr(0, name.find('@'));
     break;
+  default:
+    break;
+  }
+  return name;
+}
+
+StringRef COFFImportFile::getExportName() const {
+  const coff_import_header *hdr = getCOFFImportHeader();
+  StringRef name = Data.getBuffer().substr(sizeof(*hdr)).split('\0').first;
+
+  switch (hdr->getNameType()) {
+  case IMPORT_ORDINAL:
+    name = "";
+    break;
+  case IMPORT_NAME_NOPREFIX:
+  case IMPORT_NAME_UNDECORATE:
+    name = applyNameType(static_cast<ImportNameType>(hdr->getNameType()), name);
+    break;
   case IMPORT_NAME_EXPORTAS: {
     // Skip DLL name
     name = Data.getBuffer().substr(sizeof(*hdr) + name.size() + 1);
@@ -691,19 +703,6 @@ Error writeImportLibrary(StringRef ImportName, StringRef Path,
         Name.swap(*ReplacedName);
       }
 
-      if (!E.ImportName.empty() && Name != E.ImportName) {
-        StringRef Prefix = "";
-        if (Machine == IMAGE_FILE_MACHINE_I386 && AddUnderscores)
-          Prefix = "_";
-
-        if (ImportType == IMPORT_CODE)
-          Members.push_back(OF.createWeakExternal((Prefix + E.ImportName).str(),
-                                                  Name, false, M));
-        Members.push_back(OF.createWeakExternal((Prefix + E.ImportName).str(),
-                                                Name, true, M));
-        continue;
-      }
-
       ImportNameType NameType;
       std::string ExportName;
       if (E.Noname) {
@@ -711,6 +710,31 @@ Error writeImportLibrary(StringRef ImportName, StringRef Path,
       } else if (!E.ExportAs.empty()) {
         NameType = IMPORT_NAME_EXPORTAS;
         ExportName = E.ExportAs;
+      } else if (!E.ImportName.empty()) {
+        // If we need to import from a specific ImportName, we may need to use
+        // a weak alias (which needs another import to point at). But if we can
+        // express ImportName based on the symbol name and a specific NameType,
+        // prefer that over an alias.
+        if (Machine == IMAGE_FILE_MACHINE_I386 &&
+            applyNameType(IMPORT_NAME_UNDECORATE, Name) == E.ImportName)
+          NameType = IMPORT_NAME_UNDECORATE;
+        else if (Machine == IMAGE_FILE_MACHINE_I386 &&
+                 applyNameType(IMPORT_NAME_NOPREFIX, Name) == E.ImportName)
+          NameType = IMPORT_NAME_NOPREFIX;
+        else if (Name == E.ImportName)
+          NameType = IMPORT_NAME;
+        else {
+          StringRef Prefix = "";
+          if (Machine == IMAGE_FILE_MACHINE_I386 && AddUnderscores)
+            Prefix = "_";
+
+          if (ImportType == IMPORT_CODE)
+            Members.push_back(OF.createWeakExternal(
+                (Prefix + E.ImportName).str(), Name, false, M));
+          Members.push_back(OF.createWeakExternal((Prefix + E.ImportName).str(),
+                                                  Name, true, M));
+          continue;
+        }
       } else {
         NameType = getNameType(SymbolName, E.Name, M, MinGW);
       }

diff  --git a/llvm/test/tools/llvm-dlltool/coff-decorated.def b/llvm/test/tools/llvm-dlltool/coff-decorated.def
index fc81f23d09d6c..773e3762cc3d7 100644
--- a/llvm/test/tools/llvm-dlltool/coff-decorated.def
+++ b/llvm/test/tools/llvm-dlltool/coff-decorated.def
@@ -13,6 +13,10 @@ StdcallExportName at 4=StdcallInternalFunction at 4
 OtherStdcallExportName at 4=CdeclInternalFunction
 CdeclExportName=StdcallInternalFunction at 4
 
+NoprefixStdcall at 4 == NoprefixStdcall at 4
+DecoratedStdcall at 4 == _DecoratedStdcall at 4
+UndecoratedStdcall at 4 == UndecoratedStdcall
+
 ; CHECK:      Name type: noprefix
 ; CHECK-NEXT: Export name: CdeclFunction
 ; CHECK-NEXT: Symbol: __imp__CdeclFunction
@@ -43,3 +47,15 @@ CdeclExportName=StdcallInternalFunction at 4
 ; CHECK-NEXT: Export name: CdeclExportName
 ; CHECK-NEXT: Symbol: __imp__CdeclExportName
 ; CHECK-NEXT: Symbol: _CdeclExportName
+; CHECK:      Name type: noprefix
+; CHECK-NEXT: Export name: NoprefixStdcall at 4
+; CHECK-NEXT: Symbol: __imp__NoprefixStdcall at 4
+; CHECK-NEXT: Symbol: _NoprefixStdcall at 4
+; CHECK:      Name type: name
+; CHECK-NEXT: Export name: _DecoratedStdcall at 4
+; CHECK-NEXT: Symbol: __imp__DecoratedStdcall at 4
+; CHECK-NEXT: Symbol: _DecoratedStdcall at 4
+; CHECK:      Name type: undecorate
+; CHECK-NEXT: Export name: UndecoratedStdcall
+; CHECK-NEXT: Symbol: __imp__UndecoratedStdcall at 4
+; CHECK-NEXT: Symbol: _UndecoratedStdcall at 4


        


More information about the llvm-commits mailing list