[IOS] what are dyld, mach-o, rebase relocation?

Time:2021-12-2

Foreword: the first thing an application brings to users is the startup experience. The shorter the time, the better the experience. Apple recommends that the first loading time of the application should not exceed 400 milliseconds, so we must understand what the startup does. Here are some concepts:

1.DYLD

The full name isdynamic loader, dynamic loader, is the application that apple is responsible for loading. Its running process is the same as the code you write. It will load all dependent frameworks, including the system framework, at startup.

Functions: load mach-o executable file (including rebase file path), load dylib dynamic library, link library, link main program, find main program entry (load of all classes will be called)

1.0 shared cache technology

When the program starts and runs, it will rely on many system dynamic libraries, which will be loaded into memory through dyld (dynamic loader) (the default is / usr / lib / dyld). The system kernel reads the information of the program executable file, makes some preparations, and then gives the work to dyld. Because many programs need to use system dynamic libraries, it is impossible to load all system dynamic libraries when each program is loaded. In order to optimize the program startup speed and make use of dynamic library cache, IOS system adopts shared cache technology to compile all system libraries (private and public) into a large cache file, which isdyld_shared_cache, the cache file is stored in / system / library / caches / com. Apple. Dyld / directory under IOS system.)

1.1 rebase relocation of dyld

First of all, app is actually a binary IPA file, which is full of binary metadata pointers. The IPA data structure downloaded by anyone is the same. Therefore, in order to prevent others from guessing the location of a specific function in memory, Apple will use address space layout randomization technology ASLR (address space layout randomization) To give a random offset to the starting address of the pointer, and one of the dyld tasks is to reposition the metadata pointer in the binary IPA file and correct the starting address. Therefore, reducing the generation of objc metadata is an effective way to reduce the startup time. Specific measures: 1. Appropriately replace class declaration with struct. 2. Reduce the use of classification expansion. 3. Reduce the use of @ objc keyword with swift. 4. Large classes with many attributes modified by final   You can use struct instead, which can reduce the multiple positioning time by 60%. 5. Improved code generation, such as replacing user-defined types with generation functions

Reference link:The effect of repositioning of dyld on startup time is tiktok. Let’s see the relationship between OC and other swift mainstream APP relocations and startup time.

2.Mach-O

It is a kind of file format with internal package exchange: executable file, dynamic library, static library, dyld, target file, etc.

Mach-o is roughly divided into three parts:

Header: the user quickly confirms the file (description information), such as CPU type, file type, etc;

Loadcommands: tell the loader how to set and load binary data;

Data: store data, such as code, string constants, classes, methods, etc;

reference resources:What are IOS – macho files

From Startup to main function:

1: Read load dyld

When the application starts, the system first reads the mach-o file, obtains the dyld path, and loads the dyld

2: Use dyld to load mach-o files, load libraries, and find an entry

1. Start the context information first,   Get the path to correct the offset of the executable file, process environment variables, and get host information

2. Enable shared cache mapping to shared area

3. Start loading

–Add executable

Specific method: call the instantiatefromloadedimage function   Generate an imageloader object and judge whether it is in mach-o format. If so, add it to the sallimages array. If not, throw a format exception

–Load dylib

Traverse dyld_ INSERT_ Libraries environment variable, call loadinserteddylib to load.

4. Start link

–Link mainexecute

–Link the previously inserted library image (loaded by imageloader), and register the caret for each library. Use: register iterposing

5. Start executing initialization function

–Initializemainexecutable initialization   The + load and constructor methods are executed here

–Initialize the dynamic library internally first

–Then initialize the main program and call a series of functions until dyld in notifysingle function is called_ objc_ notify_ Register() function, and in objc_ There will be a call in init_ class_ Loads calls the load method once for all classes

6. Feedback an entrance

–Call getentryfromlc first_ Main gets LC_ Main, the address of the main function is fed back

–If there is no LC_ Main calls getentryfromlc_ Unixthread reads the main thread   Feed back the address of the main thread

3: The dyld process ends when the entry address is obtained   The program goes to the entrance.

Reference link:Startup process with screenshot of calling function

Reference link:  What is the binding or association with objc in the dyld process

Reference link:Dyld loading process

Reference link:Learning notes of dyld source code