[llvm] ca2353c - Teach llvm-jitlink to support archives in inputs files and -load_hidden

Ben Langmuir via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 14 16:28:33 PST 2022


Author: Ben Langmuir
Date: 2022-01-14T16:27:51-08:00
New Revision: ca2353ce5a778d2b2780f3f54244e1844363bba3

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

LOG: Teach llvm-jitlink to support archives in inputs files and -load_hidden

Similar to the ld64 command-line options. These use the same underlying
mechanisms as -l and -hidden-l, but allow specifying an absolute path to
the archive. This is often more convenient for a one-off, or when adding
a new search path could change how existing -l options are resolved.

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

Added: 
    

Modified: 
    llvm/test/ExecutionEngine/JITLink/X86/MachO_archive_load_hidden_expect_success.s
    llvm/test/ExecutionEngine/JITLink/X86/MachO_archive_support.s
    llvm/tools/llvm-jitlink/llvm-jitlink.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/test/ExecutionEngine/JITLink/X86/MachO_archive_load_hidden_expect_success.s b/llvm/test/ExecutionEngine/JITLink/X86/MachO_archive_load_hidden_expect_success.s
index 249519356f8cb..e52f905628a35 100644
--- a/llvm/test/ExecutionEngine/JITLink/X86/MachO_archive_load_hidden_expect_success.s
+++ b/llvm/test/ExecutionEngine/JITLink/X86/MachO_archive_load_hidden_expect_success.s
@@ -6,6 +6,8 @@
 # RUN:   -o %t/MachO_archive_load_hidden_support.o %s
 # RUN: llvm-jitlink -noexec %t/MachO_archive_load_hidden_support.o \
 # RUN:   -L%t -hidden-lExtraDef
+# RUN: llvm-jitlink -noexec %t/MachO_archive_load_hidden_support.o \
+# RUN:   -load_hidden %t/libExtraDef.a
 #
 # Expect this test to succeed -- ExtraDef should be hidden, but visible to
 # ExtraDefRef as they're linked in the same JITDylib. This tests that we're

diff  --git a/llvm/test/ExecutionEngine/JITLink/X86/MachO_archive_support.s b/llvm/test/ExecutionEngine/JITLink/X86/MachO_archive_support.s
index e3fea53e397b9..77f396075c4eb 100644
--- a/llvm/test/ExecutionEngine/JITLink/X86/MachO_archive_support.s
+++ b/llvm/test/ExecutionEngine/JITLink/X86/MachO_archive_support.s
@@ -5,6 +5,7 @@
 # RUN: llvm-mc -triple x86_64-apple-macosx10.9 -filetype=obj \
 # RUN:   -o %t/MachO_archive_support.o %s
 # RUN: llvm-jitlink -noexec %t/MachO_archive_support.o -lFoo -jd Foo -L%t -lExtraDef
+# RUN: llvm-jitlink -noexec %t/MachO_archive_support.o -lFoo -jd Foo %t/libExtraDef.a
 #
 # Test that archives can be loaded and referenced from other JITDylibs.
 

diff  --git a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
index 8d0fd0403d4db..f581ea131f133 100644
--- a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
+++ b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
@@ -82,9 +82,16 @@ static cl::list<std::string>
               cl::desc("Link against library X in the library search paths"),
               cl::Prefix, cl::cat(JITLinkCategory));
 
-static cl::list<std::string> LibrariesHidden(
-    "hidden-l", cl::desc("Link against library X in the library search paths"),
-    cl::Prefix, cl::cat(JITLinkCategory));
+static cl::list<std::string>
+    LibrariesHidden("hidden-l",
+                    cl::desc("Link against library X in the library search "
+                             "paths with hidden visibility"),
+                    cl::Prefix, cl::cat(JITLinkCategory));
+
+static cl::list<std::string>
+    LoadHidden("load_hidden",
+               cl::desc("Link against library X with hidden visibility"),
+               cl::cat(JITLinkCategory));
 
 static cl::opt<bool> NoExec("noexec", cl::desc("Do not execute loaded code"),
                             cl::init(false), cl::cat(JITLinkCategory));
@@ -1403,6 +1410,8 @@ static Error addObjects(Session &S,
     unsigned InputFileArgIdx =
         InputFiles.getPosition(InputFileItr - InputFiles.begin());
     const std::string &InputFile = *InputFileItr;
+    if (StringRef(InputFile).endswith(".a"))
+      continue;
     auto &JD = *std::prev(IdxToJD.lower_bound(InputFileArgIdx))->second;
     LLVM_DEBUG(dbgs() << "  " << InputFileArgIdx << ": \"" << InputFile
                       << "\" to " << JD.getName() << "\n";);
@@ -1474,14 +1483,41 @@ static Error addLibraries(Session &S,
     }
   });
 
-  // 2. Collect library loads from -lx, -hidden-lx.
+  // 2. Collect library loads
   struct LibraryLoad {
     StringRef LibName;
+    bool IsPath = false;
     unsigned Position;
     StringRef *CandidateExtensions;
     enum { Standard, Hidden } Modifier;
   };
   std::vector<LibraryLoad> LibraryLoads;
+  // Add archive files from the inputs to LibraryLoads.
+  for (auto InputFileItr = InputFiles.begin(), InputFileEnd = InputFiles.end();
+       InputFileItr != InputFileEnd; ++InputFileItr) {
+    StringRef InputFile = *InputFileItr;
+    if (!InputFile.endswith(".a"))
+      continue;
+    LibraryLoad LL;
+    LL.LibName = InputFile;
+    LL.IsPath = true;
+    LL.Position = InputFiles.getPosition(InputFileItr - InputFiles.begin());
+    LL.CandidateExtensions = nullptr;
+    LL.Modifier = LibraryLoad::Standard;
+    LibraryLoads.push_back(std::move(LL));
+  }
+
+  // Add -load_hidden arguments to LibraryLoads.
+  for (auto LibItr = LoadHidden.begin(), LibEnd = LoadHidden.end();
+       LibItr != LibEnd; ++LibItr) {
+    LibraryLoad LL;
+    LL.LibName = *LibItr;
+    LL.IsPath = true;
+    LL.Position = LoadHidden.getPosition(LibItr - LoadHidden.begin());
+    LL.CandidateExtensions = nullptr;
+    LL.Modifier = LibraryLoad::Hidden;
+    LibraryLoads.push_back(std::move(LL));
+  }
   StringRef StandardExtensions[] = {".so", ".dylib", ".a"};
   StringRef ArchiveExtensionsOnly[] = {".a"};
 
@@ -1511,7 +1547,7 @@ static Error addLibraries(Session &S,
 
   // If there are any load-<modified> options then turn on flag overrides
   // to avoid flag mismatch errors.
-  if (!LibrariesHidden.empty())
+  if (!LibrariesHidden.empty() || !LoadHidden.empty())
     S.ObjLayer.setOverrideObjectFlagsWithResponsibilityFlags(true);
 
   // Sort library loads by position in the argument list.
@@ -1520,6 +1556,24 @@ static Error addLibraries(Session &S,
   });
 
   // 3. Process library loads.
+  auto AddArchive = [&](const char *Path, const LibraryLoad &LL)
+      -> Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>> {
+    unique_function<Expected<MaterializationUnit::Interface>(
+        ExecutionSession & ES, MemoryBufferRef ObjBuffer)>
+        GetObjFileInterface;
+    switch (LL.Modifier) {
+    case LibraryLoad::Standard:
+      GetObjFileInterface = getObjectFileInterface;
+      break;
+    case LibraryLoad::Hidden:
+      GetObjFileInterface = getObjectFileInterfaceHidden;
+      break;
+    }
+    return StaticLibraryDefinitionGenerator::Load(
+        S.ObjLayer, Path, S.ES.getExecutorProcessControl().getTargetTriple(),
+        std::move(GetObjFileInterface));
+  };
+
   for (auto &LL : LibraryLoads) {
     bool LibFound = false;
     auto &JD = *std::prev(IdxToJD.lower_bound(LL.Position))->second;
@@ -1530,6 +1584,18 @@ static Error addLibraries(Session &S,
       continue;
     }
 
+    if (LL.IsPath) {
+      auto G = AddArchive(LL.LibName.str().c_str(), LL);
+      if (!G)
+        return createFileError(LL.LibName, G.takeError());
+      JD.addGenerator(std::move(*G));
+      LLVM_DEBUG({
+        dbgs() << "Adding generator for static library " << LL.LibName << " to "
+               << JD.getName() << "\n";
+      });
+      continue;
+    }
+
     // Otherwise look through the search paths.
     auto JDSearchPathsItr = JDSearchPaths.find(&JD);
     if (JDSearchPathsItr != JDSearchPaths.end()) {
@@ -1583,21 +1649,7 @@ static Error addLibraries(Session &S,
           }
           case file_magic::archive:
           case file_magic::macho_universal_binary: {
-            unique_function<Expected<MaterializationUnit::Interface>(
-                ExecutionSession & ES, MemoryBufferRef ObjBuffer)>
-                GetObjFileInterface;
-            switch (LL.Modifier) {
-            case LibraryLoad::Standard:
-              GetObjFileInterface = getObjectFileInterface;
-              break;
-            case LibraryLoad::Hidden:
-              GetObjFileInterface = getObjectFileInterfaceHidden;
-              break;
-            }
-            auto G = StaticLibraryDefinitionGenerator::Load(
-                S.ObjLayer, LibPath.data(),
-                S.ES.getExecutorProcessControl().getTargetTriple(),
-                std::move(GetObjFileInterface));
+            auto G = AddArchive(LibPath.data(), LL);
             if (!G)
               return G.takeError();
             JD.addGenerator(std::move(*G));


        


More information about the llvm-commits mailing list