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……