diff options
| author | Nick Kledzik <kledzik@apple.com> | 2014-10-16 19:31:28 +0000 |
|---|---|---|
| committer | Nick Kledzik <kledzik@apple.com> | 2014-10-16 19:31:28 +0000 |
| commit | 51720673915e21fbe2756e9ec7a2b38f9b53396c (patch) | |
| tree | 5dda9424a2ca85e2f39c4d62ebb0386f3cbd5e1c /lld/lib/Driver | |
| parent | b38b96ab4c491b914835d005532e8f8e4842c77a (diff) | |
| download | bcm5719-llvm-51720673915e21fbe2756e9ec7a2b38f9b53396c.tar.gz bcm5719-llvm-51720673915e21fbe2756e9ec7a2b38f9b53396c.zip | |
[mach-o] Add support for upward linking
To deal with cycles in shared library dependencies, the darwin linker supports
marking specific link dependencies as "upward". An upward link is when a
lower level library links against a higher level library.
llvm-svn: 219949
Diffstat (limited to 'lld/lib/Driver')
| -rw-r--r-- | lld/lib/Driver/DarwinInputGraph.cpp | 3 | ||||
| -rw-r--r-- | lld/lib/Driver/DarwinLdDriver.cpp | 37 | ||||
| -rw-r--r-- | lld/lib/Driver/DarwinLdOptions.td | 9 |
3 files changed, 37 insertions, 12 deletions
diff --git a/lld/lib/Driver/DarwinInputGraph.cpp b/lld/lib/Driver/DarwinInputGraph.cpp index 5a337086420..1ddde24b534 100644 --- a/lld/lib/Driver/DarwinInputGraph.cpp +++ b/lld/lib/Driver/DarwinInputGraph.cpp @@ -57,7 +57,8 @@ std::error_code MachOFileNode::parse(const LinkingContext &ctx, for (std::unique_ptr<File> &pf : parsedFiles) { // If a dylib was parsed, inform LinkingContext about it. if (SharedLibraryFile *shl = dyn_cast<SharedLibraryFile>(pf.get())) { - _context.registerDylib(reinterpret_cast<mach_o::MachODylibFile*>(shl)); + _context.registerDylib(reinterpret_cast<mach_o::MachODylibFile*>(shl), + _upwardDylib); } _files.push_back(std::move(pf)); } diff --git a/lld/lib/Driver/DarwinLdDriver.cpp b/lld/lib/Driver/DarwinLdDriver.cpp index 5aedd7b9774..41cec564956 100644 --- a/lld/lib/Driver/DarwinLdDriver.cpp +++ b/lld/lib/Driver/DarwinLdDriver.cpp @@ -85,9 +85,14 @@ static std::string canonicalizePath(StringRef path) { } static void addFile(StringRef path, std::unique_ptr<InputGraph> &inputGraph, - bool forceLoad, MachOLinkingContext &ctx) { - inputGraph->addInputElement(std::unique_ptr<InputElement>( - new MachOFileNode(path, forceLoad, ctx))); + MachOLinkingContext &ctx, bool loadWholeArchive, + bool upwardDylib) { + auto node = llvm::make_unique<MachOFileNode>(path, ctx); + if (loadWholeArchive) + node->setLoadWholeArchive(); + if (upwardDylib) + node->setUpwardDylib(); + inputGraph->addInputElement(std::move(node)); } // Export lists are one symbol per line. Blank lines are ignored. @@ -165,7 +170,7 @@ static std::error_code parseFileList(StringRef fileListPath, if (ctx.testingFileUsage()) { diagnostics << "Found filelist entry " << canonicalizePath(path) << '\n'; } - addFile(path, inputGraph, forceLoad, ctx); + addFile(path, inputGraph, ctx, forceLoad, false); buffer = lineAndRest.second; } return std::error_code(); @@ -638,34 +643,44 @@ bool DarwinLdDriver::parse(int argc, const char *argv[], // Handle input files for (auto &arg : *parsedArgs) { + bool upward; ErrorOr<StringRef> resolvedPath = StringRef(); switch (arg->getOption().getID()) { default: continue; case OPT_INPUT: - addFile(arg->getValue(), inputGraph, globalWholeArchive, ctx); + addFile(arg->getValue(), inputGraph, ctx, globalWholeArchive, false); + break; + case OPT_upward_library: + addFile(arg->getValue(), inputGraph, ctx, false, true); break; case OPT_l: + case OPT_upward_l: + upward = (arg->getOption().getID() == OPT_upward_l); resolvedPath = ctx.searchLibrary(arg->getValue()); if (!resolvedPath) { - diagnostics << "Unable to find library -l" << arg->getValue() << "\n"; + diagnostics << "Unable to find library for " << arg->getSpelling() + << arg->getValue() << "\n"; return false; } else if (ctx.testingFileUsage()) { - diagnostics << "Found library " + diagnostics << "Found " << (upward ? "upward " : " ") << "library " << canonicalizePath(resolvedPath.get()) << '\n'; } - addFile(resolvedPath.get(), inputGraph, globalWholeArchive, ctx); + addFile(resolvedPath.get(), inputGraph, ctx, globalWholeArchive, upward); break; case OPT_framework: + case OPT_upward_framework: + upward = (arg->getOption().getID() == OPT_upward_framework); resolvedPath = ctx.findPathForFramework(arg->getValue()); if (!resolvedPath) { - diagnostics << "Unable to find -framework " << arg->getValue() << "\n"; + diagnostics << "Unable to find framework for " + << arg->getSpelling() << " " << arg->getValue() << "\n"; return false; } else if (ctx.testingFileUsage()) { - diagnostics << "Found framework " + diagnostics << "Found " << (upward ? "upward " : " ") << "framework " << canonicalizePath(resolvedPath.get()) << '\n'; } - addFile(resolvedPath.get(), inputGraph, globalWholeArchive, ctx); + addFile(resolvedPath.get(), inputGraph, ctx, globalWholeArchive, upward); break; case OPT_filelist: if (std::error_code ec = parseFileList(arg->getValue(), inputGraph, diff --git a/lld/lib/Driver/DarwinLdOptions.td b/lld/lib/Driver/DarwinLdOptions.td index 22d6e354906..fff976cf06f 100644 --- a/lld/lib/Driver/DarwinLdOptions.td +++ b/lld/lib/Driver/DarwinLdOptions.td @@ -115,9 +115,18 @@ def syslibroot : Separate<["-"], "syslibroot">, MetaVarName<"<dir>">, def l : Joined<["-"], "l">, MetaVarName<"<libname>">, HelpText<"Base name of library searched for in -L directories">; +def upward_l : Joined<["-"], "upward-l">, + MetaVarName<"<libname>">, + HelpText<"Base name of upward library searched for in -L directories">; def framework : Separate<["-"], "framework">, MetaVarName<"<name>">, HelpText<"Base name of framework searched for in -F directories">; +def upward_framework : Separate<["-"], "upward_framework">, + MetaVarName<"<name>">, + HelpText<"Base name of upward framework searched for in -F directories">; +def upward_library : Separate<["-"], "upward_library">, + MetaVarName<"<path>">, + HelpText<"path to upward dylib to link with">; def filelist : Separate<["-"], "filelist">, MetaVarName<"<path>">, HelpText<"file containing paths to input files">; |

