X-Git-Url: https://git.saurik.com/apple/dyld.git/blobdiff_plain/10b92d3b56e938a5c1f5e708ddd1c5d0c2c807d1..refs/heads/master:/src/ImageLoaderMegaDylib.cpp diff --git a/src/ImageLoaderMegaDylib.cpp b/src/ImageLoaderMegaDylib.cpp index a54625d..5978ac3 100644 --- a/src/ImageLoaderMegaDylib.cpp +++ b/src/ImageLoaderMegaDylib.cpp @@ -39,14 +39,14 @@ #include #include #include +#include #include #include "ImageLoaderMegaDylib.h" #include "ImageLoaderMachO.h" -#include "mach-o/dyld_images.h" #include "dyldLibSystemInterface.h" #include "Tracing.h" -#include "dyld.h" +#include "dyld2.h" // from dyld_gdb.cpp extern void addImagesToAllImages(uint32_t infoCount, const dyld_image_info info[]); @@ -196,7 +196,7 @@ bool ImageLoaderMegaDylib::hasDylib(const char* path, unsigned* index) const { const uint8_t* imageNode = ImageLoader::trieWalk(_dylibsTrieStart, _dylibsTrieEnd, path); if ( imageNode == NULL ) { - #if __MAC_OS_X_VERSION_MIN_REQUIRED + #if TARGET_OS_OSX // not all symlinks are recorded as aliases in accelerator tables if ( (strncmp(path, "/usr/lib/", 9) == 0) || (strncmp(path, "/System/Library/", 16) == 0) ) { char resolvedPath[PATH_MAX]; @@ -268,11 +268,21 @@ unsigned ImageLoaderMegaDylib::findImageIndex(const LinkContext& context, const if ( hasDylib(path, &index) ) return index; - // Somehow we found the dylib in the cache, but it is not this literal string, try simple expansions of @rpath - if ( strncmp(path, "@rpath/", 7) == 0 ) { + if ( strncmp(path, "@rpath/libswift", 15) == 0 ) { + // a stable swift app built to run on pre-iOS-12.2 will use @rpath to reference swift dylibs in OS + const char* trailingPath = &path[7]; + char possiblePath[strlen(trailingPath)+16]; + strcpy(possiblePath, "/usr/lib/swift/"); + strcat(possiblePath, trailingPath); + if ( hasDylib(possiblePath, &index) ) + return index; + } + else if ( strncmp(path, "@rpath/", 7) == 0 ) { + // Somehow we found the dylib in the cache, but it is not this literal string, try simple expansions of @rpath std::vector rpathsFromMainExecutable; context.mainExecutable->getRPaths(context, rpathsFromMainExecutable); rpathsFromMainExecutable.push_back("/System/Library/Frameworks/"); + rpathsFromMainExecutable.push_back("/usr/lib/swift/"); const char* trailingPath = &path[7]; for (const char* anRPath : rpathsFromMainExecutable) { if ( anRPath[0] != '/' ) @@ -367,7 +377,7 @@ bool ImageLoaderMegaDylib::incrementCoalIterator(CoalIterator& it) segOffset = read_uleb128(p, end); mh = (mach_header*)getIndexedMachHeader((unsigned)it.imageIndex); if ( uintptr_t segPrefAddress = ImageLoaderMachO::segPreferredAddress(mh, segIndex) ) - it.address = segPrefAddress + segOffset + _slide; + it.address = segPrefAddress + (uintptr_t)segOffset + _slide; else dyld::throwf("BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB has segment %d which is too large", segIndex); break; @@ -452,7 +462,7 @@ void ImageLoaderMegaDylib::updateUsesCoalIterator(CoalIterator& it, uintptr_t va segOffset = read_uleb128(p, end); mh = (mach_header*)getIndexedMachHeader((unsigned)it.imageIndex); if ( uintptr_t segPrefAddress = ImageLoaderMachO::segPreferredAddress(mh, segIndex) ) - address = segPrefAddress + segOffset + _slide; + address = segPrefAddress + (uintptr_t)segOffset + _slide; else dyld::throwf("BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB has segment %d which is too large", segIndex); break; @@ -460,17 +470,17 @@ void ImageLoaderMegaDylib::updateUsesCoalIterator(CoalIterator& it, uintptr_t va address += read_uleb128(p, end); break; case BIND_OPCODE_DO_BIND: - ImageLoaderMachO::bindLocation(context, address, value, type, symbolName, addend, getIndexedPath((unsigned)it.imageIndex), targetImagePath, "weak "); + ImageLoaderMachO::bindLocation(context, 0, address, value, type, symbolName, addend, getIndexedPath((unsigned)it.imageIndex), targetImagePath, "weak ", NULL, _slide); boundSomething = true; address += sizeof(intptr_t); break; case BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: - ImageLoaderMachO::bindLocation(context, address, value, type, symbolName, addend, getIndexedPath((unsigned)it.imageIndex), targetImagePath, "weak "); + ImageLoaderMachO::bindLocation(context, 0, address, value, type, symbolName, addend, getIndexedPath((unsigned)it.imageIndex), targetImagePath, "weak ", NULL, _slide); boundSomething = true; address += read_uleb128(p, end) + sizeof(intptr_t); break; case BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: - ImageLoaderMachO::bindLocation(context, address, value, type, symbolName, addend, getIndexedPath((unsigned)it.imageIndex), targetImagePath, "weak "); + ImageLoaderMachO::bindLocation(context, 0, address, value, type, symbolName, addend, getIndexedPath((unsigned)it.imageIndex), targetImagePath, "weak ", NULL, _slide); boundSomething = true; address += immediate*sizeof(intptr_t) + sizeof(intptr_t); break; @@ -478,7 +488,7 @@ void ImageLoaderMegaDylib::updateUsesCoalIterator(CoalIterator& it, uintptr_t va count = read_uleb128(p, end); skip = read_uleb128(p, end); for (uint32_t i=0; i < count; ++i) { - ImageLoaderMachO::bindLocation(context, address, value, type, symbolName, addend, getIndexedPath((unsigned)it.imageIndex), targetImagePath, "weak "); + ImageLoaderMachO::bindLocation(context, 0, address, value, type, symbolName, addend, getIndexedPath((unsigned)it.imageIndex), targetImagePath, "weak ", NULL, _slide); boundSomething = true; address += skip + sizeof(intptr_t); } @@ -508,7 +518,7 @@ void ImageLoaderMegaDylib::appendImagesNeedingCoalescing(ImageLoader* images[], } -bool ImageLoaderMegaDylib::weakSymbolsBound(unsigned index) +bool ImageLoaderMegaDylib::weakSymbolsBound(unsigned index) const { return ( _stateFlags[index] >= kStateFlagWeakBound ); } @@ -563,7 +573,7 @@ void ImageLoaderMegaDylib::recursiveLoadLibraries(const LinkContext& context, bo recursiveMarkLoaded(context, index); } -unsigned int ImageLoaderMegaDylib::recursiveUpdateDepth(unsigned int maxDepth) +unsigned int ImageLoaderMegaDylib::updateDepth(unsigned int maxDepth) { setDepth(maxDepth); return maxDepth; @@ -721,7 +731,7 @@ void ImageLoaderMegaDylib::processExportNode(const LinkContext& context, const c default: dyld::throwf("unsupported exported symbol kind. flags=%lu at node=%p", flags, exportNode); } - dyld::throwf("unsupported exported symbol node=%p", exportNode); + //dyld::throwf("unsupported exported symbol node=%p", exportNode); } bool ImageLoaderMegaDylib::findInChainedTries(const LinkContext& context, const char* symbolName, unsigned definedImageIndex, @@ -777,24 +787,32 @@ bool ImageLoaderMegaDylib::findInChainedTriesAndDependents(const LinkContext& co } -bool ImageLoaderMegaDylib::flatFindSymbol(const char* name, bool onlyInCoalesced, const ImageLoader::Symbol** sym, const ImageLoader** image) +bool ImageLoaderMegaDylib::flatFindSymbol(const char* name, bool onlyInCoalesced, const ImageLoader::Symbol** sym, const ImageLoader** image, ImageLoader::CoalesceNotifier notifier) { + bool found = false; // check export trie of all in-use images for (unsigned i=0; i < _imageCount ; ++i) { uint16_t imageIndex = _bottomUpArray[i]; if ( _stateFlags[imageIndex] == kStateUnused ) continue; - if ( onlyInCoalesced && (_imageExtras[imageIndex].weakBindingsSize == 0) ) + const macho_header* mh = getIndexedMachHeader(imageIndex); + if ( onlyInCoalesced && (mh->flags & MH_WEAK_DEFINES) == 0 ) continue; const uint8_t* exportNode; const uint8_t* exportTrieEnd; if ( exportTrieHasNode(name, imageIndex, &exportNode, &exportTrieEnd) ) { - *sym = (Symbol*)exportNode; - *image = this; - return true; + if ( notifier ) + notifier((Symbol*)exportNode, this, (mach_header*)getIndexedMachHeader(imageIndex)); + if ( !found ) { + *sym = (Symbol*)exportNode; + *image = this; + found = true; + } + if ( !onlyInCoalesced ) + return true; } } - return false; + return found; } @@ -881,9 +899,10 @@ void ImageLoaderMegaDylib::recursiveInitialization(const LinkContext& context, m if ( context.verboseInit ) dyld::log("dyld: calling initializer function %p in %s\n", func, getIndexedPath(imageIndex)); bool haveLibSystemHelpersBefore = (dyld::gLibSystemHelpers != NULL); - dyld3::kdebug_trace_dyld_duration(DBG_DYLD_TIMING_STATIC_INITIALIZER, (uint64_t)func, 0, ^{ + { + dyld3::ScopedTimer timer(DBG_DYLD_TIMING_STATIC_INITIALIZER, (uint64_t)getIndexedMachHeader(imageIndex), (uint64_t)func, 0); func(context.argc, context.argv, context.envp, context.apple, &context.programVars); - }); + }; bool haveLibSystemHelpersAfter = (dyld::gLibSystemHelpers != NULL); ranSomeInitializers = true; if ( !haveLibSystemHelpersBefore && haveLibSystemHelpersAfter ) { @@ -914,22 +933,20 @@ void ImageLoaderMegaDylib::recursiveInitialization(const LinkContext& context, m void ImageLoaderMegaDylib::recursiveInitialization(const LinkContext& context, mach_port_t thisThread, const char* pathToInitialize, InitializerTimingList& timingInfo, UninitedUpwards&) { - unsigned imageIndex; - if ( hasDylib(pathToInitialize, &imageIndex) ) { - UpwardIndexes upsBuffer[256]; - UpwardIndexes& ups = upsBuffer[0]; - ups.count = 0; - this->recursiveInitialization(context, thisThread, imageIndex, timingInfo, ups); - for (int i=0; i < ups.count; ++i) { - UpwardIndexes upsBuffer2[256]; - UpwardIndexes& ignoreUp = upsBuffer2[0]; - ignoreUp.count = 0; - this->recursiveInitialization(context, thisThread, ups.images[i], timingInfo, ignoreUp); - } + UpwardIndexes upsBuffer[256]; + UpwardIndexes& ups = upsBuffer[0]; + ups.count = 0; + unsigned imageIndex = findImageIndex(context, pathToInitialize); + this->recursiveInitialization(context, thisThread, imageIndex, timingInfo, ups); + for (int i=0; i < ups.count; ++i) { + UpwardIndexes upsBuffer2[256]; + UpwardIndexes& ignoreUp = upsBuffer2[0]; + ignoreUp.count = 0; + this->recursiveInitialization(context, thisThread, ups.images[i], timingInfo, ignoreUp); } } -void ImageLoaderMegaDylib::recursiveBind(const LinkContext& context, bool forceLazysBound, bool neverUnload) +void ImageLoaderMegaDylib::recursiveBind(const LinkContext& context, bool forceLazysBound, bool neverUnload, const ImageLoader* parent) { markAllbound(context); }