Chinaunix首页 | 论坛 | 博客
  • 博客访问: 143355
  • 博文数量: 29
  • 博客积分: 717
  • 博客等级: 上士
  • 技术积分: 352
  • 用 户 组: 普通用户
  • 注册时间: 2011-05-16 16:17
文章分类

全部博文(29)

文章存档

2013年(4)

2012年(4)

2011年(21)

我的朋友

分类: LINUX

2011-08-14 18:36:52

URL:

9    Program Loading and Dynamic Linking

Executable files and shared library files are used to create a process image when a program is started by the system. This chapter describes the object file structures that relate to program execution and also describes how the process image is created from executable and shared object files.

当系统创建一个进程映像时会用到可执行文件和共享库,这章描述可执行文件的结构和进程映像是怎么从可执行文件和共享库中创建的。

This chapter addresses the following topics:

这章主要讨论一下几个话题

  • Factors that influence linking and loading operations. ()
  • 链接和装载的涉及到哪些因素
  • The loading process. ()
  • 装载过程
  • Dynamic linking and loading. ()
  • 动态装载和链接

9.1    Object File Considerations目标文件的注意事项

The following sections describe several general factors that are involved in the linking and loading process.

接下来几节描述装载和链接的几个因素
9.1.1    Structures

The following object file structures contain information that is used in linking and loading operations:

装载和链接会用到下面几个目标文件结构

  • File Header - The file header identifies a file as an object file and additionally indicates whether the object is a static executable file, a shared executable file, or a shared library file.
  • 文件头-表明该文件是静态可执行,还是共享可执行,还是共享库。
  • Optional Header - The optional header immediately follows the file header and identifies the size, location, and virtual addresses of the object's segments.
  • 可选文件头-指示区段的虚拟地址,大小,位置
  • Section Headers - Section headers describe the individual sections that comprise the object's segments. Section headers are normally not used in program loading; however, the section headers are used to locate the dynamic section in shared executable files and shared libraries.
  • 区段头-描述该段的信息,区段头不用于文件装载过程,而是用于定位共享可执行文件和库的动态段

See for further details on file headers, optional headers, and section headers.

详细描述第7章

9.1.2    Base Addresses 基址

Executable files and shared library files have a base address, which is the lowest virtual address associated with the process image of the program. The base address is used to relocate the process image during dynamic linking.

可执行文件和共享库有个基址,基址是对应进程的最小虚拟地址,基址用在动态链接时重定位进程映像。

During program loading, the base address is calculated from the memory load address, the maximum page size, and the lowest virtual address of the program's loadable segment.

在程序装载时,基址是从内存装载地址,页面的最大值,程序可装载的最小的虚拟地址中计算而来的。
9.1.3    Segment Access Permissions区段访问权限

A program that is to be loaded by the system must have at least one loadable segment, even though this is not required by the file format. When the process image is created, the segments are assigned access permissions, which are determined by the type of segment and type of program image. shows the access permissions for the various segment and image types.

程序至少有一个可以装载的区段,虽然这不是文件格式所必须的,但是当进程被创建时,所有的段都要分配访问权限,由段的格式和程序的格式决定(具体参见表9-1)
Table 9-1: Segment Access Permissions
Image Segment Access Permissions
OMAGIC text, data, bss Read, Write, Execute
NMAGIC text Read, Execute
NMAGIC data, bss Read, Write, Execute
ZMAGIC text Read, Execute
ZMAGIC data, bss Read, Write, Execute

上表可以看出镜像有3种格式OMAGIC,NMAGIC,ZMAGIC。

9.1.4    Segment Contents区段目录

An object file segment can contain one or more sections. The number of sections in a segment is not important for program loading, but specific information must be present for linking and execution. illustrates typical segment contents for executable files and shared object files. The order of sections within a segment may vary.

目标文件可以包含一个或多个区段。程序装载时区段的数量不重要,连接和执行是相关信息要说明,图9-1说明可执行文件和共享对象文件典型段内容段内部分路段顺序可能会有所不同

Text segments contain instructions and read-only data, and data segments contain writable data. Text segments and data segments typically include the sections shown in .

文本段包含指令只读数据段,数据段包含可写数据文本段和数据段通常包括图9-1所示部分

Figure 9-1: Text and Data Segments of Object Files
文本段和数据段的对象文件


9.2    Program Loading程序的装载

As the system creates or augments a process image, it logically copies a file's segment to a virtual memory segment. The time at which the system physically reads the file depends on the program's execution behavior, system load, and other factors. A process does not require a physical page unless it references the logical page during execution.

在该系统创建或扩充进程映像在逻辑上复制文件到虚拟内存段该系统物理读取文件的时间取决于程序的执行行为系统的负载,以及其他因素一个进程并不需要一个物理页除非在执行过程中引用逻辑页

Processes commonly leave many pages unreferenced. This improves system performance because delaying physical reads frequently obviates them. To obtain this efficiency in practice, shared executable files and shared library files must have segment images whose virtual addresses are zero, modulo the file system block size.

进程常常‘离开’未引用的许多页面因为物理延时读取可以提高系统性能在实践中获得这种效率共享可执行文件和共享库文件虚拟地址必须都是零,文件系统块大小图像。(modulo the file system block size.)

Virtual addresses for the text and data segments must be aligned on 64KB (0x10000) or larger power of 2 boundaries. File offsets must be aligned on 8KB (0x2000) or larger power of 2 boundaries.

文本段和数据段虚拟地址必须是64KB或更大2的边界边界对齐文件偏移量必须8KB或更大的2的边界边界上对齐

Because the page size can be larger than the alignment restrictions of a segment's file offset, up to seven file pages (depending on page size) can hold text or data that is not logically part of the segment. The contents of the various file pages are as follows:

由于页面大小可以大于段的文件对齐偏移限制,最多7文件页视页大小文件页可容纳文本或数据一部分合乎逻辑各种文件页面如下:

  • The first text page contains the COFF file header, section headers, and other information.
  • 第一个文本页面包含COFF文件其他信息
  • The last text page may hold a copy of the beginning of data.
  • 最后文本页面可容纳数据开始副本
  • The first data page may have a copy of the end of text.
  • 第一个数据页可能有一个复制文本结束
  • The last data page may contain file information not relevant to the running process.
  • 最后一个数据可能包含文件运行过程中不相关信息

Logically, the system enforces the memory permissions as if each segment were complete and separate; segment's addresses are adjusted to ensure that each logical page in the address space has a single set of permissions.

从逻辑上讲,系统要按照内存权限强制执行如果每个段完整的和独立的调整段的地址,以确保每个逻辑页在地址空间中有一个单一权限设置

The end of the data segment requires special handling for uninitialized data, which must be set to zero. If a file's last data page includes information not in the logical memory page, the extraneous data must be set to zero, not the contents of the executable file.

数据段的结束处需要特殊处理未初始化的数据必须设置为零如果最后一个数据包括信息在逻辑内存页面无关的数据必须设置零,而不是可执行文件的内容

9.3    Dynamic Linking 动态链接

An executable file is loaded at fixed addresses; the system creates its segments using the virtual addresses from the optional header. The system transfers control directly to the entry point of the executable file.

一个可执行文件被加载在固定地址;系统利用可选头使用虚拟地址创建它的段系统控制权转移直接指向可执行文件入口

An executable file that uses dynamic linking requires one or more shared libraries to be loaded in addition to the executable file. Instead of loading the executable file, the system loads the dynamic loader, which in turn loads the executable file and its shared libraries.

加载使用动态链接的可执行文件需要一个或多个共享库和可执行文件,装载可执行文件过程,加载系统装载器,在依次加载可执行文件和共享库。

 9.3.1    Dynamic Loader 动态加载器

When building an executable file that uses dynamic linking, the linker adds the flag F_MIPS_CALL_SHARED to the f_flags field of the file header. This flag tells the system to invoke the dynamic loader to load the executable file. Typically, the dynamic loader requested is /sbin/loader, the default loader. The exec function and the dynamic loader cooperate to create the process image. Creating the process image involves the following operations:

采用动态链接编译可执行文件,链接器会将F_MIPS_CALL_SHARED标志加到f_flags文件头的字段这个标志告诉系统调用动态加载器来加载可执行文件通常情况下,默认动态加载器/sbin/loader exec函数动态加载器合作创建进程映像创建过程如下:

  • Adding segments of the file to the process image
  • 添加文件的段到进程映像
  • Adding segments of shared object files to the process image
  • 添加共享的对象文件的段到进程映像
  • Performing relocations for the executable file and its shared library files
  • 执行可执行文件共享库文件重定位
  • Transferring control to the program, making it appear that the program received control directly from exec
  • 将控制权转交给程序,是程序直接从exec函数中获得操作权

To assist the dynamic loader, the linker also constructs the following data items for shared library files and shared executable files:

协助动态加载器链接器构建共享库文件共享可执行文件以下数据项

  • The .dynamic section contains the dynamic header. (See .)
  • .dynamic 节包含动态
  • The .got section contains the global offset table. (See .)
  • .got节包含全局偏移表
  • The .dynsym section contains the dynamic symbol table. (See .)
  • .dynsym节包含动态符号表
  • The .rel.dyn section contains the dynamic relocation table. (See .)
  • .rel.dyn节包含动态重定位表
  • The .msym section contains the msym table. (See .)
  • .msym节包含msym表
  • The .hash section contains a symbol hash table. (See .)
  • .hash节包含一个符号哈希表
  • The .dynstr section contains the dynamic string table. (See .)
  • .dynstr节包含动态字符串表
  • The .liblist section contains the library dependency table. (See .)
  • .liblist包含库的依赖
  • The .conflict section contains the conflict symbol table. (See .)
  • .conflict节包含冲突的符号表

These data items are located in loadable segments and are available during execution.

这些数据项都位于可装载的在执行过程中可能会用到。

Shared library files may be located at virtual addresses that differ from the addresses in the optional header. The dynamic loader relocates the memory image and updates absolute addresses before control is given to the program.

共享库文件虚拟地址可能和可选头中定义的不一样程序获得控制权前动态加载器会重定位内存映像更新绝对地址

If the environment variable LD_BIND_NOW has a non-null value, the dynamic loader processes all relocations before transferring control to the program. The dynamic loader may use the lazy binding technique to evaluate procedure linkage table entries, avoiding symbol resolution and relocation for functions that are not called.(See for information about lazy binding.)

如果环境变量LD_BIND_NOW一个非空动态加载在将控制权交给程序之前执行所有重定位,动态加载器可能使用延迟绑定技术评估链接表项的过程避免对不调用的函数符号解析和重定位 延迟绑定信息参见9.3.3.1

The following sections describe the various dynamic linking sections. The C language definitions are in the header files elf_abi.h and elf_mips.h.

以下各节描述的各种动态链接部分 C语言定义在头文件中elf_abi.helf_mips.h


9.3.2    Dynamic Section (.dynamic)

The dynamic section acts as a table of contents for dynamic linking information within the object. Dynamic sections are present only in shared executable files and shared library files.

动态节动态链接信息表的对象动态节目前仅在共享可执行文件和共享库文件

The dynamic section is located by its section header. This section header is identified by its name (.dynamic) or its section type (STYP_DYNAMIC) in the flags field (s_flags).

动态节是位于节头此节头它的名字.dynamic部分类型的标志字段STYP_DYNAMIC)(s_flags确定

The dynamic section is an array with entries of the following type:

动态节类型


typedef struct { Elf32_Sword d_tag; union { Elf32_Word d_val; Elf32_Addr d_ptr; } d_un; } Elf32_Dyn;

The structure and union members in the preceding structure definition provide the following information:

结构和联盟成员的相关信息

d_tag Indicates how the d_un field is to be interpreted.


d_val Represents integer values。
_tag指示d_un域该如何解释.
d_val表示整数值。


d_ptr Represents program virtual addresses. A file's virtual addresses may not match the memory virtual addresses during execution. The dynamic loader computes actual addresses based on the virtual address from the file and the memory base address. Object files do not contain relocation entries to correct addresses in the dynamic section.

d_ptr 表示程序的虚拟地址。在执行的过程中,文件的虚拟地址可能与内存的虚拟地址不匹配。动态加载器在内存基地址和文件的虚拟地址基础上计算出实际地址。在动态节中,对象文件不包含正确的地址重定位项


The d_tag requirements for shared executable files and shared library files are summarized in . "Mandatory" indicates that the dynamic linking array must contain an entry of that type; "optional" indicates that an entry for the tag may exist but is not required.

d_tag所需要的共享可执行文件和共享库文件的要求总结在表9-2。 “强制性”表明动态链接数组必须包含该类型的条目,“可选”表示,标签的条目可能存在,但不是必需的。


Table 9-2: Dynamic Array Tags (d_tag)
Name Value d_un Executable Shared Object
DT_NULL 0 ignored mandatory mandatory
DT_NEEDED 1 d_val optional optional
DT_PLTRELSZ[Table Note 1] 2 d_val optional optional
DT_PLTGOT 3 d_ptr optional optional
DT_HASH 4 d_ptr mandatory mandatory
DT_STRTAB 5 d_ptr mandatory mandatory
DT_SYMTAB 6 d_ptr mandatory mandatory
DT_RELA[Table Note 1] 7 d_ptr mandatory optional
DT_RELASZ[Table Note 1] 8 d_val mandatory optional
DT_RELAENT[Table Note 1] 9 d_val mandatory optional
DT_STRSZ 10 d_val mandatory mandatory
DT_SYMENT 11 d_val mandatory mandatory
DT_INIT 12 d_ptr optional optional
DT_FINI 13 d_ptr optional optional
DT_SONAME 14 d_val ignored optional
DT_RPATH 15 d_val optional ignored
DT_SYMBOLIC 16 ignored ignored optional
DT_REL 17 d_ptr mandatory optional
DT_RELSZ 18 d_val mandatory optional
DT_RELENT 19 d_val mandatory optional
DT_PLTREL[Table Note 1] 20 d_val optional optional
DT_DEBUG[Table Note 1] 21 d_ptr optional ignored
DT_TEXTREL[Table Note 1] 22 ignored optional optional
DT_JMPREL[Table Note 1] 23 d_ptr optional optional
DT_LOPROC 0x70000000 unspecified unspecified unspecified
DT_HIPROC 0x7fffffff unspecified unspecified unspecified


Table Notes:

  1. Not used by the default system linker and loader.The uses of the various dynamic array tags are as follows:
DT_NULL Marks the end of the array.


DT_NEEDED Contains the string table offset of a null terminated string that is the name of a needed library. The offset is an index into the table indicated in the DT_STRTAB entry. The dynamic array may contain multiple entries of this type. The order of these entries is significant.
DT_NEEDED包含字符串表的偏移,该偏移是DT_STRTAB项中的索引,这种类型的动态数组可能包含多个条目这些项顺序是很重要


DT_PLTRELSZ Contains the total size in bytes of the relocation entries associated with the procedure linkage table. If an entry of type DT_JMPREL is present, it must have an associated DT_PLTRELSZ entry. (Not used by the default system linker and loader.)


DT_PLTGOT Contains an address associated with either the procedure linkage table, the global offset table, or both.
DT_PLTGOT包含程序链接表全局偏移表或两者关联的地址


DT_HASH Contains the address of the symbol hash table.


DT_STRTAB Contains the address of the string table.


DT_SYMTAB Contains the address of the symbol table with Elf32_Sym entries.


DT_RELA Contains the address of a relocation table. Entries in the table have explicit addends, such as Elf32_Rela. An object file may have multiple relocation sections. When the linker builds the relocation table for an shared executable file or shared object file, these sections are concatenated to form a single table. While the sections are independent in the object file, the dynamic loader sees a single table. When the dynamic loader creates a process image or adds a shared library file to a process image, it reads the relocation table and performs the associated actions. If this entry is present, the dynamic structure must also contain DT_RELASZ and DT_RELAENT entries. When relocation is mandatory for a file, either DT_RELA or DT_REL may be present. (Not used by the default system linker and loader.)


DT_RELASZ Contains the size in bytes of the DT_RELA relocation table. (Not used by the default system linker and loader.)


DT_RELAENT Contains the size in bytes of a DT_RELA relocation table entry. (Not used by the default system linker and loader.)


DT_STRSZ Contains the size in bytes of the string table.


DT_SYMENT Contains the size in bytes of a symbol table entry.


DT_INIT Contains the address of the initialization function.


DT_FINI Contains the address of the termination function.


DT_SONAME Contains the string table offset of a null-terminated string that gives the name of the shared library file. The offset is an index into the table indicated in the DT_STRTAB entry.


DT_RPATH Contains the string table offset of a null-terminated library search path string. The offset is an index into the table indicated in the DT_STRTAB entry.


DT_SYMBOLIC If this entry is present, the dynamic loader uses a different symbol resolution algorithm for references within a library. The symbol search starts from the shared library file instead of the shared executable file. If the shared library file does not supply the referenced symbol, the shared executable file and other shared library file are searched.


DT_REL Contains the address of the relocation table. An object file can have multiple relocation sections. When the linker builds the relocation table for a shared executable file or shared library file, these sections are concatenated to form a single table. While the sections are independent in the object file, the dynamic loader sees a single table. When the dynamic loader creates a process image or adds a shared library file to a process image, it reads the relocation table and performs the associated actions. If this entry is present, the dynamic structure must contain the DT_RELSZ entry.


DT_RELSZ Contains the size in bytes of the relocation table pointed to by the DT_REL entry.


DT_RELENT Contains the size in bytes of a DT_REL entry.


DT_PLTREL Specifies the type of relocation entry referred to by the procedure linkage table. The d_val member holds DT_REL or DT_RELA, as appropriate. All relocations in a procedure linkage table must use the same relocation. (Not used by the default system linker and loader.)


DT_DEBUG Used for debugging. The contents of this entry are not specified. (Not used by the default system linker and loader.)


DT_TEXTREL If this entry is not present, no relocation entry should cause a modification to a nonwritable segment. If this entry is present, one or more relocations might request modifications to a nonwritable segment. (Not used by the default system linker and loader.)


DT_JMPREL If this entry is present, its d_ptr field contains the address of relocation entries associated only with the procedure linkage table. The dynamic loader may ignore these entries during process initialization if lazy binding is enabled. See for information about lazy binding. (Not used by the default system linker and loader.)


DT_LOPROC through DT_HIPROC Reserved for processor-specific semantics.

Table 9-3: Processor-Specific Dynamic Array Tags (d_tag)
Name Value d_un Executable Shared Object
DT_MIPS_RLD_VERSION 0x70000001 d_val mandatory mandatory
DT_MIPS_TIME_STAMP 0x70000002 d_val optional optional
DT_MIPS_ICHECKSUM 0x70000003 d_val optional optional
DT_MIPS_IVERSION 0x70000004 d_val optional optional
DT_MIPS_FLAGS 0x70000005 d_val mandatory mandatory
DT_MIPS_BASE_ADDRESS 0x70000006 d_ptr mandatory mandatory
DT_MIPS_CONFLICT 0x70000008 d_ptr optional optional
DT_MIPS_LIBLIST 0x70000009 d_ptr optional optional
DT_MIPS_LOCAL_GOTNO 0x7000000A d_val mandatory mandatory
DT_MIPS_CONFLICTNO 0x7000000B d_val optional optional
DT_MIPS_LIBLISTNO 0x70000010 d_val optional optional
DT_MIPS_SYMTABNO 0x70000011 d_val optional optional
DT_MIPS_UNREFEXTNO 0x70000012 d_val optional optional
DT_MIPS_GOTSYM 0x70000013 d_val mandatory mandatory
DT_MIPS_HIPAGENO[Table Note 1] 0x70000014 d_val mandatory mandatory


Table Notes:

  1. Not used by the default system linker and loader.

The uses of the various processor-specific dynamic array tags are as follows:

DT_MIPS_RLD_VERSION Holds an index into the object file's string table, which holds the version of the run-time linker interface. The version is 1 for executable objects that have a single GOT and 2 for executable objects that have multiple GOTs.


DT_MIPS_TIME_STAMP Contains a 32-bit time stamp.


DT_MIPS_ICHECKSUM Contains a value that is the sum of all of the COMMON sizes and the names of defined external symbols.


DT_MIPS_IVERSION Contains the string table offset of a series of colon-separated version strings. An index value of zero means no version string was specified.


DT_MIPS_FLAGS Contains a set of 1-bit flags. The following flags are defined for DT_MIPS_FLAGS:
Flag Value Meaning
RHF_QUICKSTART 0x00000001 Object may be quickstarted by loader
RHF_NOTPOT 0x00000002 Hash size not a power of two
RHF_NO_LIBRARY_REPLACEMENT 0x00000004 Use default system libraries only
RHF_NO_MOVE 0x00000008 Do not relocate
RHF_RING_SEARCH 0x10000000 Symbol resolution same as DT_SYMBOLIC
RHF_DEPTH_FIRST 0x20000000 Depth first symbol resolution
RHF_USE_31BIT_ADDRESSES 0x40000000 TASO (Truncated Address Support Option) objects



DT_MIPS_BASE_ADDRESS Contains the base address.


DT_MIPS_CONFLICT Contains the address of the .conflict section.


DT_MIPS_LIBLIST Contains the address of the .liblist section.


DT_MIPS_LOCAL_GOTNO Contains the number of local GOT entries. The dynamic array contains one of these entries for each GOT.


DT_MIPS_CONFLICTNO Contains the number of entries in the .conflict section and is mandatory if there is a .conflict section.


DT_MIPS_LIBLISTNO Contains the number of entries in the .liblist section.


DT_MIPS_SYMTABNO Indicates the number of entries in the .dynsym section.


DT_MIPS_UNREFEXTNO Holds an index into the dynamic symbol table. The index is the entry of the first external symbol that is not referenced within the object.


DT_MIPS_GOTSYM Holds the index of the first dynamic symbol table entry that corresponds to an entry in the global offset table. The dynamic array contains one of these entries for each GOT.


DT_MIPS_HIPAGENO Holds the number of page table entries in the global offset table. A page table entry here refers to 64KB of data space. This entry is used by the profiling tools and is optional. (Not used by the default system linker and loader.)


All other tag values are reserved. Entries may appear in any order, except for the relative order of the DT_NEEDED entries and the DT_NULL entry at the end of the array.

9.3.2.1    Shared Object Dependencies

When the linker processes an archive library, library members are extracted and copied into the output object file. These statically linked services are available during execution and do not involve the dynamic loader. Shared executable files also provide services that require the dynamic loader to include the appropriate shared library files in the process image. To accomplish this, shared executable files and shared library files must describe their dependencies.

当链接器处理归档库库成员被提取并复制输出目标文件这些静态链接服务在执行过程中有效,不涉及动态加载器。在进程映像里共享的可执行文件提供的服务需要动态加载器加载适当的共享库文件而要做到这一点共享可执行文件和共享库文件必须描述他们的依赖关系

The dependencies, indicated by the DT_NEEDED entries of the dynamic structure, indicate which shared library files are required for the program. The dynamic loader builds a process image by connecting the referenced shared library files and their dependencies. When resolving symbolic references, the dynamic loader looks first at the symbol table of the shared executable program, then at the symbol tables of the DT_NEEDED entries (in order), then at the second-level DT_NEEDED entries, and so on. Shared library files must be readable by the process.

依赖关系由dynamic结构的DT_NEEDED项表明,表明程序需要哪些共享库文件动态加载器进程映像需要连接相应的共享库文件和它们的依赖关系,解析符号引用动态装载器首先查找共享可执行程序符号表然后在符号表的DT_NEEDED(按顺序)然后第二级DT_NEEDED,依此类推共享库文件必须是可读的过程

Note

Even if a shared object is referenced more than once in the dependency list, the dynamic loader includes only one instance of the object in the process image.

即使一个共享对象的依赖列表不止一次被引用,创建进程时动态加载程序只包含对象的一个实例。


Names in the dependency list are copies of the DT_SONAME strings.

依赖列表名称是DT_SONAME字符串

If a shared library name has one or more slash characters in its name, such as /usr/lib/libz, the dynamic loader uses the string as the pathname. If the name has no slashes, such as liba, the object is searched as follows:

如果共享库的名称一个或多个斜杠字符在其名称如/usr/lib/LIBZ动态加载器使用的路径名的字符串。如果这个名字已经没有斜线,liba搜索对象如下:

The dynamic array tag DT_RPATH may give a string that holds a list of directories separated by colons, such as

DT_RPATH可能是字符串,冒号隔开 

/usr/newlib:/usr/local/lib. The dynamic loader searches these directories in order and, if a library is not located, it then searches the current directory.

动态加载器按顺序搜索这些路径,如果还没有,搜索当前目录

The environment variable LD_LIBRARY_PATH can hold a list of colon-separated directories, optionally followed by a semicolon and another directory list. These directories are searched after those specified by DT_RPATH.

DT_PATH搜索完以后还会搜索环境变量LD_LIBRARY_PATH的路径

If the library was not located in any of the directories specified by DT_RPATH or LD_LIBRARY_PATH, the dynamic loader searches /usr/shlib, /usr/ccs/lib, /usr/lib/cmplrs/cc, /usr/lib, and then /usr/local/lib.

如果还没有找到动态加载器会搜索/usr/shlib,/usr/ccs/lib,/usr/lib/cmplrs/cc, /usr/lib, /usr/local/lib.

The following environment variables are defined:

_RLD_ARGS Argument to dynamic loader
_RLD_ROOT Prefix that the dynamic loader adds to all paths except those
specified by LD_LIBRARY_PATH


Note

For security, the dynamic loader ignores environmental search specifications, such as LD_LIBRARY_PATH, for set-user-ID and set-group-ID programs.

出于安全考虑,动态加载器忽略环境变量的路径搜索。

9.3.3    Global Offset Table (.got)

Position-independent code cannot contain absolute virtual addresses. Global offset tables (GOTs) hold absolute addresses in private data, thus making the addresses available without compromising the position-independence and sharability of a program's text. A program references its global offset table using position-independent addressing and extracts absolute values, thus redirecting position-independent references to absolute locations.

位置无关的代码不能包含绝对虚拟地址,全局偏移(GOTS)里存放数据绝对地址从而使得地址影响程序的文本的位置独立性和共享性程序通过对全局偏移表地址和位置无关的地址提取绝对值从而重定向绝对位置位置无关的引用

The global offset table is split into two logically separate subtables - local and external:

全局偏移被分成两个逻辑独立子表 - 本地和扩展全局偏移表

  • Local entries reside in the first part of the table; these are entries for which there are standard local relocation entries. These entries only require relocation if they occur in a shared library file with a memory load address that differs from the virtual address of its loadable segments. As with the defined external entries in the global offset table, these local entries contain actual addresses.
  • 本地项位于全局偏移表的第1部分,这些是标准的本地重定位项,只有共享库文件的内存加载地址和可加载虚拟地址不同时才重定位,和扩展项不同的是本地项包含实际地址
  • External entries reside in the second part of the section. Each entry in the external part of the GOT corresponds to an entry in the .dynsym section. The first referenced global symbol in the .dynsym section corresponds to the first quadword of the table, the second symbol corresponds to the second quadword, and so on. Each quadword in the external entry part of the GOT contains the actual address for its corresponding symbol.
  • 扩展项位于全局偏移表的第2部分,每个扩展项都有对应的.dynsym节,对应关系:第一项的真实地址在.dynsym部分的第一个四字第二个的真实地址在第二个的四字依次类推。

    The external entries for defined symbols must contain actual addresses. If an entry corresponds to an undefined symbol and the table entry contains a zero, the entry must be resolved by the dynamic loader, even if the dynamic loader is performing a quickstart. (See for information about quickstart processing.)

    扩展项定义的符号必须包含真实地址,如果一个扩展项对应了一个未定义的符号或者扩展项有包含0,该项必须被动态加载器解析动态加载器执行的是快速启动。(快速启动详见9.3.10)


After the system creates memory segments for a loadable object file, the dynamic loader may process the relocation entries. The only relocation entries remaining are type R_REFQUAD or R_REFLONG, referring to local entries in the GOT and data items containing addresses. The dynamic loader determines the associated symbol (or section) values, calculates their absolute addresses, and sets the proper values. Although the absolute addresses may be unknown when the linker builds an object file, the dynamic loader knows the addresses of all memory segments and can find the correct symbols and calculate the absolute addresses.

If a program requires direct access to the absolute address of a symbol, it uses the appropriate GOT entry. Because the shared executable file and shared library file have separate global offset tables, a symbol's address may appear in several tables. The dynamic loader processes all necessary relocations before giving control to the process image, thus ensuring the absolute addresses are available during execution.

The zero (first) entry of the .dynsym section is reserved and holds a null symbol table entry. The corresponding zero entry in the GOT is reserved to hold the address of the entry point in the dynamic loader to call when using lazy binding to resolve text symbols (see for information about resolving text symbols using lazy binding).

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

A single GOT can hold a maximum of 8190 local and global entries. If a program references 8K or more global symbols, it will have multiple GOTs. Each GOT in a multiple-GOT object is referenced by means of a different global pointer value. A single .got section holds all of the GOTs in a multiple-GOT object.

一个.GOT最多可容纳8190本地项和全局项如果某个程序引用8K或多个全局项它将会产生个multiple-GOT。对单个.got引用通过全局指针值,A single got section holds all of the GOTs in a multiple-GOT object.

The DT_MIPS_LOCAL_GOTNO and DT_PLTGOT entries of the dynamic section describe the attributes of the global offset table.

.dynamic节的DT_MIPS_LOCAL_GOTNO和DT_PLTGOT描述全局偏移表的属性


9.3.3.1    Resolving Calls to Position-Independent Functions

The GOT is used to hold addresses of position-independent functions as well as data addresses. It is not possible to resolve function calls from one shared executable file or shared library file to another at static link time, so all of the function address entries in the GOT would normally be resolved at run time by the dynamic loader. Through the use of specially constructed pieces of code known as stubs, this run-time resolution can be deferred through a technique known as lazy binding.

Using the lazy binding technique, the linker builds a stub for each called function and allocates GOT entries that initially point to the stubs. Because of the normal calling sequence for position-independent code, the call invokes the stub the first time that the call is made.


stub_xyz: ldq t12, .got_index(gp) lda $at, .dynsym_index_low(zero) ldah $at, .dynsym_index_high($at) jmp t12, (t12)

The stub code loads register t12 with an entry from the GOT. The entry loaded into register t12 is the address of the procedure in the dynamic loader that handles lazy binding. The stub code also loads register $at with the index into the .dynsym section of the referenced external symbol. The code then transfers control to the dynamic loader and loads register t12 with the address following the stub. The dynamic loader determines the correct address for the called function and replaces the address of the stub in the GOT with the address of the function.

Most undefined text references can be handled by lazy text evaluation, except when the address of a function is used in other than a jsr instruction. In the exception case, the program uses the address of the stub instead of the actual address of the function. Determining which case is in effect is based on the following processing:

  • The linker generates symbol-table entries for all function references with the st_shndx field containing SHN_UNDEF and the st_type field containing STT_FUNC.
  • The dynamic loader examines each symbol-table entry when it starts execution:
    • If the st_value field for one of these symbols is nonzero, only jsr references were made to the function and nothing needs to be done to the GOT entry.
    • If the field is zero, some other kind of reference was made to the function and the GOT entry must be replaced with the actual address of the referenced function.



The LD_BIND_NOW environment variable can also change dynamic loader behavior. If its value is non-null, the dynamic loader evaluates all symbol-table entries of type STT_FUNC, replacing their stub addresses in the GOT with the actual address of the referenced function.

Note

Lazy binding generally improves overall application performance because unused symbols do not incur the dynamic loader overhead. Two situations, however, make lazy binding undesirable for some applications:

  • The initial reference to a function in a shared object file takes longer than subsequent calls because the dynamic loader intercepts the call to resolve the symbol. Some applications cannot tolerate this unpredictability.
  • If an error occurs and the dynamic loader cannot resolve the symbol, the dynamic loader terminates the program. Under lazy binding, this might occur at arbitrary times. Once again, some applications cannot tolerate this unpredictability.


By turning off lazy binding, the dynamic loader forces the failure to occur during process initialization, before the application receives control.

9.3.4    Dynamic Symbol Section (.dynsym)

The dynamic symbol section provides information on all external symbols, either imported or exported from an object.

All externally visible symbols, both defined and undefined, must be hashed into the hash table (see).

Undefined symbols of type STT_FUNC that have been referenced only by jsr instructions may contain nonzero values in their st_value field denoting the stub address used for lazy evaluation for this symbol. The dynamic loader uses this to reset the GOT entry for this external symbol to its stub address when unloading a shared library file. All other undefined symbols must contain zero in their st_value fields.

Defined symbols in a shared executable file cannot be preempted. The symbol table in the shared executable file is always searched first to resolve any symbol references.


The dynamic symbol section contains an array of entries of the following type:


typedef struct { Elf32_Word st_name; Elf32_Addr st_value; Elf32_Word st_size; unsigned char st_info; unsigned char st_other; Elf32_Half st_shndx; } Elf32_Sym;

The structure members in the preceding structure definition provide the following information:

st_name Contains the offset of the symbol's name in the dynamic string section.


st_value Contains the value of the symbol for those symbols defined within the object; otherwise, contains the value zero.


st_size Identifies the size of symbols with common storage allocation; otherwise, contains the value zero. For STB_DUPLICATE symbols, the size field holds the index of the primary symbol.


st_info Identifies the symbol's binding and type. The macros ELF32_ST_BIND and ELF32_ST_TYPE are used to access the individual values.

A symbol's binding determines the linkage visibility and behavior. The binding is encoded in the st_info field and can have one of the following values:

Value Description
STB_LOCAL Indicates that the symbol is local to the object.
STB_GLOBAL Indicates that the symbol is visible to other objects.
STB_WEAK Indicates that the symbol is a weak global symbol.
STB_DUPLICATE Indicates the symbol is a duplicate. (Used for objects that have multiple GOTs.)

A symbol's type identifies its use. The type is encoded in the st_info field and can have one of the following values:

Value Description
STT_NOTYPE Indicates that the symbol has no type or its type is unknown.
STT_OBJECT Indicates that the symbol is a data object.
STT_FUNC Indicates that the symbol is a function.
STT_SECTION Indicates that the symbol is associated with a program section.
STT_FILE Indicates that the symbol as the name of a source file.



st_other Currently holds a value of zero and has no defined meaning.


st_shndx Identifies the section to which this symbol is related.

All symbols are defined relative to some program section. The st_shndx field identifies the section and can have one of the following values:

Value Description
SHN_UNDEF Indicates that the symbol is undefined.
SHN_ABS Indicates that the symbol has an absolute value.
SHN_COMMON Indicates that the symbol has common storage (unallocated).
SHN_MIPS_ACOMMON Indicates that the symbol has common storage (allocated).
SHN_MIPS_TEXT Indicates that the symbol is in a text segment.
SHN_MIPS_DATA Indicates that the symbol is in a data segment.



The entries of the dynamic symbol section are ordered as follows:

  • A single null entry.
  • Symbols local to the object.
  • Unreferenced global symbols, that is, symbols that are defined within the object but not referenced.
  • Referenced global symbols. These symbols correspond one-to-one with the GOT entries for global symbols.

shows the layout of the .dynsym section and its relationship to the .got section.

Figure 9-2: Relationship Between .dynsym and .got


The DT_SYMENT and DT_SYMTAB entries of the dynamic section describe the attributes of the dynamic symbol table.

.dynamic节的DT_SYMENTDT_SYMTAB条目描述动态符号表中的属性


9.3.5    Dynamic Relocation Section (.rel.dyn)

The dynamic relocation section describes all locations within the object that must be adjusted if the object is loaded at an address other than its linked base address.

.rel.dyn节描述的是调整对象,这些对象是加载链接基地址以外

Only one dynamic relocation section is used to resolve addresses in data items, and it must be called .rel.dyn. Shared executable files can contain normal relocation sections in addition to a dynamic relocation section. The normal relocation sections may contain resolutions for any absolute values in the main program. The dynamic linker does not resolve these or relocate the main program.

只有一个.rel.dyn节是用来解析数据项地址,并且必须调用.rel.dyn共享的可执行文件除了包含普通的重定位节还包含动态的重定位节The normal relocation sections may contain resolutions for any absolute values in the main program。动态链接器不解析这些或重定位主要代码

As noted previously, only R_REFQUAD and R_REFLONG relocation entries are supported in the dynamic relocation section.

如前所述只有R_REFQUADR_REFLONG重定位项被支在.rel.dyn。

The dynamic relocation section is an array of entries of the following type:

.rel.dyn节类型如下


typedef struct { Elf32_Addr r_offset; Elf32_Word r_info; } Elf32_Rel;

The structure members in the preceding structure definition provide the following information:

在前面的结构定义结构成员提供下列信息

r_offset Identifies the location within the object to be adjusted.
r_offset标识要调整的对象位置


r_info Identifies the relocation type and the index of the symbol that is referenced. The macros ELF32_R_SYM and ELF32_R_TYPE access the individual attributes. The relocation type must be either R_REFQUAD or R_REFLONG.
r_info确定重定位类型和所引用的符号索引ELF32_R_SYMELF32_R_TYPE访问属性,重定位类型必须是R_REFQUADR_REFLONG


The entries of the dynamic relocation section are ordered by symbol index value.

.rel.dyn节中的项符号索引值进行排列

The DT_REL and DT_RELSZ entries of the dynamic section describe the attributes of the dynamic relocation section.

.dynamic节的DT_RELDT_RELSZ描述.rel.dyn的属性

9.3.6    Msym Section (.msym)

The optional .msym section contains precomputed hash values and dynamic relocation indexes for each entry in the dynamic symbol table. Each entry in the .msym section maps directly to an entry in the .dynsym section. The .msym section is an array of entries of the following type:


typedef struct { Elf32_Word ms_hash_value; Elf32_Word ms_info; } Elf32_Msym;

The structure members in the preceding structure definition provide the following information:

ms_hash_value The hash value computed from the name of the corresponding dynamic symbol.


ms_info Contains both the dynamic relocation index and the symbol flags field. The macros ELF32_MS_REL_INDEX and ELF32_MS_FLAGS are used to acess the individual values.

The dynamic relocation index identifies the first entry in the .rel.dyn section that references the dynamic symbol corresponding to this msym entry. If the index is 0, no dynamic relocations are associated with the symbol.

The symbol flags field is reserved for future use.

The DT_MIPS_MSYM entry of the dynamic section contains the address of the .msym section.

9.3.7    Hash Table Section (.hash)

A hash table of Elf32_Word entries provides fast access to symbol entries in the dynamic symbol section. shows the contents of a hash table.

Figure 9-3: Hash Table Section

The entries in the hash table contain the following information:

  • The nbucket entry indicates the number of entries in the bucket array.
  • The nchain entry indicates the number of entries in the chain array.
  • The bucket and chain entries hold symbol table indexes; the entries in chain parallel the symbol table. The number of symbol table entries should be equal to nchain; symbol table indexes also select chain entries.

The hashing function accepts a symbol name and returns a value that can be used to compute a bucket index. If the hashing function returns the value X for a name, bucket[X % nbucket] gives an index, Y, into the symbol table and chain array. If the symbol table entry indicated is not the correct one, chain[Y] indicates the next symbol table entry with the same hash value. The chain links can be followed until the correct symbol table entry is located or until the chain entry contains the value STN_UNDEF.

The DT_HASH entry of the dynamic section contains the address of the hash table section.

9.3.8    Dynamic String Section (.dynstr)

The dynamic string section is the repository for all strings referenced by the dynamic linking sections. Strings are referenced by using a byte offset within the dynamic string section. The end of the string is denoted by a byte containing the value zero.

The DT_STRTAB and DT_STRSZ entries of the dynamic section describe the attributes of the dynamic string section.

9.3.9    Initialization and Termination Functions

After the dynamic loader has created the process image and performed relocations, each shared object file gets the opportunity to execute initialization code. The initialization functions are called in reverse-dependency order. Each shared object file's initialization functions are called
only after the initialization functions for its dependencies have been executed. All initialization of shared object files occurs before the executable file gains control.

Similarly, shared object files can have termination functions that are executed by the atexit mechanism when the process is terminating. Termination functions are called in dependency order - the exact opposite of the order in which initialization functions are called.

Shared object files designate initialization and termination functions through the DT_INIT and DT_FINI entries in the dynamic structure. Typically, the code for these functions resides in the .init and .fini sections.

Note

Although atexit termination processing normally is done, it is not guaranteed to have executed when the process terminates. In particular, the process does not execute the termination processing if it calls _exit or if the process terminates because it received a signal that it neither caught nor ignored.

9.3.10    Quickstart

The quickstart capability provided by the assembler supports several sections that are useful for faster startup of programs that have been linked with shared library files. Some ordering constraints are imposed on these sections. The group of structures defined in these sections and the ordering constraints allow the dynamic loader to operate more efficiently. These additional sections are also used for more complete dynamic shared library file version control.

9.3.10.1    Shared Object List (.liblist)

A shared object list section is an array of Elf32_Lib structures that contains information about the various dynamic shared library files used to statically link the shared object file. Each shared library file used has an entry in the array. Each entry has the following format:


typedef struct { Elf32_Word l_name; Elf32_Word l_time_stamp; Elf32_Word l_checksum; Elf32_Word l_version; Elf32_Word l_flags; } Elf32_Lib;

The structure members in the preceding structure definition provide the following information:

l_name Specifies the name of a shared library file. Its value is a string table index. This name can be a full pathname, relative pathname, or file name.


l_time_stamp Contains a 32-bit time stamp. The value can be combined with the l_checksum value and the l_version string to form a unique identifier for this shared library file.


l_checksum Contains the sum of all common sizes and all string names of externally visible symbols.


l_version Specifies the interface version. Its value is a string table index. The interface version is a string containing no colons. It is compared to a colon separated string of versions pointed to by a dynamic section entry of the shared library file. Shared library file with matching names may be considered incompatible if the interface version strings are deemed incompatible. An index value of zero means no version string is specified and is equivalent to the string _null.


l_flags Specifies a set of 1-bit flags.

The l_flags field can have one or both of the following flags set:

LL_EXACT_MATCH At run time, use a unique ID composed of the l_time_stamp, l_checksum, and l_version fields to demand that the run-time dynamic shared library file match exactly the shared library file used at static link time.
LL_IGNORE_INT_VER At run time, ignore any version incompatibility between the dynamic shared library file and the shared library file used at static link time.

Normally, if neither LL_EXACT_MATCH nor LL_IGNORE_INT_VER bits are set, the dynamic loader requires that the version of the dynamic shared library match at least one of the colon separated version strings indexed by the l_version string table index.


The DT_MIPS_LIBLIST and DT_MIPS_LIBLISTNO entries of the dynamic section describe the attributes of the shared object list section.

9.3.10.2    Conflict Section (.conflict)

Each .conflict section is an array of indexes into the .dynsym section. Each index entry identifies a symbol that is multiply defined in either of the following ways:

  • The symbol is defined in the shared object file and one or more of the shared library files that the shared object file depends on.
  • The symbol is defined in two or more or the shared library files that the shared object file depends on.


The shared library files that the shared object file depends on are identified at static link time.

The symbols identified in this section must be resolved by the dynamic loader, even if the object is quickstarted. The dynamic loader resolves all references of a multiply-defined symbol to a single definition.

The .conflict section is an array of Elf32_Conflict elements:


typedef Elf32_Word Elf32_Conflict;

The DT_MIPS_CONFLICT and DT_MIPS_CONFLICTNO entries of the dynamic section describe the attributes of the conflict section.

9.3.10.3    Ordering of Sections

In order to take advantage of the quickstart capability, ordering constraints are imposed on the .rel.dyn section. The .rel.dyn section must have all local entries first, followed by the external entries. Within these subsections, the entries must be ordered by symbol index. This groups each symbol's relocations together.


阅读(4901) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~