diff options
Diffstat (limited to 'lld/lib')
| -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 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp | 15 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp | 2 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp | 2 |
6 files changed, 53 insertions, 15 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">; diff --git a/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp b/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp index 3b9c6fb9973..f23bfc86a6e 100644 --- a/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp +++ b/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp @@ -598,7 +598,7 @@ Writer &MachOLinkingContext::writer() const { } MachODylibFile* MachOLinkingContext::loadIndirectDylib(StringRef path) { - std::unique_ptr<MachOFileNode> node(new MachOFileNode(path, false, *this)); + std::unique_ptr<MachOFileNode> node(new MachOFileNode(path, *this)); std::error_code ec = node->parse(*this, llvm::errs()); if (ec) return nullptr; @@ -668,15 +668,26 @@ bool MachOLinkingContext::createImplicitFiles( } -void MachOLinkingContext::registerDylib(MachODylibFile *dylib) const { +void MachOLinkingContext::registerDylib(MachODylibFile *dylib, + bool upward) const { _allDylibs.insert(dylib); _pathToDylibMap[dylib->installName()] = dylib; // If path is different than install name, register path too. if (!dylib->path().equals(dylib->installName())) _pathToDylibMap[dylib->path()] = dylib; + if (upward) + _upwardDylibs.insert(dylib); } +bool MachOLinkingContext::isUpwardDylib(StringRef installName) const { + for (MachODylibFile *dylib : _upwardDylibs) { + if (dylib->installName().equals(installName)) + return true; + } + return false; +} + ArchHandler &MachOLinkingContext::archHandler() const { if (!_archHandler) _archHandler = ArchHandler::create(_arch); diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp index e41d9189640..531479de250 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp @@ -808,7 +808,7 @@ std::error_code MachOFileLayout::writeLoadCommands() { for (const DependentDylib &dep : _file.dependentDylibs) { dylib_command* dc = reinterpret_cast<dylib_command*>(lc); uint32_t size = sizeof(dylib_command) + pointerAlign(dep.path.size()+1); - dc->cmd = LC_LOAD_DYLIB; + dc->cmd = dep.kind; dc->cmdsize = size; dc->dylib.name = sizeof(dylib_command); // offset dc->dylib.timestamp = 0; // FIXME diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp index 7147c1222c5..d3ee9f0be29 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp @@ -935,6 +935,8 @@ void Util::addDependentDylibs(const lld::File &atomFile,NormalizedFile &nFile) { DylibInfo &info = _dylibInfo[dep.path]; if (info.hasWeak && !info.hasNonWeak) dep.kind = llvm::MachO::LC_LOAD_WEAK_DYLIB; + else if (_context.isUpwardDylib(dep.path)) + dep.kind = llvm::MachO::LC_LOAD_UPWARD_DYLIB; } } |

