这是我参与8月更文挑战的第12天,活动详情查看:8月更文挑战
1 dyld加载流程分析(下)
上文说到_objc_init中调用了_dyld_objc_notify_register(&map_images, load_images, unmap_image)对registerObjCNotifiers中的sNotifyObjCMapped,sNotifyObjCInit,sNotifyObjCUnmapped,进行了赋值。那么sNotifyObjCMapped,sNotifyObjCInit是在哪里调用的呢
1.1 sNotifyObjCMapped 的调用
在dyld 源码中搜索sNotifyObjCMapped,看到其在notifyBatchPartial中被调用。

在搜索notifyBatchPartial在哪里被调用,发现其在被赋值后就直接被调用了。

1.2 sNotifyObjCInit 的调用
在dyld 源码中搜索sNotifyObjCInit,发现也是赋值后,sNotifyObjCMapped调用之后调用。

1.3 load 函数的调用
load函数是哪里调用的呢?在load函数打个断点,然后输入bt查看,发现是在load_images里面。

那么load_images 又是如何调用的load函数呢。 首先找到load_images,看到这里有一个prepare_load_methods。

点击进去看到prepare_load_methods有主类和分类的load方法

先看主类的load 方法,看到这里会进行递归,将类的所有父类也调用schedule_class_load方法。然后会add_class_to_loadable_list。

点进去看到有getLoadMethod。

在点进去看到这里将类中的load方法imp取了出来。

在看回getLoadMethod,发现其将class 添加到loadable_classes里面,这里的method就是之前返回的load 方法的imp。
再来看分类的load方法发现实现差不多,只是添加到了另一个字典loadable_categories里面。

再回到load_images 方法,看到有call_load_methods方法。

看到call_load_methods里面有call_class_loads和call_category_loads方法。这里做的就是递归将所有的loadable_classes里面的类和loadable_categories里面的分类的load方法进行调用。

看一下call_class_loads,发现确实是将loadable_classes里面的class和method取出来,然后进行load方法的调用。

看一下分类的实现方法,也是一摸摸一样样的。

1.4 CXX 方法的调用
在main函数中添加一个CXX 方法。

运行后发现,是在load方法之后。

在CXX 方法里面打个断点,然后输入bt查看方法栈,发现是在doModInitFunctions里面调用的。

doModInitFunctions是在doInitialization里面调用的,而doInitialization是在notify之前,也就是load方法之前的,为什么这里反而cxx方法在load之后调用呢?这里因为这里的doInitialization是objc的镜像文件初始化,而不是工程的初始化,所以工程里的cxx方法在load后面调用。证明一下,在_objc_init中添加cxx方法。

然后运行,可以看到在_objc_init中的c++函数确实是在load方法之前的。

1.5 main 函数的调用
dyld是如何找到main函数并对其进行调用的呢? 又回到最初的起点:dyld_start。看到这里的最后一行有一个跳转到main函数的地方。

在mac上运行一下证明,在cXX函数打个断点,然后进入汇编模式。

往下走,看到jmpq *%rax,也就是之前说会跳转到main函数的地方。

读取一下寄存器,发现rax就是main函数。所以jmpq *%rax 也就是调用main函数。

如果把main函数名字改成别的,那么还能进行调用吗?

运行一下,发现了报错。可以知道main是写定的函数,写入内存,读取到dyld,如果修改了main函数的名称,那么程序就会报错。

1.6 dyld流程图






















![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)