2929#include " llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h"
3030#include " llvm/ExecutionEngine/Orc/EPCEHFrameRegistrar.h"
3131#include " llvm/ExecutionEngine/Orc/ExecutionUtils.h"
32+ #include " llvm/ExecutionEngine/Orc/GetTapiInterface.h"
3233#include " llvm/ExecutionEngine/Orc/IndirectionUtils.h"
3334#include " llvm/ExecutionEngine/Orc/JITLinkRedirectableSymbolManager.h"
3435#include " llvm/ExecutionEngine/Orc/JITLinkReentryTrampolines.h"
5859#include " llvm/Object/COFF.h"
5960#include " llvm/Object/MachO.h"
6061#include " llvm/Object/ObjectFile.h"
62+ #include " llvm/Object/TapiUniversal.h"
6163#include " llvm/Support/CommandLine.h"
6264#include " llvm/Support/Debug.h"
6365#include " llvm/Support/InitLLVM.h"
@@ -140,6 +142,20 @@ static cl::list<std::string>
140142 cl::desc (" Link against library X with hidden visibility" ),
141143 cl::cat(JITLinkCategory));
142144
145+ static cl::list<std::string>
146+ LibrariesWeak (" weak-l" ,
147+ cl::desc (" Emulate weak link against library X. Must resolve "
148+ " to a TextAPI file, and all symbols in the "
149+ " interface will resolve to null." ),
150+ cl::Prefix, cl::cat(JITLinkCategory));
151+
152+ static cl::list<std::string> WeakLibraries (
153+ " weak_library" ,
154+ cl::desc (" Emulate weak link against library X. X must point to a "
155+ " TextAPI file, and all symbols in the interface will "
156+ " resolve to null" ),
157+ cl::cat(JITLinkCategory));
158+
143159static cl::opt<bool > SearchSystemLibrary (
144160 " search-sys-lib" ,
145161 cl::desc (" Add system library paths to library search paths" ),
@@ -2100,6 +2116,27 @@ static SmallVector<StringRef, 5> getSearchPathsFromEnvVar(Session &S) {
21002116 return PathVec;
21012117}
21022118
2119+ static Expected<std::unique_ptr<DefinitionGenerator>>
2120+ LoadLibraryWeak (Session &S, StringRef InterfacePath) {
2121+ auto TapiFileBuffer = getFile (InterfacePath);
2122+ if (!TapiFileBuffer)
2123+ return TapiFileBuffer.takeError ();
2124+
2125+ auto Tapi =
2126+ object::TapiUniversal::create ((*TapiFileBuffer)->getMemBufferRef ());
2127+ if (!Tapi)
2128+ return Tapi.takeError ();
2129+
2130+ auto Symbols = getInterfaceFromTapiFile (S.ES , **Tapi);
2131+ if (!Symbols)
2132+ return Symbols.takeError ();
2133+
2134+ return std::make_unique<EPCDynamicLibrarySearchGenerator>(
2135+ S.ES , [Symbols = std::move (*Symbols)](const SymbolStringPtr &Sym) {
2136+ return Symbols.count (Sym);
2137+ });
2138+ }
2139+
21032140static Error addLibraries (Session &S,
21042141 const std::map<unsigned , JITDylib *> &IdxToJD,
21052142 const DenseSet<unsigned > &LazyLinkIdxs) {
@@ -2142,11 +2179,12 @@ static Error addLibraries(Session &S,
21422179 bool IsPath = false ;
21432180 unsigned Position;
21442181 ArrayRef<StringRef> CandidateExtensions;
2145- enum { Standard, Hidden } Modifier;
2182+ enum { Standard, Hidden, Weak } Modifier;
21462183 };
21472184
21482185 // Queue to load library as in the order as it appears in the argument list.
21492186 std::deque<LibraryLoad> LibraryLoadQueue;
2187+
21502188 // Add archive files from the inputs to LibraryLoads.
21512189 for (auto InputFileItr = InputFiles.begin (), InputFileEnd = InputFiles.end ();
21522190 InputFileItr != InputFileEnd; ++InputFileItr) {
@@ -2173,9 +2211,23 @@ static Error addLibraries(Session &S,
21732211 LL.Modifier = LibraryLoad::Hidden;
21742212 LibraryLoadQueue.push_back (std::move (LL));
21752213 }
2214+
2215+ // Add -weak_library arguments to LibraryLoads.
2216+ for (auto LibItr = WeakLibraries.begin (), LibEnd = WeakLibraries.end ();
2217+ LibItr != LibEnd; ++LibItr) {
2218+ LibraryLoad LL;
2219+ LL.LibName = *LibItr;
2220+ LL.IsPath = true ;
2221+ LL.Position = WeakLibraries.getPosition (LibItr - WeakLibraries.begin ());
2222+ LL.CandidateExtensions = {};
2223+ LL.Modifier = LibraryLoad::Weak;
2224+ LibraryLoadQueue.push_back (std::move (LL));
2225+ }
2226+
21762227 StringRef StandardExtensions[] = {" .so" , " .dylib" , " .dll" , " .a" , " .lib" };
21772228 StringRef DynLibExtensionsOnly[] = {" .so" , " .dylib" , " .dll" };
21782229 StringRef ArchiveExtensionsOnly[] = {" .a" , " .lib" };
2230+ StringRef InterfaceExtensionsOnly = {" .tbd" };
21792231
21802232 // Add -lx arguments to LibraryLoads.
21812233 for (auto LibItr = Libraries.begin (), LibEnd = Libraries.end ();
@@ -2201,6 +2253,18 @@ static Error addLibraries(Session &S,
22012253 LibraryLoadQueue.push_back (std::move (LL));
22022254 }
22032255
2256+ // Add -weak-lx arguments to LibraryLoads.
2257+ for (auto LibWeakItr = LibrariesWeak.begin (),
2258+ LibWeakEnd = LibrariesWeak.end ();
2259+ LibWeakItr != LibWeakEnd; ++LibWeakItr) {
2260+ LibraryLoad LL;
2261+ LL.LibName = *LibWeakItr;
2262+ LL.Position = LibrariesWeak.getPosition (LibWeakItr - LibrariesWeak.begin ());
2263+ LL.CandidateExtensions = InterfaceExtensionsOnly;
2264+ LL.Modifier = LibraryLoad::Weak;
2265+ LibraryLoadQueue.push_back (std::move (LL));
2266+ }
2267+
22042268 // Sort library loads by position in the argument list.
22052269 llvm::sort (LibraryLoadQueue,
22062270 [](const LibraryLoad &LHS, const LibraryLoad &RHS) {
@@ -2220,6 +2284,9 @@ static Error addLibraries(Session &S,
22202284 GetObjFileInterface = getObjectFileInterfaceHidden;
22212285 S.HiddenArchives .insert (Path);
22222286 break ;
2287+ case LibraryLoad::Weak:
2288+ llvm_unreachable (" Unsupported" );
2289+ break ;
22232290 }
22242291
22252292 auto &LinkLayer = S.getLinkLayer (LazyLinkIdxs.count (LL.Position ));
@@ -2266,11 +2333,26 @@ static Error addLibraries(Session &S,
22662333
22672334 // If this is the name of a JITDylib then link against that.
22682335 if (auto *LJD = S.ES .getJITDylibByName (LL.LibName )) {
2336+ if (LL.Modifier == LibraryLoad::Weak)
2337+ return make_error<StringError>(
2338+ " Can't use -weak-lx or -weak_library to load JITDylib " +
2339+ LL.LibName ,
2340+ inconvertibleErrorCode ());
22692341 JD.addToLinkOrder (*LJD);
22702342 continue ;
22712343 }
22722344
22732345 if (LL.IsPath ) {
2346+ // Must be -weak_library.
2347+ if (LL.Modifier == LibraryLoad::Weak) {
2348+ if (auto G = LoadLibraryWeak (S, LL.LibName )) {
2349+ JD.addGenerator (std::move (*G));
2350+ continue ;
2351+ } else
2352+ return G.takeError ();
2353+ }
2354+
2355+ // Otherwise handle archive.
22742356 auto G = AddArchive (JD, LL.LibName .c_str (), LL);
22752357 if (!G)
22762358 return createFileError (LL.LibName , G.takeError ());
@@ -2337,6 +2419,14 @@ static Error addLibraries(Session &S,
23372419 });
23382420 break ;
23392421 }
2422+ case file_magic::tapi_file:
2423+ assert (LL.Modifier == LibraryLoad::Weak &&
2424+ " TextAPI file not being loaded as weak?" );
2425+ if (auto G = LoadLibraryWeak (S, LibPath.data ()))
2426+ JD.addGenerator (std::move (*G));
2427+ else
2428+ return G.takeError ();
2429+ break ;
23402430 default :
23412431 // This file isn't a recognized library kind.
23422432 LLVM_DEBUG ({
0 commit comments