工具接口标准(TIS)可执行链接格式(ELF)规范版本 1.2
翻译以中英对照方式,英语水平有限,如有翻译不当的地方,请谅解。
Program Interpreter
程序解释器
An executable file that participates in dynamic linking shall have one PT_INTERP program header element. During exec (BA_OS), the system retrieves a path name from the PT_INTERP segment and creates the initial process image from the interpreter file's segments. That is, instead of using the original executable file's segment images, the system composes a memory image for the interpreter. It then is the interpreter's responsibility to receive control from the system and provide an environment for the application program.
一个参与动态链接的可执行文件应该有一个PT_INTERP程序头元素。在执行程序中,系统取得一个从PT_INTERP分段中的路径名并从解释器文件分段创建初始进程映像。就是说,系统为解释器构成一个内存映像,替代原始可执行文件的分段映像。然后由解释器负责接收系统控制柄提供一个此应用程序的环境。
The interpreter receives control in one of two ways. First, it may receive a file descriptor to read the executable file, positioned at the beginning. It can use this file descriptor to read and/or map the executable file's segments into memory. Second, depending on the executable file format, the system may load the executable file into memory instead of giving the interpreter an open file descriptor. With the possible exception of the file descriptor, the interpreter's initial process state matches what the executable file would have received. The interpreter itself may not require a second interpreter. An interpreter may be either a shared object or an executable file.
解释器通过两种方法中的一种接收控制。第一,它接收一个指向该可执行文件开始处的描述符。它能使用这个文件描述符来读取和/或映射此可执行文件的分段到内存。第二,依赖于这个可执行文件的格式,系统可以加载可执行文件到内存,而不是将一个打开的描述符传递给解释器。由于文件描述符存在异常的可能性,解释器解释器初始化进程状态时需要匹配收到的可执行文件内容。解释器自身不需要另外的解释器解释。一个解释器可能是共享文件或可执行文件。
• A shared object (the normal case) is loaded as position-independent, with addresses that may vary from one process to another; the system creates its segments in the dynamic segment area used by mmap(KE_OS) and related services. Consequently, a shared object interpreter typically will not conflict with the original executable file's original segment addresses.
• An executable file is loaded at fixed addresses; the system creates its segments using the virtual addresses from the program header table. Consequently, an executable file interpreter's virtual addresses may collide with the first executable file; the interpreter is responsible for resolving conflicts.
- 一个共享文件(普通情况下)是作为位置无关加载的,不同的进程地址是不同的;系统通过mmap和相关服务在动态分段区域创建共享文件的分段。因此,一个共享对象解释器典型情况下不会和原始可执行文件的原始分段地址冲突;
- 一个可执行文件被加载到固定地址;系统使用程序头表中的虚拟地址创建它的分段。因此,一个可执行文件解释器的虚拟地址可能和第一个可执行文件冲突;解释器有责任解决冲突。
Dynamic Linker
动态链接器
When building an executable file that uses dynamic linking, the link editor adds a program header element of type PT_INTERP to an executable file, telling the system to invoke the dynamic linker as the program interpreter.
当使用动态链接创建一个可执行文件,链接编辑器添加一个PT_INTERP类型的程序头元素到可执行文件,告诉系统调用调用动态链接器作为程序解释器。
NOTE. The locations of the system provided dynamic linkers are processor—specific.
注意:系统定位提供的动态链接器是处理器特定的。
The executable file and the dynamic linker cooperate to create the process image for the program, which entails the following actions:
• Adding the executable file's memory segments to the process image;
• Adding shared object memory segments to the process image;
• Performing relocations for the executable file and its shared objects;
• Closing the file descriptor that was used to read the executable file, if one was given to the dynamic linker;
• Transferring control to the program, making it look as if the program had received control directly from the executable file.
可执行文件和动态链接器配合创建程序进程映像,包含有以下动作:
- 添加可执行文件内存分段到进程映像;
- 添加共享对象内存分段到进程映像;
- 为可执行文件盒它的共享对象执行重定位;
- 关闭用于读写可执行文件的文件描述符,如果之前有传递给动态链接器的话;
- 传出控制给程序,使其看起来像程序已经直接从可执行文件接收到了控制。
The link editor also constructs various data that assist the dynamic linker for executable and shared object files. As shown above in "Program Header,'' these data reside in loadable segments, making them available during execution. (Note that the exact segment contents are processor-specific.)
• A .dynamic section with type SHT_DYNAMIC holds various data. The structure residing at the beginning of the section holds the addresses of other dynamic linking information.
• The .hash section with type SHT_HASH holds a symbol hash table.
• The .got and .plt sections with type SHT_PROGBITS hold two separate tables: the global offset table and the procedure linkage table. Programs use the global offset table for position-independent code. Sections below explain how the dynamic linker uses and changes the tables to create memory images for object files.
链接编辑器为可执行和共享对象文件构建不同的辅助动态链接器的数据。就像上面“程序头”展示的一样,这些数据位于可加载分段,使其在整个执行期间有效。(注意,确切的分段内容是处理器相关的)
一个类型为SHT_DYNAMIC的.dynamic分节包含不同的数据。位于分节开始的结构包含其它动态链接信息的地址;
类型为SHT_HASH的.hash分节包含符号哈希表;
类型为SHT_PROGBITS的.got和.plt分节包含两个单独的表:全局偏移表和过程链接表。程序使用全局偏移表存储位置无关代码。以下分节解释了动态链接器如何使用和改变这些表来为对象文件闯将内存映像。
Because every UNIX System V conforming program imports the basic system services from a shared object library, the dynamic linker participates in every TIS ELF-conforming program execution.
由于每个符合UNIX System V的程序从一个共享对象库导入基本的系统服务,动态链接器参与了每个兼容TIS ELF的程序执行。
As "Program Loading" explains in the appendix at the end of this book, shared objects may occupy virtual memory addresses that are different from the addresses recorded in the file's program header table. The dynamic linker relocates the memory image, updating absolute addresses before the application gains control. Although the absolute address values would be correct if the library were loaded at the addresses specified in the program header table, this normally is not the case.
就像本卷末尾附录“程序加载”解释的一样,共享对象占据的虚拟内存地址可能和文件中程序头表记录的地址不同。动态链接器重定位内存映像,在应用获取控制前更新绝对地址。虽然动态库被加载到程序头表中指定的地址作为绝对地址是正确的,但通常不是这种情况。
If the process environment contains a variable named LD_BIND_NOW with a non-null value, the dynamic linker processes all relocation before transferring control to the program. For example, all the following environment entries would specify this behavior.
• LD_BIND_NOW=1
• LD_BIND_NOW=on
• LD_BIND_NOW=off
Otherwise, LD_BIND_NOW either does not occur in the environment or has a null value. The
dynamic linker is permitted to evaluate procedure linkage table entries lazily, thus avoiding
symbol resolution and relocation overhead for functions that are not called.
假如进程环境包含一个非空值的环境变量LD_BIND_NOW,动态链接器将在传输控制给程序前处理所有的重定位操作。比如,所有以下环境入口会指定这种行为。
- LD_BIND_NOW=1
- LD_BIND_NOW=on
- LD_BIND_NOW=off