X-Git-Url: https://git.saurik.com/apple/ld64.git/blobdiff_plain/60ce07c1e7dbeedd94a57ba21c14ff07c4ada4db..afe874b1634377ecb27057ee76deb04915bb34d7:/src/ld/passes/dylibs.cpp diff --git a/src/ld/passes/dylibs.cpp b/src/ld/passes/dylibs.cpp index 2b4452b..47b1647 100644 --- a/src/ld/passes/dylibs.cpp +++ b/src/ld/passes/dylibs.cpp @@ -72,12 +72,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; + } + } + } + } + } + } + } + }