Relocation section '.rel.plt' at offset 0x2c8 contains 1 entries: Offset Info Type Symbol's Value Symbol's Name 000013b8 00000e07 R_386_JUMP_SLOT 00000000 printf
| 这个值假如在文档中找到0x13b8(这是相对偏移量)的内容就是
由于intel 是little endian 所以这个数翻译过来是0x02e6,那这里是什么呢?
2e0: ff a3 0c 00 00 00 jmp *0xc(離) 2e6: 68 00 00 00 00 push x0 2eb: e9 e0 ff ff ff jmp 2d0
|
这下就会全部明白了吧。他就是压入0x0(这其实就是我们前面的printf在rel节中的索引数0------他是第一项)。而下面跳到的就是2d0(这是个相对转移)处
2d0: ff b3 04 00 00 00 pushl 0x4(離) 2d6: ff a3 08 00 00 00 jmp *0x8(離)
|
前面已说过離得到的是got的起始地址,所以这就是压got[1]入栈,再转移到got[2]中所包含的地址去,您能够看前面在elf_machine_runtime_setup中的2162行和2167行,他就是这个动态链接库自身的struct link_map*的指针,和_dl_runtime_resolve所在的地址。下面一张图就能够形象的说明这一点。

假如是第一次的函数调用,他所走的路线就是我在上图中用红线标出的,而要是在第二次以后调用,那就是蓝线所标明的。原因在前面的代码中已给出了。
82 int _dl_relocate_object (struct link_map* lmap,int lazy_mode) 83 { 84 elf_machine_runtime_setup(lmap,lazy_mode); 85 elf_machine_lazy_rel (lmap,lazy_mode); 86 87 }
|
这里要分两步来完成,第一步的elf_machine_runtime_setup是把这个动态链接库所代表的数据结构lmap的地址写入一个在ELF文档中特别地方,而elf_machine_lazy_rel是对任何的要被调用的动态链接库外部的函数重定位的实现。这两步很重要,因为假如没有这两步,那要实现动态链接库的函数动态解析是不可能的,这个您能够在上面的 相对转移,绝对转移 中的论述得到周详的了解。
54 void elf_machine_runtime_setup(struct link_map* lmap,int lazy_mode) 55 { 56 Elf32_Addr *got; 57 58 got = (Elf32_Addr *) lmap->l_info[DT_PLTGOT].d_un.d_ptr; 59 60 got[2]=&_dl_runtime_resolve 61 got[1]=lmap; 62 }
|
明显的,那个被写入的ELF文档中的地址就是他的DT_PLTGOT节中的第二个项目-----第60行的内容。而写入第一项的内容就是要调动的处理函数的地址,这一点在后面所提到的动态解析中的入口地址。
64 void elf_machine_lazy_rel (struct link_map* lmap,int lazy_mode) 65 { 66 Elf32_Addr rel_addr=lmap->l_info[DT_REL].d_un.d_ptr; 67 int rel_num=lmap->l_info[DT_RELSZ].d_un.d_ptr; 68 int i; 69 Elf32_Addr l_addr=lmap->l_addr; 70 71 Elf32_Rel* rel; 72 for (i=0,rel=(Elf32_Rel*)rel_addr;i 73 { 74 Elf32_Addr *const reloc_addr = (void *) (l_addr rel->r_offset); 75 *reloc_addr =l_addr; 76 } 77 78 }
|
这里的elf_machine_lazy_rel我只列出了在intel平台下的那种情况,其他的还要特别的内容,在这里很明显,我们只是写把原来的在ELF文档的内容加上一个文档加载的地址,这就是lazy mode,因为动态链接库的函数很可能在整个程式运行中不会被调用--------这一点和虚拟内存管理的原理是相同的。
四、动态链接库函数的解析
前面的60行的代码----设定了动态解析的入口地址和给出的在动态链接库中的在达到调用一个外部函数时任何的函数路线,已到了 _dl_runtime_resolve处
2087 # define ELF_MACHINE_RUNTIME_TRAMPOLINE asm (" 2088 .text
2089 .globl _dl_runtime_resolve
2090 .type _dl_runtime_resolve, @function
2091 .align 16
2092 _dl_runtime_resolve:
2093 pushl 陎
2094 pushl 靫
2095 pushl 韝
2096 movl 16(%esp), 韝
2097 movl 12(%esp), 陎
2098 call fixup
2099 popl 韝
2100 popl 靫
2101 xchgl 陎, (%esp)
2102 ret 2103 .size _dl_runtime_resolve, .-_dl_runtime_resolve
文章整理:西部数码--专业提供域名注册、虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!
| | 版权所有 西部数码(www.west263.com)
CopyRight (c) 2002~2007 west263.com all right reserved.
公司地址:四川成都市万和路90号天象大厦4楼 邮编:610031
电话总机:028-86263408 86263960 86264018 86267838 86262244 86263408 售前咨询:总机转201 202 203 204 205 206 207 208 售后服务:总机转211
212 213 214 217 218 晚上0点以后拔分机225 |
| 财务咨询:总机转224
223 传真:028-86264041 财务QQ: 635483282
售前咨询QQ: 327314358 241975952 275026793 408235859 2182518 499513144 售后服务QQ: 634349278 809071471 307742704 512359778 287976517 363783715 在线咨询
《中华人民共和国增值电信业务经营许可证》编号:川B2-20030065号
|
|