手机站
网通分站
电信主站
密 码:
用户名:
当前位置 : 主页>网站运营>建站经验>列表

elf文档格式-- 3

来源:互联网 作者:west263.com 时间:2008-04-16
西部数码-全国虚拟主机10强!40余项虚拟主机管理功能,全国领先!双线多线虚拟主机南北访问畅通无阻!免费赠送企业邮局,.CN域名,自助建站480元起,免费试用7天,满意再付款! P4主机租用799元/月.月付免压金!

地址。

GOT表的格式和解释是处理器相关的。在32位Intel体系结构下,标号
_GLOBAL_OFFSET_TABLE_可能被用来访问该表。

Figure 2-11: Global Offset Table

extern Elf32_Addr _GLOBAL_OFFSET_TABLE_[];

标号_GLOBAL_OFFSET_TABLE_可能驻留在.got section的中间,允许负的和非负
的下标索引这个数组。


Procedure Linkage Table(PLT过程连接表)

就象GOT重定位把位置无关的地址计算成绝对地址相同,PLT过程连接表重定位
位置无关的函数调用到绝对的地址。从一个可执行或共享的object文档到另外的,
连接编辑器不解析执行的传输(例如函数的调用)。因此,连接编辑器安排程式
的传递控制到PLT中的入口。在SYSTEM V体系下,PLT存在共享文本中,但是他们
使用的地址是在私有的GOT中。符号连接器决定了目标的绝对地址并且修改GOT的
内存映象。因此,在没有危及到位置无关、程式文本的共享能力的情况下。动态
连接器能重定位人口。


Figure 2-12: Absolute Procedure Linkage Table
绝对的过程连接表

.PLT0:pushl got_plus_4
jmp *got_plus_8
nop; nop
nop; nop
.PLT1:jmp *name1_in_GOT
pushl $offset
jmp .PLT0@PC
.PLT2:jmp *name2_in_GOT
pushl $offset
jmp .PLT0@PC
...

Figure 2-13: Position-Independent Procedure Linkage Table
位置无关(或说位置单独)的过程连接表
.PLT0:pushl 4(離)
jmp *8(離)
nop; nop
nop; nop
.PLT1:jmp *name1@GOT(離)
pushl $offset
jmp .PLT0@PC
.PLT2:jmp *name2@GOT(離)
pushl $offset
jmp .PLT0@PC
...

注意:如图所示,PLT的指令使用了不同的操作数地址方式,对绝对代码和
对位置无关的代码。但是,他们的界面对于动态连接器是相同的。

以下的步骤,动态连接器和程式协作(cooperate)通过PLT和GOT来解析符号
引用。

1. 当第一次创建程式的内存映象时,动态连接器为在GOT中特别的变量配置
第二次和第三次的入口。下面关于那些变量有更多的解释。

2. 假如PLT是位置无关的,那么GOT的地址一定是保留在離中的。每个在进程
映象中共享的object文档有他自己的PLT,并且仅仅在同一个object文档中,
控制传输到PLT入口。从而,要调用的函数有责任在调用PLT入口前,配置PLT
地址到寄存器中。

3. 举例说明,假如程式调用函数name1,他的传输控制到标号.PLT1.

4. 第一个指令跳到在GOT入口的name1地址。初始话时,GOT保存着紧跟着的push1
指令的地址,而不是真实的name1的地址。

5. 因此,程式在堆栈中压入(push)一个重定位的偏移量。重定位的偏移量是
一个32位,非负的字节偏移量(从定位表算起)。指派的重定位入口将是
一个R_386_JMP_SLOT类型,他的偏移量指明了GOT入口(在前面的jmp指令中
被使用)。该重定位入口也包含一个符号表的索引,因此告诉动态连接器
哪个符号要被引用,在这里是name1。

6. 在压入(push)一个重定位的偏移量后,程式跳到.PLT0,在PLT中的第一个入口。
push1指令在堆栈中放置第二个GOT入口(got_plus_4 or 4(離))的值,
因此,给动态连接器一个word的鉴别信息。然后程式跳到第三个GOT入口
(got_plus_8 or 8(離)),他传输控制到动态连接器。

7. 当动态连接器接到控制权,他展开堆栈,查看指派的重定位入口,寻找符号的
值,在GOT入口中存储真实的name1地址,然后传输控制想要目的地。

8. PLT入口的并发执行将直接传输控制到name1,而不用第二次调用动态连接器
了。所以,在.PLT1中的jmp指令将转到name1,代替“falling through”
转到pushl指令。

LD_BIND_NOW环境变量能改变动态连接器的行为。假如这个变量为非空,动态
连接器在传输控制到程式前计算PLT入口。换句话说,动态连接器处理重定位
类型为R_386_JMP_SLOT的入口在进程初始化时。否则,动态连接器计算PLT入口
懒惰的,推迟到符号解析和重定位直到一个表入口的第一次执行。


注意:一般来说,以懒惰(Lazy)方式绑定是对全应用程式执行的改进。
因为不使用的符号就不会招致动态连接器做无用功。然而,对一些应用程式,
两种情况使用懒惰(Lazy)方式是不受欢迎的。

第一 初始的引用一个共享object函数比后来的调用要花的时间长,因为动
态连接器截取调用来解析符号。一些应用程式是不能容忍这样的。
第二 假如这个错误发生并且动态连接器不能解析该符号,动态连接器将终止
程式。在懒惰(Lazy)方式下,这可能发生在任意的时候。一再的,一
些应用程式是不能容忍这样的。通过关掉懒惰(Lazy)方式,在应用程
序接到控制前,当在处理初始话时发生错误,动态连接器强迫程式,使
之失败。

Hash Table(哈希表)

Elf32_Word object的哈希表支持符号表的访问。
标号出现在下面帮助解释哈希表的组织,但是他们不是规范的一部分。

Figure 2-14: Symbol Hash Table

nbucket
nchain
bucket[0]
...
bucket[nbucket - 1]
chain[0]
...
chain[nchain - 1]


bucket数组包含了nbucket入口,并且chain数组包含了nchain个入口;索引从0开始。
bucket和chain保存着符号表的索引。Chain表入口类似于符号表。符号表入口的
数目应该等于nchain;所以符号表的索引也选择chain表的入口。

文章整理:西部数码--专业提供域名注册虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!