Application loading principles library: executable binary files that are loaded into memory file type: static library. A dynamic library.so.dll both are the difference between links
We can directly open the project directory Products under the. App file to find the executable file drag to the terminal can directly run
Library – Maps to in-memory images
/ / output
+[ViewController load]
(lldb) image list
[ 0] 404C4B96-E4D1- 3501.-BBDA-B6895DA2626A 0x000000010080c000
[ 1] 1AC765614 -F9A- 34B1-BA7C- 4516.CACEAED7 0x0000000101122000 /usr/lib/dyld
[ 2] 2A92FC99- 72.A9- 38ED- 8 -DDD-AF4C25080124 0x0000000100820000/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes /iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib/dyld_sim [3] C2A182884 -AA2- 3189.-A1C6-5963E370DE4C 0x00007fff2071f000/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes /iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/Foundation.framework/FoundationCopy the code
Next look at the DYld dynamic linker
Dyldbootstrap jump Looks for start
// Focus on return
return dyld::_main((macho_header*)appsMachHeader, appsSlide, argc, argv, envp, apple, startGlue);
Copy the code
_main jump
getHostInfo jump
/ / instantiateFromLoadedImage image file loader
CRSetCrashLogMessage(sLoadingCrashMessage);
// instantiate ImageLoader for main executable
sMainExecutable = instantiateFromLoadedImage(mainExecutableMH, mainExecutableSlide, sExecPath);
gLinkContext.mainExecutable = sMainExecutable;
gLinkContext.mainExecutableCodeSigned = hasCodeSignatureLoadCommand(mainExecutableMH);
Copy the code
instantiateFromLoadedImage jump
addImage jump
instantiateMainExecutable jump
AllImagesCount Number of all image files
RunInitializers Jump is then executed
// Key code
processInitializers(context, thisThread, timingInfo, up);
context.notifyBatch(dyld_image_state_initialized, false);
Copy the code
processInitializers jump
recursiveInitialization jump
// Key code
context.notifySingle(dyld_image_state_dependents_initialized, this, &timingInfo);
// initialize this image
bool hasInitializers = this->doInitialization(context);
Copy the code
notifySingle jump
void (*notifySingle)(dyld_image_states, const ImageLoader* image, InitializerTimingList*);
Copy the code
Single Registration Notice
notifyMonitoringDyld sNotifyObjCInit
registerObjCNotifiers jump
sNotifyObjCInit = init;
Single image file loading -> _dyLD_OBJC_NOTIFY_register
registerObjCNotifiers
_os_object_init jump
libdispatch_init jump
Found _os_object_init ();
libSystem_initializer jump
// The key code calls libdispatch_init
libdispatch_init();
_libSystem_ktrace_init_func(LIBDISPATCH);
Copy the code
doModInitFunctions jump
// The key code libSystemInitialized
if(! dyld::gProcessInfo->libSystemInitialized ) {// <rdar://problem/17973316> libSystem initializer must run first
const char* installPath = getInstallPath();
if ( (installPath == NULL) || (strcmp(installPath, libSystemPath(context)) ! =0) )
dyld::throwf("initializer in image (%s) that does not link with libSystem.dylib\n".this->getPath());
}
func(context.argc, context.argv, context.envp, context.apple, &context.programVars);
Copy the code
DoModInitFunctions are called in ImageLoaderMachO and the image file is initialized to doModInitFunctions
The process to comb
_os_object_init (libdispatch) -> _objc_init (libobjc)
_objc_init jump
_dyld_objc_notify_register jump
registerObjCNotifiers jump
// Assignment code
// record functions to call
sNotifyObjCMapped = mapped;
sNotifyObjCInit = init;
sNotifyObjCUnmapped = unmapped;
Copy the code
Call doModInitFunctions
DoInitialization call
// initialize this image
bool hasInitializers = this->doInitialization(context);
Copy the code
SNotifyObjCMapped call
static void notifyBatchPartial(dyld_image_states state, bool orLater, dyld_image_state_change_handler onlyHandler, bool preflightOnly, boolCall sNotifyObjCMapped onlyObjCMappedNotification)if( objcImageCount ! =0 ) {
dyld3::ScopedTimer timer(DBG_DYLD_TIMING_OBJC_MAP, 0.0.0);
uint64_t t0 = mach_absolute_time();
(*sNotifyObjCMapped)(objcImageCount, paths, mhs);
uint64_t t1 = mach_absolute_time();
ImageLoader::fgTotalObjCSetupTime += (t1-t0);
}
Copy the code
notifyBatchPartial jump
RegisterObjCNotifiers Registers calls to notifyBatchPartial
SNotifyObjCInit notifySingle calls sNotifyObjCInit
The ImageLoader recursive loop process calls notifySingle
// The key code is assigned first and then initialized
context.notifySingle(dyld_image_state_dependents_initialized, this, &timingInfo);
// initialize this image - initializes all image-load_images assignments
bool hasInitializers = this->doInitialization(context);
// let anyone know we finished initializing this image
fState = dyld_image_state_initialized;
oldState = fState;
context.notifySingle(dyld_image_state_initialized, this.NULL);
Copy the code
Bittorrent first calls +[ViewController Load], then calls doModInitFunctions, which appears to be the opposite of what is written above
All image files are initialized internally -> load method -> HL_objc
load_images jump
prepare_load_methods jump
RealizeClassWithoutSwift implements classification
schedule_class_load jump
schedule_class_load(cls->getSuperclass());
add_class_to_loadable_list jump
I’m going to add it to loadable_classes, which is the equivalent array, which is going to hold the model, which is going to give me the dictionary for the index, which is going to give me the value for the index. Loadable_classes collects all load methods (including class methods, class methods)
loadable_classes[loadable_classes_used].cls = cls;
loadable_classes[loadable_classes_used].method = method;
loadable_classes_used++;
> getLoadMethod jump
if (0 == strcmp(name, "load")) {
return meth.imp(false);
}
Copy the code
add_category_to_loadable_list jump
_category_getLoadMethod jump
mlist = ISA()->data()->ro()->baseMethods() // Recurse all baseMethods
return meth.imp(false); // Return to the past
Copy the code
call_load_methods jump
Call_class_loads is called at call_load_methods (*load_method)(CLS, @selector(load));
Call_category_loads is called at call_load_methods (*load_method)(CLS, @selector(load));
To be continued……