工具接口标准(TIS)可执行链接格式(ELF)规范-卷III-附录A-Intel架构和System V Release 4依赖(三)

本文是对Tool Interface Standard (TIS) Executable and Linking Format (ELF) Specification Version 1.2的翻译
工具接口标准(TIS)可执行链接格式(ELF)规范版本 1.2

翻译以中英对照方式,英语水平有限,如有翻译不当的地方,请谅解。


Dynamic Linking
动态链接

Dynamic Section
动态分节

Dynamic section entries giveinformation to the dynamic linker. Some of this information isprocessor-specific, including the interpretation of some entries in the dynamicstructure.

   动态分节入口给出了动态链接器需要的信息。这些信息中一部分是处理器相关的,包括在此动态结构中一些入口的解释。

DT_PLTGOT

On the Intel architecture, this entry's d_ptr member gives the address of the first entry in the global offset table. 

As mentioned below, the first three global offset table entries are reserved, and two are used to hold procedure linkage table information.

在Intel架构,这个入口的d_ptr成员给出在全局偏移表中的第一个入口地址。像下面提到的,前三个全局偏移表入口时保留的,

其中两个用于包含全局链接表信息。

 

Global Offset Table

全局偏移表

Position-independent code cannot,in general, contain absolute virtual addresses. Global offset tables holdabsolute addresses in private data, thus making the addresses available withoutcompromising the position-independence and sharability of a program's text. Aprogram references its global offset table using position-independentaddressing and extracts absolute values, thus redirecting position-independentreferences to absolute locations.

位置无关代码通常情况下不能包含绝对虚拟地址。全局偏移表在私有数据中包含绝对地址,从而使地址在没有让步位置无关及共享程序代码时有效。一个程序的使用位置无关地址和确切的绝对值来引用它的全局偏移表,从而重定位位置无关引用到绝对定位。

 

Initially, the global offset tableholds information as required by its relocation entries [see "Relocation''in Chapter 1]. After the system creates memory segments for a loadable objectfile, the dynamic linker processes the relocation entries, some of which willbe type R_386_GLOB_DAT referring to the global offset table. The dynamic linkerdetermines the associated symbol values, calculates their absolute addresses,and sets the appropriate memory table entries to the proper values. Althoughthe absolute addresses are unknown when the link editor builds an object file,the dynamic linker knows the addresses of all memory segments and can thuscalculate the absolute addresses of the symbols contained therein.

最初,全局偏移表包含它的重定位入口的请求[看第一章的“重定位”]。在系统为可加载对象文件创建内存分段后,动态链接器处理重定位入口,这些入口中的类型为R_386_GLOB_DAT的入口被关联到全局偏移表。动态链接器决定关联符号的值,计算它们的绝对地址,设置恰当的内存表入口到固定值。虽然当连接编辑器建立对象文件时,绝对地址是未知的,但动态链接器指导所有内存分段的地址,并能够因此计算包含在其中的符号的绝对地址。

 

If a program requires directaccess to the absolute address of a symbol, that symbol will have a globaloffset table entry. Because the executable file and shared objects haveseparate global offset tables, a symbol's address may appear in several tables.The dynamic linker processes all the global offset table relocations beforegiving control to any code in the process image, thus ensuring the absoluteaddresses are available during execution.

假如一个程序需要对一个符号直接定位到绝对地址,这个符号需要有一个全局偏移表入口。因为可执行文件和共享对象有分离的全局偏移表,一个符号地址可能出现在多个表。动态连接器在移交控制给进程映像中的代码前,处理所有的全局偏移表重定位,从而确保在执行中绝对地址是有效的。

 

The table's entry zero is reservedto hold the address of the dynamic structure, referenced with the symbol_DYNAMIC. This allows a program, such as the dynamic linker, to find its owndynamic structure without having yet processed its relocation entries. This isespecially important for the dynamic linker, because it must initialize itselfwithout relying on other programs to relocate its memory image. On the Intelarchitecture, entries one and two in the global offset table also are reserved."Procedure Linkage Table'' below describes them.

表入口0是保留给动态结构地址使用的,由符号_DYNAMIC引用。这将允许一个程序,比如动态链接器,在没有处理它的重定位入口前查找它自己的动态结构。这对动态链接器来说特别重要,因为它必须在没有依赖于其它程序重定位它内存映像的情况下初始化它自身。在Intel架构下,在全局偏移表中的入口一和二是保留的。以下的“过程链接表”会描述它们。

 

The system may choose differentmemory segment addresses for the same shared object in different programs; itmay even choose different library addresses for different executions of thesame program. Nonetheless, memory segments do not change addresses once theprocess image is established. As long as a process exists, its memory segmentsreside at fixed virtual addresses.

系统可能为在不同程序中的相同共享对象选择不同的内存分段地址;它甚至可能为相同程序的不同执行选择不同的库地址。尽管如此,一旦进程映像建立后,内存分段不会改变地址。只要一个进程存在,它的内存分段位于固定的虚拟地址。

 

A global offset table's format andinterpretation are processor-specific. For the Intel architecture, the symbol_GLOBAL_OFFSET_TABLE_ may be used to access the table.

   全局偏移表的格式和解释是处理器相关的。Intel架构下,符_GLOBAL_OFFSET_TABLE_可以用来访问这个表

 

FigureA-8.  Global Offset Table

图A-8.全局偏移表

extern Elf32_Addr _GLOBAL_OFFSET_TABLE_[];

 

The symbol _GLOBAL_OFFSET_TABLE_may reside in the middle of the .got section, allowing both negative andnon-negative "subscripts'' into the array of addresses.

   符号_GLOBAL_OFFSET_TABLE_可能位于.got分节的中部,允许正负“下标”在访问地址数组。

 

Function Addresses

函数地址

References to the address of afunction from an executable file and the shared objects associated with itmight not resolve to the same value. References from within shared objects willnormally be resolved by the dynamic linker to the virtual address of thefunction itself. References from within the executable file to a functiondefined in a shared object will normally be resolved by the link editor to theaddress of the procedure linkage table entry for that function within theexecutable file.

   从一个可执行文件及和它关联的共享对象引用一个函数的地址,可能不会解析到相同的值。共享对象中的引用通常被动态链接器解析到函数自身的虚拟地址。可执行文件中引用一个定义在共享对象中的函数,通常被链接编辑器解析到过程链接表入口地址。

To allow comparisons of functionaddresses to work as expected, if an executable file references a functiondefined in a shared object, the link editor will place the address of theprocedure linkage table entry for that function in its associated symbol tableentry. [See "Symbol Values'' in Chapter 1]. The dynamic linker treats suchsymbol table entries specially. If the dynamic linker is searching for asymbol, and encounters a symbol table entry for that symbol in the executablefile, it normally follows the rules below.

1. If the st_shndx member of thesymbol table entry is not SHN_UNDEF, the dynamic linker has found a definitionfor the symbol and uses its st_value member as the symbol's address.

2. If the st_shndx member isSHN_UNDEF and the symbol is of type STT_FUNC and the st_value member is notzero, the dynamic linker recognizes this entry as special and uses the st_valuemember as the symbol's address.

3. Otherwise, the dynamic linkerconsiders the symbol to be undefined within the executable file and continuesprocessing.

为了使函数地址比较像预期一样工作,假如一个可执行文件引用一个定义在共享对象中的函数,链接编辑器存放该函数过程链接表入口地址到它关联的符号表入口。[看第一章“符号值”]。动态链接器特殊对待这样的符号表。假如动态链接器搜索一个符号,并遇到在可执行文件中的该符号的符号表入口,它一般遵循以下规则:

1.假如符号表入口成员st_shndx不是SHN_UNDEF,动态链接器就找到了该符号定义并使用它的st_value成员作为符号地址;

2.假如st_shndx成员是SHN_UNDEF,并且符号类型是STT_FUNC,并且st_value成员是0,动态链接器特殊识别这个入口并使用st_value成员作为符号地址;

3.否则,动态链接器认为符号在可执行文件中未定义并继续后面的处理。


Some relocations are associated with procedure linkage table entries. These entries are used for direct function calls rather than for references to function addresses. These relocations are not treated in the special way described above because the dynamic linker must not redirect procedure linkage table entries to point to themselves.
一些重定位是和过程链接表入口关联的。这些入口用于直接函数调用而不是函数地址引用。这些重定位不会被上述那样特殊对待,因为动态链接器不能重定位过程链接表入口来指向它们自己。
 

Procedure Linkage Table

过程链接表

Much as the global offset tableredirects position-independent address calculations to absolute locations, theprocedure linkage table redirects position-independent function calls toabsolute locations. The link editor cannot resolve execution transfers (such asfunction calls) from one executable or shared object to another. Consequently,the link editor arranges to have the program transfer control to entries in theprocedure linkage table. On the Intel architecture, procedure linkage tablesreside in shared text, but they use addresses in the private global offsettable. The dynamic linker determines the destinations' absolute addresses andmodifies the global offset table's memory image accordingly. The dynamic linkerthus can redirect the entries without compromising the position-independenceand sharability of the program's text.

   非常像全局偏移表重定位位置无关地址计算到据对定位,过程链接表重定位位置无关函数调用到绝对定位。链接编辑器不能从一个可执行为间或者共享对象间解析可执行装换(比如函数调用)。因此,链接编辑器安排程序转换控制到过程链接表入口。在Intel架构,过程链接表位于共享文本内,但它们使用私有全局偏移表地址。动态链接器决定目的绝对地址并修改相应的全局偏移表内存映像。动态链接器从而在没有让步位置无关和程序文本共享的情况下重定位入口。

Executable files and shared objectfiles have separate procedure linkage tables.

   可执行文件和共享对象文件有分离的过程链接表。

FigureA-9. Absolute Procedure Linkage Table

图A-9.绝对过程链接表

.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

                  ...

 

FigureA-10. Position-Independent Procedure Linkage Table

图A-10.位置无关过程链接表

.PLT0:      pushl       4(%ebx)

                  jmp          *8(%ebx)

                  nop; nop

                  nop; nop

.PLT1:      jmp          *name1@GOT(%ebx)

                  pushl       $offset

                  jmp          .PLT0@PC

.PLT2:      jmp          *name2@GOT(%ebx)

                  pushl       $offset

                  jmp          .PLT0@PC

                  ...

 

NOTE. As the figures show, theprocedure linkage table instructions use different operand addressing modes forabsolute code and for position-independent code. Nonetheless, their interfacesto the dynamic linker are the same.

注意:就像上面的图,过程链接表指令为绝对代码和位置无关代码使用不同的操作数地址模式。但是,它们的接口对动态链接器是一样的。

 

Following the steps below, thedynamic linker and the program "cooperate'' to resolve symbolic referencesthrough the procedure linkage table and the global offset table.

1. When first creating the memoryimage of the program, the dynamic linker sets the second and the third entriesin the global offset table to special values. Steps below explain more aboutthese values.

2. If the procedure linkage tableis position-independent, the address of the global offset table must reside in%ebx. Each shared object file in the process image has its own procedurelinkage table, and control transfers to a procedure linkage table entry onlyfrom within the same object file. Consequently, the calling function isresponsible for setting the global offset table base register before callingthe procedure linkage table entry.

3. For illustration, assume theprogram calls name1, which transfers control to the label .PLT1.

4. The first instruction jumps tothe address in the global offset table entry for name1. Initially, the globaloffset table holds the address of the following pushl instruction, not the realaddress of name1.

5. Consequently, the programpushes a relocation offset (offset) on the stack. The relocation offset is a32-bit, non-negative byte offset into the relocation table. The designatedrelocation entry will have type R_386_JMP_SLOT, and its offset will specify theglobal offset table entry used in the previous jmp instruction. The relocationentry also contains a symbol table index, thus telling the dynamic linker whatsymbol is being referenced, name1 in this case.

6. After pushing the relocationoffset, the program then jumps to .PLT0, the first entry in the procedurelinkage table. The pushl instruction places the value of the second globaloffset table entry (got_plus_4 or 4(%ebx)) on the stack, thus giving thedynamic linker one word of identifying information. The program then jumps tothe address in the third global offset table entry (got_plus_8 or 8(%ebx)),which transfers control to the dynamic linker.

7. When the dynamic linkerreceives control, it unwinds the stack, looks at the designated relocationentry, finds the symbol's value, stores the "real'' address for name1 inits global offset table entry, and transfers control to the desireddestination.

8. Subsequent executions of theprocedure linkage table entry will transfer directly to name1, without callingthe dynamic linker a second time. That is, the jmp instruction at .PLT1 willtransfer to name1, instead of "falling through'' to the pushl instruction.

跟随以下的步骤,动态链接器和程序“合作”,通过过程链接表和全局偏移表解析符号引用:

1.当第一次创建程序内存映像,动态链接器设置全局偏移表第二和第三个入口到特殊值。以下的步骤会更多解释这些值;

2.假如过程链接表是位置无关的,全局偏移表的地址位于%ebx。每个进程映像中的共享对象文件有它自己的过程链接表,以及仅从相同的对象文件控制传输到一个过程链接表入口。因此,调用函数对调用过程链接表入口前设置全局偏移表基础寄存器负责;

3.为了阐述,假设程序调用name1,转换控制到标签.PLT1。

4.第一条指令是跳转到name1的全局偏移表入口。最初,全局偏移表是接下来的pushl指令的地址,不是实际的name1地址;

5.因此,程序压栈了一个重定位偏移。这个重定位偏移是一个重定位表中的32位非负字节偏移。指定的重定位入口有着R_386_JMP_SLOT类型,并且它的偏移会指向使用在前面jmp指令中的全局偏移表入口。这个重定位入口页包含一个符号表索引,从而告诉动态链接器哪个是符号是被引用的,在这种情况下是name1;

6.在压入重定位偏移后,程序跳转到.PLT0,在过程链接表的第一个入口。pushl指令在堆栈存放了第二个全局偏移表的入口(got_plus_4或4(%ebx)),从而给动态链接器一个识别信息词。程序接着跳转到第三个全局偏移表入口的地址(got_plus_8或8(%ebx)),转换控制到动态链接器;

7.当动态链接器收到控制,它展开堆栈,查看指定的重定位入口,找到符号值,存储name1在它的全局偏移表入口的“真实”地址,然后转换控制给预定目标;

8.之后的过程链接表入口的执行将直接转换到name1,不会第二次调用动态链接器。就是说,.PLT1中的jmp指令将装换到name1,而不是“掉落”到随后的pushl指令。

 

The LD_BIND_NOW environmentvariable can change dynamic linking behavior. If its value is non-null, thedynamic linker evaluates procedure linkage table entries before transferringcontrol to the program. That is, the dynamic linker processes relocationentries of type R_3862_JMP_SLOT during process initialization. Otherwise, thedynamic linker evaluates procedure linkage table entries lazily, delayingsymbol resolution and relocation until the first execution of a table entry.

   LD_BIND_NOW环境变量能够改变动态链接器的行为。假如它的值是非空的,动态链接器在转换控制到程序前评估过程链接表。就是说,动态链接器在进程初始化中处理类型为R_3862_JMP_SLOT的重定位入口。否则,动态链接器懒惰的评估过程链接表,延迟符号解析和重定位,直到该符号的入口第一次执行

 

NOTE. Lazy binding generallyimproves overall application performance, because unused symbols do not incurthe dynamic linking overhead. Nevertheless, two situations make lazy bindingundesirable for some applications. First, the initial reference to a sharedobject function takes longer than subsequent calls, because the dynamic linkerintercepts the call to resolve the symbol. Some applications cannot toleratethis unpredictability. Second, if an error occurs and the dynamic linker cannotresolve the symbol, the dynamic linker will terminate the program. Under lazybinding, this might occur at arbitrary times. Once again, some applicationscannot tolerate this unpredictability. By turning off lazy binding, the dynamiclinker forces the failure to occur during process initialization, before theapplication receives control.

注意:懒惰绑定通常改善整个应用性能,因为未使用的符号不会产生动态链接开销。然而,两种状况使懒惰绑定对一些应用不可取。第一,到一个共享对象函数的初始引用耗费的时间比接下来的调用更长,因为动态链接器拦截了这个调用来解析符号。一些应用不能忍受这种不可预见性。第二,假如错误发生并且动态链接器不能解析这个符号,动态链接器将终止程序。在懒惰绑定下,这可能发生在任意时刻。再一次,一些应用不能忍受这种不可预见性。通过关闭懒惰绑定,动态链接器强制这种失败发生在进程初始化时,在应用接收控制前。

 

Program Interpreter

程序解释器

There is one valid programinterpreter for programs conforming to the ELF specification for the Intelarchitecture: /usr/lib/libc.so.1

    Intel架构有一个符合ELF规范的有效的程序解释器:/usr/lib/libc.so.1。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值