X-Git-Url: https://git.saurik.com/apple/ld64.git/blobdiff_plain/a645023da60d22e86be13f7b4d97adeff8bc6665..b1f7435d66a93f03b77932b3a9ad8a83ce5e1ebc:/src/ld/passes/dylibs.cpp diff --git a/src/ld/passes/dylibs.cpp b/src/ld/passes/dylibs.cpp index 2b4452b..af1ecf6 100644 --- a/src/ld/passes/dylibs.cpp +++ b/src/ld/passes/dylibs.cpp @@ -52,10 +52,6 @@ void doPass(const Options& opts, ld::Internal& state) { // const bool log = false; - // only optimize dylibs in final linked images - if ( opts.outputKind() == Options::kObjectFile ) - return; - // clear "willRemoved" bit on all dylibs for (std::vector::iterator it = state.dylibs.begin(); it != state.dylibs.end(); ++it) { ld::dylib::File* aDylib = *it; @@ -72,12 +68,61 @@ void doPass(const Options& opts, ld::Internal& state) // set "willRemoved" bit on any unused explicit when -dead_strip_dylibs is used if ( opts.deadStripDylibs() && !aDylib->providedExportAtom() ) aDylib->setWillBeRemoved(true); - } - - + } // remove unused dylibs state.dylibs.erase(std::remove_if(state.dylibs.begin(), state.dylibs.end(), WillBeUsed()), state.dylibs.end()); + + // automatically weak-import dylibs when all symbols from it are weak-imported + for (std::vector::iterator sit=state.sections.begin(); sit != state.sections.end(); ++sit) { + ld::Internal::FinalSection* sect = *sit; + for (std::vector::iterator ait=sect->atoms.begin(); ait != sect->atoms.end(); ++ait) { + const ld::Atom* atom = *ait; + const ld::Atom* target = NULL; + bool targetIsWeakImport = false; + for (ld::Fixup::iterator fit = atom->fixupsBegin(), end=atom->fixupsEnd(); fit != end; ++fit) { + if ( fit->firstInCluster() ) + target = NULL; + switch ( fit->binding ) { + case ld::Fixup::bindingsIndirectlyBound: + target = state.indirectBindingTable[fit->u.bindingIndex]; + targetIsWeakImport = fit->weakImport; + break; + case ld::Fixup::bindingDirectlyBound: + target = fit->u.target; + targetIsWeakImport = fit->weakImport; + break; + default: + break; + } + if ( (target != NULL) && (target->definition() == ld::Atom::definitionProxy) ) { + ld::Atom::WeakImportState curWI = target->weakImportState(); + if ( curWI == ld::Atom::weakImportUnset ) { + // first use of this proxy, set weak-import based on this usage + (const_cast(target))->setWeakImportState(targetIsWeakImport); + } + else { + // proxy already has weak-importness set, check for weakness mismatch + bool curIsWeakImport = (curWI == ld::Atom::weakImportTrue); + if ( curIsWeakImport != targetIsWeakImport ) { + // found mismatch + switch ( opts.weakReferenceMismatchTreatment() ) { + case Options::kWeakReferenceMismatchError: + throwf("mismatching weak references for symbol: %s", target->name()); + case Options::kWeakReferenceMismatchWeak: + (const_cast(target))->setWeakImportState(true); + break; + case Options::kWeakReferenceMismatchNonWeak: + (const_cast(target))->setWeakImportState(false); + break; + } + } + } + } + } + } + } + }