void ImageLoader::recursiveLoadLibraries(const LinkContext& context, bool preflightOnly, const RPathChain& loaderRPaths) { if ( fState < dyld_image_state_dependents_mapped ) { // break cycles fState = dyld_image_state_dependents_mapped; // get list of libraries this image needs // 获取image需要的所有的lib的信息 DependentLibraryInfo libraryInfos[fLibraryCount]; this->doGetDependentLibraries(libraryInfos); // get list of rpaths that this image adds std::vector<const char*> rpathsFromThisImage; this->getRPaths(context, rpathsFromThisImage); const RPathChain thisRPaths(&loaderRPaths, &rpathsFromThisImage); // try to load each bool canUsePrelinkingInfo = true; for(unsigned int i=0; i < fLibraryCount; ++i){ ImageLoader* dependentLib; bool depLibReExported = false; bool depLibReRequired = false; bool depLibCheckSumsMatch = false; DependentLibraryInfo& requiredLibInfo = libraryInfos[i]; #if DYLD_SHARED_CACHE_SUPPORT if ( preflightOnly && context.inSharedCache(requiredLibInfo.name) ) { //如果存在于share_cache之中的lib不需要再lode了,因为在shared cache中的lib不会被卸载 // <rdar://problem/5910137> dlopen_preflight() on image in shared cache leaves it loaded but not objc initialized // in preflight mode, don't even load dylib that are in the shared cache because they will never be unloaded setLibImage(i, NULL, false, false); continue; } #endif try { dependentLib = context.loadLibrary(requiredLibInfo.name, true, this->getPath(), &thisRPaths); //static ImageLoader* libraryLocator(const char* libraryName, bool search, const char* origin, const ImageLoader::RPathChain* rpaths) if ( dependentLib == this ) { // 循环引用的检测 // found circular reference, perhaps DYLD_LIBARY_PATH is causing this rdar://problem/3684168 dependentLib = context.loadLibrary(requiredLibInfo.name, false, NULL, NULL); if ( dependentLib != this ) dyld::warn("DYLD_ setting caused circular dependency in %s\n", this->getPath()); } if ( fNeverUnload ) dependentLib->setNeverUnload(); if ( requiredLibInfo.upward ) { } else { dependentLib->fIsReferencedDownward = true; } LibraryInfo actualInfo = dependentLib->doGetLibraryInfo(); depLibReRequired = requiredLibInfo.required; depLibCheckSumsMatch = ( actualInfo.checksum == requiredLibInfo.info.checksum ); //检查checksum是否一致 depLibReExported = requiredLibInfo.reExported; if ( ! depLibReExported ) { // for pre-10.5 binaries that did not use LC_REEXPORT_DYLIB // 10.5之前的程序没有LC_REXPORT_DYLIB字段,使用这种方法检测 depLibReExported = dependentLib->isSubframeworkOf(context, this) || this->hasSubLibrary(context, dependentLib); } // check found library version is compatible // <rdar://problem/89200806> 0xFFFFFFFF is wildcard that matches any version if ( (requiredLibInfo.info.minVersion != 0xFFFFFFFF) && (actualInfo.minVersion < requiredLibInfo.info.minVersion) ) { // record values for possible use by CrashReporter or Finder // 如果依赖库的版本过低就抛出异常 dyld::throwf("Incompatible library version: %s requires version %d.%d.%d or later, but %s provides version %d.%d.%d", this->getShortName(), requiredLibInfo.info.minVersion >> 16, (requiredLibInfo.info.minVersion >> 8) & 0xff, requiredLibInfo.info.minVersion & 0xff, dependentLib->getShortName(), actualInfo.minVersion >> 16, (actualInfo.minVersion >> 8) & 0xff, actualInfo.minVersion & 0xff); } // prebinding for this image disabled if any dependent library changed if ( !depLibCheckSumsMatch ) canUsePrelinkingInfo = false; // prebinding for this image disabled unless both this and dependent are in the shared cache if ( !dependentLib->inSharedCache() || !this->inSharedCache() ) //检测share_cache中是否存在需要的lib canUsePrelinkingInfo = false; //if ( context.verbosePrebinding ) { // if ( !requiredLib.checksumMatches ) // fprintf(stderr, "dyld: checksum mismatch, (%u v %u) for %s referencing %s\n", // requiredLibInfo.info.checksum, actualInfo.checksum, this->getPath(), dependentLib->getPath()); // if ( dependentLib->getSlide() != 0 ) // fprintf(stderr, "dyld: dependent library slid for %s referencing %s\n", this->getPath(), dependentLib->getPath()); //} } catch (const char* msg) {