Android Linker:程序员
http://geek.csdn.net/news/detail/104860?locationNum=11&fps=1数组
关于load_bias_: SO 能够指定加载基址,可是 SO 指定的加载基址可能不是页对齐的,这种状况会致使实际映射地址和指定的加载地址有一个误差,这个误差即是 load_bias_
,以后在针对虚拟地址进行计算时须要使用 load_bias_
修正。普通的 SO 都不会指定加载基址,这时min_vaddr = 0
,则 load_bias_ = load_start_
,即load_bias_
等于加载基址,下文会将 load_bias_
直接称为基址。函数
Section Header:测试
.data保存初始化过的数据,这是普通程序数据的一部分,能够在程序运行期间修改。spa
.rodata保存了只读数据,能够读取但不能修改,例如printf语句中的全部静态字符串封装到该节。.net
.init和.fini保存了进程初始化和结束所用的代码,这一般是由编译器自动添加的。debug
.hash是一个散列表,容许在不对全表元素进行线性搜索的状况下,快速访问全部符号表项。指针
符号表机制radelf调试
符号表保存了程序实现或使用的全部全局变量和函数;若是程序引用一个自身代码未定义的符号,则称之为未定义符号,这类引用必须在静态连接期间用其余目标模块或库解决,或在加载时经过动态连接过程解决。code
实现:
.symtab肯定符号的名称与其值之间的关联,其中名称不是直接以字符串形式出现的,而是表示为某一字符串数组(.strtab)的索引。
.strtab保存了字符串数组(.shstrtab包含了节名称字符串表)。
.hash保存了一个散列表,以帮助快速查找符号。
Symbol table:
上图对应下面的结构:
Num | Value | SIze | Type | Bind | Vis | Ndx | Name |
ELF64_sym.st_value | ELF64_sym.st_size | ELF64_sym.st_info | ELF64_sym.st_info | ELF64_sym.st_shndx | strtab[ELF64_sym.st_name] |
typedef struct elf64_sym { Elf64_Word st_name; // 符号名称,字符串表中的索引 unsigned char st_info; // 类型:NOTYPE,OBJECT,FUNC和绑定属性:STB_LOCAL/STB_GLOBAL/STB_WEAK; unsigned char st_other; // 语义未定义,0 Elf64_Half st_shndx; // section header index 相关节的索引,符号将绑定到该节,此外SHN_ABS指定符号是绝对值,不因重定位而改变,SHN_UNDEF标识未定义符号。 Elf64_Addr st_value; // 符号的值 Elf64_Xword st_size; // 符号的长度,如一个指针的长度或struct对象中包含的字节数。 }Elf64_Sym;
dlopen RTLD_XXX 解析:
RTLD_LAZY:在dlopen返回前,对于动态库中的未定义的符号不执行解析(只对函数引用有效,对于变量引用老是当即解析)。
RTLD_NOW: 须要在dlopen返回前,解析出全部未定义符号,若是解析不出来,在dlopen会返回NULL,错误为:: undefined symbol: xxxx.......
二、做用范围,可与解析方式经过“|”组合使用。
RTLD_GLOBAL:动态库中定义的符号可被其后打开的其它库解析。
RTLD_LOCAL: 与RTLD_GLOBAL做用相反,动态库中定义的符号不能被其后打开的其它库重定位。若是没有指明是RTLD_GLOBAL仍是RTLD_LOCAL,则缺省为RTLD_LOCAL。
三、做用方式
RTLD_NODELETE: 在dlclose()期间不卸载库,而且在之后使用dlopen()从新加载库时不初始化库中的静态变量。这个flag不是POSIX-2001标准。
RTLD_NOLOAD: 不加载库。可用于测试库是否已加载(dlopen()返回NULL说明未加载,不然说明已加载),也可用于改变已加载库的flag,如:先前加载库的flag为RTLD_LOCAL,用dlopen(RTLD_NOLOAD|RTLD_GLOBAL)后flag将变成RTLD_GLOBAL。这个flag不是POSIX-2001标准。
一、解析方式
RTLD_LAZY:在dlopen返回前,对于动态库中的未定义的符号不执行解析(只对函数引用有效,对于变量引用老是当即解析)。
RTLD_NOW: 须要在dlopen返回前,解析出全部未定义符号,若是解析不出来,在dlopen会返回NULL,错误为:: undefined symbol: xxxx.......
二、做用范围,可与解析方式经过“|”组合使用。
RTLD_GLOBAL:动态库中定义的符号可被其后打开的其它库解析。
RTLD_LOCAL: 与RTLD_GLOBAL做用相反,动态库中定义的符号不能被其后打开的其它库重定位。若是没有指明是RTLD_GLOBAL仍是RTLD_LOCAL,则缺省为RTLD_LOCAL。
三、做用方式
RTLD_NODELETE: 在dlclose()期间不卸载库,而且在之后使用dlopen()从新加载库时不初始化库中的静态变量。这个flag不是POSIX-2001标准。
RTLD_NOLOAD: 不加载库。可用于测试库是否已加载(dlopen()返回NULL说明未加载,不然说明已加载),也可用于改变已加载库的flag,如:先前加载库的flag为RTLD_LOCAL,用dlopen(RTLD_NOLOAD|RTLD_GLOBAL)后flag将变成RTLD_GLOBAL。这个flag不是POSIX-2001标准。