1、执行init init_array
2、JNI onLoad
更详细的可以参考 《Android so加载深入分析.pdf》
begin.s:__linker_init
1.dlopen函数
dlfcn.cpp
2.整体流程
linker.cpp
do_dlopen函数:
find_library函数:完成对so的解析装载、分配、链接
CallConstructors函数:完成对so中.init和.initarray的执行
3.先看CallConstructors函数,从后面的执行来看
CallFunction("DT_INIT", init_func);
CallArray("DT_INIT_ARRAY", init_array, init_array_count, false);
4.回到find_library函数,看so的具体加载
find_library_internal-load_library
load_library是整个so加载的主控函数
5.so加载的详细步骤
解析装载:
elf_reader.Load函数包括了下列函数:
ReadElfHeader() &&
VerifyElfHeader() &&
ReadProgramHeader() &&
ReserveAddressSpace() &&
LoadSegments() &&
FindPhdr();
所以,so的装载是一种解析式装载,这与dex有一定区别,dex是先加载进行优化验证生成odex,再去解析odex文件,而so更像边解析边装载,在装载过程中主要解析是load段
分配soinfo:
soinfo_alloc函数,生成了一个soinfo结构
链接:
soinfo_link_image函数,也就是soinfo结构链接镜像,从而得到一个以后用的镜像文件
so中用于动态链接的结构就是.dynamic节,即动态节区
a.定位动态节
b.解析动态节
c.加载依赖so
d.重定位:
主要函数为soinfo_relocate,此函数会被soinfo_link_image函数调用
解析重定位项:.rel(.plt安卓并不用),重定位表
导入符号信息:.dynsym, 符号表
修正需要重定位的地址
网友评论