This chapter describes the executable and linking format (ELF) of the object files produced by the assembler and link-editor. Three significant types of object file exist.
-
A relocatable object file holds sections containing code and data. This file is suitable to be linked with other relocatable object files to create dynamic executable files, shared object files, or another relocatable object.
-
A dynamic executable file holds a program that is ready to execute. The file specifies how exec(2) creates a program's process image. This file is typically bound to shared object files at runtime to create a process image.
-
A shared object file holds code and data that is suitable for additional linking. The link-editor can process this file with other relocatable object files and shared object files to create other object files. The runtime linker combines this file with a dynamic executable file and other shared object files to create a process image.
The first section in this chapter, File Format, focuses on the format of object files and how the format pertains to creating programs. The second section, Dynamic Linking, focuses on how the format pertains to loading programs.
Programs can manipulate object files with the functions that are provided by the ELF access library, libelf. Refer to elf(3ELF) for a description of libelf contents. Sample source code that uses libelf is provided in the SUNWosdem package under the/usr/demo/ELF directory.
File Format
Object files participate in both program linking and program execution. For convenience and efficiency, the object file format provides parallel views of a file's contents, reflecting the differing needs of these activities. The following figure shows an object file's organization.
Figure 7–1 Object File Format
![Object file formats. Object file formats.](https://i-blog.csdnimg.cn/blog_migrate/083dab4424d890bb549465668b05aa6d.gif)
An ELF header resides at the beginning of an object file and holds a road map describing the file's organization.
Note –
Only the ELF header has a fixed position in the file. The flexibility of the ELF format requires no specified order for header tables, sections or segments. However, this figure is typical of the layout used in the Solaris OS.
Sections represent the smallest indivisible units that can be processed within an ELF file. Segments are a collection of sections. Segments represent the smallest individual units that can be mapped to a memory image by exec(2) or by the runtime linker.
Sections hold the bulk of object file information for the linking view. This data includes instructions, data, symbol table, and relocation information. Descriptions of sections appear in the first part of this chapter. The second part of this chapter discusses segments and the program execution view of the file.
A program header table, if present, tells the system how to create a process image. Files used to generate a process image, executable files and shared objects, must have a program header table. Relocatable object files do not need a program header table.
A section header table contains information describing the file's sections. Every section has an entry in the table. Each entry gives information such as the section name and section size. Files that are used in link-editing must have a section header table.
Data Representation
The object file format supports various processors with 8-bit bytes, 32–bit architectures and 64–bit architectures. Nevertheless, the data representation is intended to be extensible to larger, or smaller, architectures. Table 7–1 and Table 7–2 list the 32–bit data types and 64–bit data types.
Object files represent some control data with a machine-independent format. This format provides for the common identification and interpretation of object files. The remaining data in an object file use the encoding of the target processor, regardless of the machine on which the file was created.
Table 7–1 ELF 32–Bit Data Types Name | Size | Alignment | Purpose |
---|---|---|---|
Elf32_Addr | 4 | 4 | Unsigned program address |
Elf32_Half | 2 | 2 | Unsigned medium integer |
Elf32_Off | 4 | 4 | Unsigned file offset |
Elf32_Sword | 4 | 4 | Signed integer |
Elf32_Word | 4 | 4 | Unsigned integer |
unsigned char | 1 | 1 | Unsigned small integer |
Name | Size | Alignment | Purpose |
---|---|---|---|
Elf64_Addr | 8 | 8 | Unsigned program address |
Elf64_Half | 2 | 2 | Unsigned medium integer |
Elf64_Off | 8 | 8 | Unsigned file offset |
Elf64_Sword | 4 | 4 | Signed integer |
Elf64_Word | 4 | 4 | Unsigned integer |
Elf64_Xword | 8 | 8 | Unsigned long integer |
Elf64_Sxword | 8 | 8 | Signed long integer |
unsigned char | 1 | 1 | Unsigned small integer |
All data structures that the object file format defines follow the natural size and alignment guidelines for the relevant class. Data structures can contain explicit padding to ensure 4-byte alignment for 4-byte objects, to force structure sizes to a multiple of 4, and so forth. Data also have suitable alignment from the beginning of the file. Thus, for example, a structure containing an Elf32_Addr member is aligned on a 4-byte boundary within the file. Similarly, a structure containing an Elf64_Addr member is aligned on an 8–byte boundary.
Note –
For portability, ELF uses no bit-fields.
ELF Header
Some control structures within object files can grow because the ELF header contains their actual sizes. If the object file format does change, a program can encounter control structures that are larger or smaller than expected. Programs might therefore ignore extra information. The treatment of missing information depends on context and is specified if and when extensions are defined.
The ELF header has the following structure. See sys/elf.h.
#define EI_NIDENT 16 typedef struct { unsigned char e_ident[EI_NIDENT]; Elf32_Half e_type; Elf32_Half e_machine; Elf32_Word e_version; Elf32_Addr e_entry; Elf32_Off e_phoff; Elf32_Off e_shoff; Elf32_Word e_flags; Elf32_Half e_ehsize; Elf32_Half e_phentsize; Elf32_Half e_phnum; Elf32_Half e_shentsize; Elf32_Half e_shnum; Elf32_Half e_shstrndx; } Elf32_Ehdr; typedef struct { unsigned char e_ident[EI_NIDENT]; Elf64_Half e_type; Elf64_Half e_machine; Elf64_Word e_version; Elf64_Addr e_entry; Elf64_Off e_phoff; Elf64_Off e_shoff; Elf64_Word e_flags; Elf64_Half e_ehsize; Elf64_Half e_phentsize; Elf64_Half e_phnum; Elf64_Half e_shentsize; Elf64_Half e_shnum; Elf64_Half e_shstrndx; } Elf64_Ehdr;
-
e_ident
-
The initial bytes mark the file as an object file. These bytes provide machine-independent data with which to decode and interpret the file's contents. Complete descriptions appear in ELF Identification.
e_type
-
Identifies the object file type, as listed in the following table.
Name
Value
Meaning
ET_NONE
0
No file type
ET_REL
1
Relocatable file
ET_EXEC
2
Executable file
ET_DYN
3
Shared object file
ET_CORE
4
Core file
ET_LOPROC
0xff00
Processor-specific
ET_HIPROC
0xffff
Processor-specific
Although the core file contents are unspecified, type ET_CORE is reserved to mark the file. Values from ET_LOPROC throughET_HIPROC (inclusive) are reserved for processor-specific semantics. Other values are reserved for future use.
e_machine
-
Specifies the required architecture for an individual file. Relevant architectures are listed in the following table.
Name
Value
Meaning
EM_NONE
0
No machine
EM_SPARC
2
SPARC
EM_386
3
Intel 80386
EM_SPARC32PLUS
18
Sun SPARC 32+
EM_SPARCV9
43
SPARC V9
EM_AMD64
62
AMD 64
Other values are reserved for future use. Processor-specific ELF names are distinguished by using the machine name. For example, the flags defined for e_flags use the prefix EF_. A flag that is named WIDGET for the EM_XYZ machine would be calledEF_XYZ_WIDGET.
e_version
-
Identifies the object file version, as listed in the following table.
Name
Value
Meaning
EV_NONE
0
Invalid version
EV_CURRENT
>=1
Current version
The value 1 signifies the original file format. The value of EV_CURRENT changes as necessary to reflect the current version number.
e_entry
-
The virtual address to which the system first transfers control, thus starting the process. If the file has no associated entry point, this member holds zero.
e_phoff
-
The program header table's file offset in bytes. If the file has no program header table, this member holds zero.
e_shoff
-
The section header table's file offset in bytes. If the file has no section header table, this member holds zero.
e_flags
-
Processor-specific flags associated with the file. Flag names take the form EF_machine_flag. This member is presently zero for x86. The SPARC flags are listed in the following table.
Name
Value
Meaning
EF_SPARC_EXT_MASK
0xffff00
Vendor Extension mask
EF_SPARC_32PLUS
0x000100
Generic V8+ features
EF_SPARC_SUN_US1
0x000200
Sun UltraSPARCTM 1 Extensions
EF_SPARC_HAL_R1
0x000400
HAL R1 Extensions
EF_SPARC_SUN_US3
0x000800
Sun UltraSPARC 3 Extensions
EF_SPARCV9_MM
0x3
Mask for Memory Model
EF_SPARCV9_TSO
0x0
Total Store Ordering
EF_SPARCV9_PSO
0x1
Partial Store Ordering
EF_SPARCV9_RMO
0x2
Relaxed Memory Ordering
e_ehsize
-
The ELF header's size in bytes.
e_phentsize
-
The size in bytes of one entry in the file's program header table. All entries are the same size.
e_phnum
-
The number of entries in the program header table. The product of e_phentsize and e_phnum gives the table's size in bytes. If a file has no program header table, e_phnum holds the value zero.
If the number of program headers is greater than or equal to PN_XNUM (0xffff), this member has the value PN_XNUM(0xffff). The actual number of program header table entries is contained in the sh_info field of the section header at index 0. Otherwise, the sh_info member of the initial section header entry contains the value zero. See Table 7–6 and Table 7–7.
e_shentsize
-
A section header's size in bytes. A section header is one entry in the section header table. All entries are the same size.
e_shnum
-
The number of entries in the section header table. The product of e_shentsize and e_shnum gives the section header table's size in bytes. If a file has no section header table, e_shnum holds the value zero.
If the number of sections is greater than or equal to SHN_LORESERVE (0xff00), e_shnum has the value zero. The actual number of section header table entries is contained in the sh_size field of the section header at index 0. Otherwise, thesh_size member of the initial section header entry contains the value zero. See Table 7–6 and Table 7–7.
e_shstrndx
-
The section header table index of the entry that is associated with the section name string table. If the file has no section name string table, this member holds the value SHN_UNDEF.
If the section name string table section index is greater than or equal to SHN_LORESERVE (0xff00), this member has the valueSHN_XINDEX (0xffff) and the actual index of the section name string table section is contained in the sh_link field of the section header at index 0. Otherwise, the sh_link member of the initial section header entry contains the value zero. SeeTable 7–6 and Table 7–7.
ELF Identification
ELF provides an object file framework to support multiple processors, multiple data encoding, and multiple classes of machines. To support this object file family, the initial bytes of the file specify how to interpret the file. These bytes are independent of the processor on which the inquiry is made and independent of the file's remaining contents.
The initial bytes of an ELF header and an object file correspond to the e_ident member.
Table 7–3 ELF Identification Index Name | Value | Purpose |
---|---|---|
EI_MAG0 | 0 | File identification |
EI_MAG1 | 1 | File identification |
EI_MAG2 | 2 | File identification |
EI_MAG3 | 3 | File identification |
EI_CLASS | 4 | File class |
EI_DATA | 5 | Data encoding |
EI_VERSION | 6 | File version |
EI_OSABI | 7 | Operating system/ABI identification |
EI_ABIVERSION | 8 | ABI version |
EI_PAD | 9 | Start of padding bytes |
EI_NIDENT | 16 | Size of e_ident[] |
These indexes access bytes that hold the following values.
-
EI_MAG0 -
EI_MAG3
-
A 4–byte magic number, identifying the file as an ELF object file, as listed in the following table.
Name
Value
Position
ELFMAG0
0x7f
e_ident[EI_MAG0]
ELFMAG1
'E'
e_ident[EI_MAG1]
ELFMAG2
'L'
e_ident[EI_MAG2]
ELFMAG3
'F'
e_ident[EI_MAG3]
EI_CLASS
-
Byte e_ident[EI_CLASS] identifies the file's class, or capacity, as listed in the following table.
Name
Value
Meaning
ELFCLASSNONE
0
Invalid class
ELFCLASS32
1
32–bit objects
ELFCLASS64
2
64–bit objects
The file format is designed to be portable among machines of various sizes, without imposing the sizes of the largest machine on the smallest. The class of the file defines the basic types used by the data structures of the object file container. The data that is contained in object file sections can follow a different programming model.
Class ELFCLASS32 supports machines with files and virtual address spaces up to 4 gigabytes. This class uses the basic types that are defined in Table 7–1.
Class ELFCLASS64 is reserved for 64–bit architectures such as 64–bit SPARC and x64. This class uses the basic types that are defined in Table 7–2.
EI_DATA
-
Byte e_ident[EI_DATA] specifies the data encoding of the processor-specific data in the object file, as listed in the following table.
Name
Value
Meaning
ELFDATANONE
0
Invalid data encoding
ELFDATA2LSB
1
See Figure 7–2.
ELFDATA2MSB
2
See Figure 7–3.
More information on these encodings appears in the section Data Encoding. Other values are reserved for future use.
EI_VERSION
-
Byte e_ident[EI_VERSION] specifies the ELF header version number. Currently, this value must be EV_CURRENT.
EI_OSABI
-
Byte e_ident[EI_OSABI] identifies the operating system together with the ABI to which the object is targeted. Some fields in other ELF structures have flags and values that have operating system or ABI specific meanings. The interpretation of those fields is determined by the value of this byte.
EI_ABIVERSION
-
Byte e_ident[EI_ABIVERSION] identifies the version of the ABI to which the object is targeted. This field is used to distinguish among incompatible versions of an ABI. The interpretation of this version number is dependent on the ABI identified by theEI_OSABI field. If no values are specified for the EI_OSABI field for the processor, or no version values are specified for the ABI determined by a particular value of the EI_OSABI byte, the value zero is used to indicate unspecified.
EI_PAD
-
This value marks the beginning of the unused bytes in e_ident. These bytes are reserved and are set to zero. Programs that read object files should ignore these values.
Data Encoding
A file's data encoding specifies how to interpret the integer types in a file. Class ELFCLASS32 files and class ELFCLASS64 files use integers that occupy 1, 2, 4, and 8 bytes to represent offsets, addresses and other information. Under the defined encodings, objects are represented as described by the figures that follow. Byte numbers appear in the upper left corners.
ELFDATA2LSB encoding specifies 2's complement values, with the least significant byte occupying the lowest address. This encoding if often referred to informally as little endian.
Figure 7–2 Data Encoding ELFDATA2LSB
![ELFDATA2LSB data encoding. ELFDATA2LSB data encoding.](https://i-blog.csdnimg.cn/blog_migrate/253da47959783d5e36164c0952c19c86.gif)
ELFDATA2MSB encoding specifies 2's complement values, with the most significant byte occupying the lowest address. This encoding if often referred to informally as big endian.
Figure 7–3 Data Encoding ELFDATA2MSB
![ELFDATA2MSB data encoding. ELFDATA2MSB data encoding.](https://i-blog.csdnimg.cn/blog_migrate/adca27a47e611e648b19ead7b1402dd4.gif)
Sections
An object file's section header table allows you to locate all of the sections of the file. The section header table is an array of Elf32_Shdror Elf64_Shdr structures. A section header table index is a subscript into this array. The ELF header's e_shoff member indicates the byte offset from the beginning of the file to the section header table. The e_shnum member indicates how many entries that the section header table contains. The e_shentsize member indicates the size in bytes of each entry.
If the number of sections is greater than or equal to SHN_LORESERVE (0xff00), e_shnum has the value SHN_UNDEF (0). The actual number of section header table entries is contained in the sh_size field of the section header at index 0. Otherwise, the sh_sizemember of the initial entry contains the value zero.
Some section header table indexes are reserved in contexts where index size is restricted. For example, the st_shndx member of a symbol table entry and the e_shnum and e_shstrndx members of the ELF header. In such contexts, the reserved values do not represent actual sections in the object file. Also in such contexts, an escape value indicates that the actual section index is to be found elsewhere, in a larger field.
Table 7–4 ELF Special Section Indexes Name | Value |
---|---|
SHN_UNDEF | 0 |
SHN_LORESERVE | 0xff00 |
SHN_LOPROC | 0xff00 |
SHN_BEFORE | 0xff00 |
SHN_AFTER | 0xff01 |
SHN_AMD64_LCOMMON | 0xff02 |
SHN_HIPROC | 0xff1f |
SHN_LOOS | 0xff20 |
SHN_LOSUNW | 0xff3f |
SHN_SUNW_IGNORE | 0xff3f |
SHN_HISUNW | 0xff3f |
SHN_HIOS | 0xff3f |
SHN_ABS | 0xfff1 |
SHN_COMMON | 0xfff2 |
SHN_XINDEX | 0xffff |
SHN_HIRESERVE | 0xffff |
Note –
Although index 0 is reserved as the undefined value, the section header table contains an entry for index 0. That is, if the e_shnummember of the ELF header indicates a file has 6 entries in the section header table, the sections have the indexes 0 through 5. The contents of the initial entry are specified later in this section.
-
SHN_UNDEF
-
An undefined, missing, irrelevant, or otherwise meaningless section reference. For example, a symbol defined relative to section number SHN_UNDEF is an undefined symbol.
SHN_LORESERVE
- SHN_LOPROC - SHN_HIPROC
-
Values in this inclusive range are reserved for processor-specific semantics.
SHN_LOOS -
SHN_HIOS
-
Values in this inclusive range are reserved for operating system-specific semantics.
SHN_LOSUNW -
SHN_HISUNW
-
Values in this inclusive range are reserved for Sun-specific semantics.
SHN_SUNW_IGNORE
-
This section index provides a temporary symbol definition within relocatable objects. Reserved for internal use by dtrace(1M).
SHN_BEFORE, SHN_AFTER
-
Provide for initial and final section ordering in conjunction with the SHF_LINK_ORDER and SHF_ORDERED section flags. SeeTable 7–8.
SHN_AMD64_LCOMMON
-
x64 specific common block label. This label is similar to SHN_COMMON, but provides for identifying a large common block.
SHN_ABS
-
Absolute values for the corresponding reference. For example, symbols defined relative to section number SHN_ABS have absolute values and are not affected by relocation.
SHN_COMMON
-
Symbols defined relative to this section are common symbols, such as FORTRAN COMMON or unallocated C external variables. These symbols are sometimes referred to as tentative.
SHN_XINDEX
-
An escape value indicating that the actual section header index is too large to fit in the containing field. The header section index is found in another location specific to the structure where the section index appears.
SHN_HIRESERVE
-
The upper boundary of the range of reserved indexes. The system reserves indexes between SHN_LORESERVE andSHN_HIRESERVE, inclusive. The values do not reference the section header table. The section header table does not contain entries for the reserved indexes.
Sections contain all information in an object file except the ELF header, the program header table, and the section header table. Moreover, the sections in object files satisfy several conditions.
-
Every section in an object file has exactly one section header describing the section. Section headers can exist that do not have a section.
-
Each section occupies one contiguous, possibly empty, sequence of bytes within a file.
-
Sections in a file cannot overlap. No byte in a file resides in more than one section.
-
An object file can have inactive space. The various headers and the sections might not cover every byte in an object file. The contents of the inactive data are unspecified.
A section header has the following structure. See sys/elf.h.
typedef struct { elf32_Word sh_name; Elf32_Word sh_type; Elf32_Word sh_flags; Elf32_Addr sh_addr; Elf32_Off sh_offset; Elf32_Word sh_size; Elf32_Word sh_link; Elf32_Word sh_info; Elf32_Word sh_addralign; Elf32_Word sh_entsize; } Elf32_Shdr; typedef struct { Elf64_Word sh_name; Elf64_Word sh_type; Elf64_Xword sh_flags; Elf64_Addr sh_addr; Elf64_Off sh_offset; Elf64_Xword sh_size; Elf64_Word sh_link; Elf64_Word sh_info; Elf64_Xword sh_addralign; Elf64_Xword sh_entsize; } Elf64_Shdr;
-
sh_name
-
The name of the section. This members value is an index into the section header string table section giving the location of a null-terminated string. Section names and their descriptions are listed in Table 7–10.
sh_type
-
Categorizes the section's contents and semantics. Section types and their descriptions are listed in Table 7–5.
sh_flags
-
Sections support 1-bit flags that describe miscellaneous attributes. Flag definitions are listed in Table 7–8.
sh_addr
-
If the section appears in the memory image of a process, this member gives the address at which the section's first byte should reside. Otherwise, the member contains the value zero.
sh_offset
-
The byte offset from the beginning of the file to the first byte in the section. For a SHT_NOBITS section, this member indicates the conceptual offset in the file, as the section occupies no space in the file.
sh_size
-
The section's size in bytes. Unless the section type is SHT_NOBITS, the section occupies sh_size bytes in the file. A section of type SHT_NOBITS can have a nonzero size, but the section occupies no space in the file.
sh_link
-
A section header table index link, whose interpretation depends on the section type. Table 7–9 describes the values.
sh_info
-
Extra information, whose interpretation depends on the section type. Table 7–9 describes the values. If the sh_flags field for this section header includes the attribute SHF_INFO_LINK, then this member represents a section header table index.
sh_addralign
-
Some sections have address alignment constraints. For example, if a section holds a double-word, the system must ensure double-word alignment for the entire section. In this case, the value of sh_addr must be congruent to 0, modulo the value ofsh_addralign. Currently, only 0 and positive integral powers of two are allowed. Values 0 and 1 mean the section has no alignment constraints.
sh_entsize
-
Some sections hold a table of fixed-size entries, such as a symbol table. For such a section, this member gives the size in bytes of each entry. The member contains the value zero if the section does not hold a table of fixed-size entries.
A section header's sh_type member specifies the section's semantics, as shown in the following table.
Table 7–5 ELF Section Types, sh_type Name | Value |
---|---|
SHT_NULL | 0 |
SHT_PROGBITS | 1 |
SHT_SYMTAB | 2 |
SHT_STRTAB | 3 |
SHT_RELA | 4 |
SHT_HASH | 5 |
SHT_DYNAMIC | 6 |
SHT_NOTE | 7 |
SHT_NOBITS | 8 |
SHT_REL | 9 |
SHT_SHLIB | 10 |
SHT_DYNSYM | 11 |
SHT_INIT_ARRAY | 14 |
SHT_FINI_ARRAY | 15 |
SHT_PREINIT_ARRAY | 16 |
SHT_GROUP | 17 |
SHT_SYMTAB_SHNDX | 18 |
SHT_LOOS | 0x60000000 |
SHT_LOSUNW | 0x6ffffff4 |
SHT_SUNW_dof | 0x6ffffff4 |
SHT_SUNW_cap | 0x6ffffff5 |
SHT_SUNW_SIGNATURE | 0x6ffffff6 |
SHT_SUNW_ANNOTATE | 0x6ffffff7 |
SHT_SUNW_DEBUGSTR | 0x6ffffff8 |
SHT_SUNW_DEBUG | 0x6ffffff9 |
SHT_SUNW_move | 0x6ffffffa |
SHT_SUNW_COMDAT | 0x6ffffffb |
SHT_SUNW_syminfo | 0x6ffffffc |
SHT_SUNW_verdef | 0x6ffffffd |
SHT_SUNW_verneed | 0x6ffffffe |
SHT_SUNW_versym | 0x6fffffff |
SHT_HISUNW | 0x6fffffff |
SHT_HIOS | 0x6fffffff |
SHT_LOPROC | 0x70000000 |
SHT_SPARC_GOTDATA | 0x70000000 |
SHT_AMD64_UNWIND | 0x70000001 |
SHT_HIPROC | 0x7fffffff |
SHT_LOUSER | 0x80000000 |
SHT_HIUSER | 0xffffffff |
-
SHT_NULL
-
Identifies the section header as inactive. This section header does not have an associated section. Other members of the section header have undefined values.
SHT_PROGBITS
-
Identifies information defined by the program, whose format and meaning are determined solely by the program.
SHT_SYMTAB,
SHT_DYNSYM
-
Identifies a symbol table. Typically, a SHT_SYMTAB section provides symbols for link-editing. As a complete symbol table, the table can contain many symbols that are unnecessary for dynamic linking. Consequently, an object file can also contain a SHT_DYNSYMsection, which holds a minimal set of dynamic linking symbols, to save space.
See Symbol Table Section for details.
SHT_STRTAB,
SHT_DYNSTR
-
Identifies a string table. An object file can have multiple string table sections. See String Table Section for details.
SHT_RELA
-
Identifies relocation entries with explicit addends, such as type Elf32_Rela for the 32–bit class of object files. An object file can have multiple relocation sections. See Relocation Sections for details.
SHT_HASH
-
Identifies a symbol hash table. A dynamically linked object file must contain a symbol hash table. Currently, an object file can have only one hash table, but this restriction might be relaxed in the future. See Hash Table Section for details.
SHT_DYNAMIC
-
Identifies information for dynamic linking. Currently, an object file can have only one dynamic section. See Dynamic Section for details.
SHT_NOTE
-
Identifies information that marks the file in some way. See Note Section for details.
SHT_NOBITS
-
Identifies a section that occupies no space in the file but otherwise resembles SHT_PROGBITS. Although this section contains no bytes, the sh_offset member contains the conceptual file offset.
SHT_REL
-
Identifies relocation entries without explicit addends, such as type Elf32_Rel for the 32–bit class of object files. An object file can have multiple relocation sections. See Relocation Sections for details.
SHT_SHLIB
-
Identifies a reserved section which has unspecified semantics. Programs that contain a section of this type do not conform to the ABI.
SHT_INIT_ARRAY
-
Identifies a section containing an array of pointers to initialization functions. Each pointer in the array is taken as a parameterless procedure with a void return. See Initialization and Termination Sections for details.
SHT_FINI_ARRAY
-
Identifies a section containing an array of pointers to termination functions. Each pointer in the array is taken as a parameterless procedure with a void return. See Initialization and Termination Sections for details.
SHT_PREINIT_ARRAY
-
Identifies a section containing an array of pointers to functions that are invoked before all other initialization functions. Each pointer in the array is taken as a parameterless procedure with a void return. See Initialization and Termination Sections for details.
SHT_GROUP
-
Identifies a section group. A section group identifies a set of related sections that must be treated as a unit by the link-editor. Sections of type SHT_GROUP can appear only in relocatable objects. See Group Section for details.
SHT_SYMTAB_SHNDX
-
Identifies a section containing extended section indexes, that are associated with a symbol table. If any section header indexes referenced by a symbol table, contain the escape value SHN_XINDEX, an associated SHT_SYMTAB_SHNDX is required.
The SHT_SYMTAB_SHNDX section is an array of Elf32_Word values. This array contains one entry for every entry in the associated symbol table entry. The values represent the section header indexes against which the symbol table entries are defined. Only if corresponding symbol table entry's st_shndx field contains the escape value SHN_XINDEX will the matchingElf32_Word hold the actual section header index. Otherwise, the entry must be SHN_UNDEF (0).
SHT_LOOS –
SHT_HIOS
-
Values in this inclusive range are reserved for operating system-specific semantics.
SHT_LOSUNW –
SHT_HISUNW
-
Values in this inclusive range are reserved for Solaris OS semantics.
SHT_SUNW_dof
-
Reserved for internal use by dtrace(1M).
SHT_SUNW_cap
-
Specifies hardware and software capability requirements. See Hardware and Software Capabilities Section for details.
SHT_SUNW_SIGNATURE
- SHT_SUNW_ANNOTATE
-
The processing of an annotate section follows all of the default rules for processing a section. The only exception occurs if the annotate section is in non-allocatable memory. If the section header flag SHF_ALLOC is not set, the link-editor silently ignores any unsatisfied relocations against this section.
SHT_SUNW_DEBUGSTR,
SHT_SUNW_DEBUG
-
Identifies debugging information. Sections of this type are stripped from the object using the link-editor's -s option, or after the link-edit using strip(1).
SHT_SUNW_move
-
Identifies data to handle partially initialized symbols. See Move Section for details.
SHT_SUNW_COMDAT
-
Identifies a section that allows multiple copies of the same data to be reduced to a single copy. See COMDAT Section for details.
SHT_SUNW_syminfo
-
Identifies additional symbol information. See Syminfo Table Section for details.
SHT_SUNW_verdef
-
Identifies fine-grained versions defined by this file. See Version Definition Section for details.
SHT_SUNW_verneed
-
Identifies fine-grained dependencies required by this file. See Version Dependency Section for details.
SHT_SUNW_versym
-
Identifies a table describing the relationship of symbols to the version definitions offered by the file. See Version Symbol Section for details.
SHT_LOPROC -
SHT_HIPROC
-
Values in this inclusive range are reserved for processor-specific semantics.
SHT_SPARC_GOTDATA
-
Identifies SPARC specific data, referenced using GOT-relative addressing. That is, offsets relative to the address assigned to the symbol _GLOBAL_OFFSET_TABLE_. For 64–bit SPARC, data in this section must be bound at link-edit time to locations within {+-} 2^32 bytes of the GOT address.
SHT_AMD64_UNWIND
-
Identifies x64 specific data, containing unwind function table entries for stack unwinding.
SHT_LOUSER
-
Specifies the lower boundary of the range of indexes that are reserved for application programs.
SHT_HIUSER
-
Specifies the upper boundary of the range of indexes that are reserved for application programs. Section types betweenSHT_LOUSER and SHT_HIUSER can be used by the application without conflicting with current or future system-defined section types.
Other section-type values are reserved. As mentioned before, the section header for index 0 (SHN_UNDEF) exists, even though the index marks undefined section references. The following table shows the values.
Table 7–6 ELF Section Header Table Entry: Index 0 Name | Value | Note |
---|---|---|
sh_name | 0 | No name |
sh_type | SHT_NULL | Inactive |
sh_flags | 0 | No flags |
sh_addr | 0 | No address |
sh_offset | 0 | No file offset |
sh_size | 0 | No size |
sh_link | SHN_UNDEF | No link information |
sh_info | 0 | No auxiliary information |
sh_addralign | 0 | No alignment |
sh_entsize | 0 | No entries |
Should the number of sections or program headers exceed the ELF header data sizes, elements of section header 0 are used to define extended ELF header attributes. The following table shows the values.
Table 7–7 ELF Extended Section Header Table Entry: Index 0 Name | Value | Note |
---|---|---|
sh_name | 0 | No name |
sh_type | SHT_NULL | Inactive |
sh_flags | 0 | No flags |
sh_addr | 0 | No address |
sh_offset | 0 | No file offset |
sh_size | e_shnum | The number of entries in the section header table |
sh_link | e_shstrndx | The section header index of the entry that is associated with the section name string table |
sh_info | e_phnum | The number of entries in the program header table |
sh_addralign | 0 | No alignment |
sh_entsize | 0 | No entries |
A section header's sh_flags member holds 1-bit flags that describe the section's attributes.
Table 7–8 ELF Section Attribute Flags Name | Value |
---|---|
SHF_WRITE | 0x1 |
SHF_ALLOC | 0x2 |
SHF_EXECINSTR | 0x4 |
SHF_MERGE | 0x10 |
SHF_STRINGS | 0x20 |
SHF_INFO_LINK | 0x40 |
SHF_LINK_ORDER | 0x80 |
SHF_OS_NONCONFORMING | 0x100 |
SHF_GROUP | 0x200 |
SHF_TLS | 0x400 |
SHF_MASKOS | 0x0ff00000 |
SHF_AMD64_LARGE | 0x10000000 |
SHF_ORDERED | 0x40000000 |
SHF_EXCLUDE | 0x80000000 |
SHF_MASKPROC | 0xf0000000 |
If a flag bit is set in sh_flags, the attribute is on for the section. Otherwise, the attribute is off, or does not apply. Undefined attributes are reserved and are set to zero.
-
SHF_WRITE
-
Identifies a section that should be writable during process execution.
SHF_ALLOC
-
Identifies a section that occupies memory during process execution. Some control sections do not reside in the memory image of an object file. This attribute is off for those sections.
SHF_EXECINSTR
-
Identifies a section that contains executable machine instructions.
SHF_MERGE
-
Identifies a section containing data that can be merged to eliminate duplication. Unless the SHF_STRINGS flag is also set, the data elements in the section are of a uniform size. The size of each element is specified in the section header's sh_entsize field. If theSHF_STRINGS flag is also set, the data elements consist of null-terminated character strings. The size of each character is specified in the section header's sh_entsize field.
SHF_STRINGS
-
Identifies a section that consists of null-terminated character strings. The size of each character is specified in the section header'ssh_entsize field.
SHF_INFO_LINK
-
This section headers sh_info field holds a section header table index.
SHF_LINK_ORDER
-
This section adds special ordering requirements to the link-editor. The requirements apply if the sh_link field of this section's header references another section, the linked-to section. If this section is combined with other sections in the output file, the section appears in the same relative order with respect to those sections. Similarly the linked-to section appears with respect to sections the linked-to section is combined with.
The special sh_link values SHN_BEFORE and SHN_AFTER (see Table 7–4) imply that the sorted section is to precede or follow, respectively, all other sections in the set being ordered. Input file link-line order is preserved if multiple sections in an ordered set have one of these special values.
A typical use of this flag is to build a table that references text or data sections in address order.
In the absence of the sh_link ordering information, sections from a single input file combined within one section of the output file are contiguous. These section have the same relative ordering as the sections did in the input file. The contributions from multiple input files appear in link-line order.
SHF_OS_NONCONFORMING
-
This section requires special OS-specific processing beyond the standard linking rules to avoid incorrect behavior. If this section has either an sh_type value or contains sh_flags bits in the OS-specific ranges for those fields, and the link-editor does not recognize these values, then the object file containing this section is rejected with an error.
SHF_GROUP
-
This section is a member, perhaps the only member, of a section group. The section must be referenced by a section of typeSHT_GROUP. The SHF_GROUP flag can be set only for sections that are contained in relocatable objects. See Group Section for details.
SHF_TLS
-
This section holds thread-local storage. Each thread within a process has a distinct instance of this data. See Chapter 8, Thread-Local Storage for details.
SHF_MASKOS
-
All bits that are included in this mask are reserved for operating system-specific semantics.
SHF_AMD64_LARGE
-
The default compilation model for x64 only provides for 32–bit displacements. This displacement limits the size of sections, and eventually segments, to 2 Gbytes. This attribute flag identifies a section that can hold more than 2 Gbyte. This flag allows the linking of object files that use different code models.
An x64 object file section that does not contain the SHF_AMD64_LARGE attribute flag can be freely referenced by objects using small code models. A section that contains this flag can only be referenced by objects that use larger code models. For example, an x64 medium code model object can refer to data in sections that contain the attribute flag and sections that do not contain the attribute flag. However, an x64 small code model object can only refer to data in a section that does not contain this flag.
SHF_ORDERED
-
This section requires ordering in relation to other sections of the same type. Ordered sections are combined within the section pointed to by the sh_link entry. The sh_link entry of an ordered section can point to itself.
If the sh_info entry of the ordered section is a valid section within the same input file, the ordered section is sorted based on the relative ordering within the output file of the section pointed to by the sh_info entry.
The special sh_info values SHN_BEFORE and SHN_AFTER (see Table 7–4) imply that the sorted section is to precede or follow, respectively, all other sections in the set being ordered. Input file link-line order is preserved if multiple sections in an ordered set have one of these special values.
In the absence of the sh_info ordering information, sections from a single input file combined within one section of the output file are contiguous. These sections have the same relative ordering as the sections appear in the input file. The contributions from multiple input files appear in link-line order.
SHF_EXCLUDE
-
This section is excluded from input to the link-edit of an executable or shared object. This flag is ignored if the SHF_ALLOC flag is also set, or if relocations exist against the section.
SHF_MASKPROC
-
All bits that are included in this mask are reserved for processor-specific semantics.
Two members in the section header, sh_link and sh_info, hold special information, depending on section type.
Table 7–9 ELF sh_link and sh_info Interpretation sh_type | sh_link | sh_info |
---|---|---|
SHT_DYNAMIC | The section header index of the associated string table. | 0 |
SHT_HASH | The section header index of the associated symbol table. | 0 |
SHT_REL SHT_RELA | The section header index of the associated symbol table. | If the sh_flags member contains the SHF_INFO_LINK flag, the section header index of the section to which the relocation applies, otherwise 0. See alsoTable 7–10 and Relocation Sections. |
SHT_SYMTAB SHT_DYNSYM | The section header index of the associated string table. | One greater than the symbol table index of the last local symbol, STB_LOCAL. |
SHT_GROUP | The section header index of the associated symbol table. | The symbol table index of an entry in the associated symbol table. The name of the specified symbol table entry provides a signature for the section group. |
SHT_SYMTAB_SHNDX | The section header index of the associated symbol table. | 0 |
SHT_SUNW_move | The section header index of the associated symbol table. | 0 |
SHT_SUNW_COMDAT | 0 | 0 |
SHT_SUNW_syminfo | The section header index of the associated symbol table. | The section header index of the associated .dynamic section. |
SHT_SUNW_verdef | The section header index of the associated string table. | The number of version definitions within the section. |
SHT_SUNW_verneed | The section header index of the associated string table. | The number of version dependencies within the section. |
SHT_SUNW_versym | The section header index of the associated symbol table. | 0 |
Special Sections
Various sections hold program and control information. Sections in the following table are used by the system and have the indicated types and attributes.
Table 7–10 ELF Special Sections Name | Type | Attribute |
---|---|---|
.bss | SHT_NOBITS | SHF_ALLOC + SHF_WRITE |
.comment | SHT_PROGBITS | None |
.data, .data1 | SHT_PROGBITS | SHF_ALLOC + SHF_WRITE |
.dynamic | SHT_DYNAMIC | SHF_ALLOC + SHF_WRITE |
.dynstr | SHT_STRTAB | SHF_ALLOC |
.dynsym | SHT_DYNSYM | SHF_ALLOC |
.eh_frame_hdr | SHT_AMD64_UNWIND | SHF_ALLOC |
.eh_frame | SHT_AMD64_UNWIND | SHF_ALLOC + SHF_WRITE |
.fini | SHT_PROGBITS | SHF_ALLOC + SHF_EXECINSTR |
.finiarray | SHT_FINI_ARRAY | SHF_ALLOC + SHF_WRITE |
.got | SHT_PROGBITS | |
.hash | SHT_HASH | SHF_ALLOC |
.init | SHT_PROGBITS | SHF_ALLOC + SHF_EXECINSTR |
.initarray | SHT_INIT_ARRAY | SHF_ALLOC + SHF_WRITE |
.interp | SHT_PROGBITS | |
.note | SHT_NOTE | None |
.lbss | SHT_NOBITS | SHF_ALLOC + SHF_WRITE + SHF_AMD64_LARGE |
.ldata, .ldata1 | SHT_PROGBITS | SHF_ALLOC + SHF_WRITE + SHF_AMD64_LARGE |
.lrodata, .lrodata1 | SHT_PROGBITS | SHF_ALLOC + SHF_AMD64_LARGE |
.plt | SHT_PROGBITS | |
.preinitarray | SHT_PREINIT_ARRAY | SHF_ALLOC + SHF_WRITE |
.rela | SHT_RELA | None |
.relname | SHT_REL | |
.relaname | SHT_RELA | |
.rodata, .rodata1 | SHT_PROGBITS | SHF_ALLOC |
.shstrtab | SHT_STRTAB | None |
.strtab | SHT_STRTAB | Refer to the explanation following this table. |
.symtab | SHT_SYMTAB | |
.symtab_shndx | SHT_SYMTAB_SHNDX | |
.tbss | SHT_NOBITS | SHF_ALLOC + SHF_WRITE + SHF_TLS |
.tdata, .tdata1 | SHT_PROGBITS | SHF_ALLOC + SHF_WRITE + SHF_TLS |
.text | SHT_PROGBITS | SHF_ALLOC + SHF_EXECINSTR |
.SUNW_bss | SHT_NOBITS | SHF_ALLOC + SHF_WRITE |
.SUNW_cap | SHT_SUNW_cap | SHF_ALLOC |
.SUNW_heap | SHT_PROGBITS | SHF_ALLOC + SHF_WRITE |
.SUNW_move | SHT_SUNW_move | SHF_ALLOC |
.SUNW_reloc | SHT_REL SHT_RELA | SHF_ALLOC |
.SUNW_syminfo | SHT_SUNW_syminfo | SHF_ALLOC |
.SUNW_version | SHT_SUNW_verdef SHT_SUNW_verneed SHT_SUNW_versym | SHF_ALLOC |
-
.bss
-
Uninitialized data that contribute to the program's memory image. By definition, the system initializes the data with zeros when the program begins to run. The section occupies no file space, as indicated by the section type SHT_NOBITS.
.comment
-
Comment information, typically contributed by the components of the compilation system. This section can be manipulated by mcs(1).
.data,
.data1
-
Initialized data that contribute to the program's memory image.
.dynamic
-
Dynamic linking information. See Dynamic Section for details.
.dynstr
-
Strings needed for dynamic linking, most commonly the strings that represent the names associated with symbol table entries.
.dynsym
-
Dynamic linking symbol table. See Symbol Table Section for details.
.eh_frame_hdr,
.eh_frame
-
Call frame information used to unwind the stack.
.fini
-
Executable instructions that contribute to a single termination function for the executable or shared object containing the section. SeeInitialization and Termination Routines for details.
.finiarray
-
An array of function pointers that contribute to a single termination array for the executable or shared object containing the section. See Initialization and Termination Routines for details.
.got
-
The global offset table. See Global Offset Table (Processor-Specific) for details.
.hash
-
Symbol hash table. See Hash Table Section for details.
.init
-
Executable instructions that contribute to a single initialization function for the executable or shared object containing the section. SeeInitialization and Termination Routines for details.
.initarray
-
An array of function pointers that contributes to a single initialization array for the executable or shared object containing the section. See Initialization and Termination Routines for details.
.interp
-
The path name of a program interpreter. See Program Interpreter for details.
.lbss
-
x64 specific uninitialized data. This data is similar to .bss, but provides for a section that is larger than 2 Gbytes.
.ldata,
.ldata1
-
x64 specific initialized data. This data is similar to .data, but provides for a section that is larger than 2 Gbytes.
.lrodata,
.lrodata1
-
x64 specific read-only data. This data is similar to .rodata, but provides for a section that is larger than 2 Gbytes.
.note
-
Information in the format described in Note Section.
.plt
-
The procedure linkage table. See Procedure Linkage Table (Processor-Specific) for details.
.preinitarray
-
An array of function pointers that contribute to a single pre-initialization array for the executable or shared object containing the section. See Initialization and Termination Routines for details.
.rela
-
Relocations that do not apply to a particular section. One use of this section is for register relocations. See Register Symbols for details.
.rel
name
,
.rela
name
-
Relocation information, as Relocation Sections describes. If the file has a loadable segment that includes relocation, the sections' attributes include the SHF_ALLOC bit. Otherwise, that bit is off. Conventionally, name is supplied by the section to which the relocations apply. Thus, a relocation section for .text normally will have the name .rel.text or .rela.text.
.rodata,
.rodata1
-
Read-only data that typically contribute to a non-writable segment in the process image. See Program Header for details.
.shstrtab
-
Section names.
.strtab
-
Strings, most commonly the strings that represent the names that are associated with symbol table entries. If the file has a loadable segment that includes the symbol string table, the section's attributes include the SHF_ALLOC bit. Otherwise, that bit is turned off.
.symtab
-
Symbol table, as Symbol Table Section describes. If the file has a loadable segment that includes the symbol table, the section's attributes include the SHF_ALLOC bit. Otherwise, that bit is turned off.
.symtab_shndx
-
This section holds the special symbol table section index array, as described by .symtab. The section's attributes include theSHF_ALLOC bit if the associated symbol table section does. Otherwise, that bit is turned off.
.tbss
-
This section holds uninitialized thread-local data that contribute to the program's memory image. By definition, the system initializes the data with zeros when the data is instantiated for each new execution flow. The section occupies no file space, as indicated by the section type, SHT_NOBITS. See Chapter 8, Thread-Local Storage for details.
.tdata,
.tdata1
-
These sections hold initialized thread-local data that contribute to the program's memory image. A copy of its contents is instantiated by the system for each new execution flow. See Chapter 8, Thread-Local Storage for details.
.text
-
The text or executable instructions of a program.
.SUNW_bss
-
Partially initialized data for shared objects that contribute to the program's memory image. The data is initialized at runtime. The section occupies no file space, as indicated by the section type SHT_NOBITS.
.SUNW_cap
-
Hardware and software capability requirements. See Hardware and Software Capabilities Section for details.
.SUNW_heap
-
The heap of a dynamic executable created from dldump(3C).
.SUNW_move
-
Additional information for partially initialized data. See Move Section for details.
.SUNW_reloc
-
Relocation information, as Relocation Sections describes. This section is a concatenation of relocation sections that provides better locality of reference of the individual relocation records. Only the offset of the relocation record is meaningful, thus the sectionsh_info value is zero.
.SUNW_syminfo
-
Additional symbol table information. See Syminfo Table Section for details.
.SUNW_version
-
Versioning information. See Versioning Sections for details.
Section names with a dot (.) prefix are reserved for the system, although applications can use these sections if their existing meanings are satisfactory. Applications can use names without the prefix to avoid conflicts with system sections. The object file format enables you to define sections that are not reserved. An object file can have more than one section with the same name.
Section names that are reserved for a processor architecture are formed by placing an abbreviation of the architecture name ahead of the section name. The name should be taken from the architecture names that are used for e_machine. For example, .Foo.psect is thepsect section defined by the FOO architecture.
Existing extensions use their historical names
COMDAT Section
COMDAT sections are uniquely identified by their section name (sh_name). If the link-editor encounters multiple sections of typeSHT_SUNW_COMDAT, with the same section name, the first section is retained and the rest discarded. Any relocations that are applied to a discarded SHT_SUNW_COMDAT section are ignored. Any symbols that are defined in a discarded section are removed.
Additionally, the link-editor supports the section naming convention that is used for section reordering when the compiler is invoked with the-xF option. If a function is placed in a SHT_SUNW_COMDAT section that is named .sectname%funcname, the finalSHT_SUNW_COMDAT sections that are retained are coalesced into the section that is named .sectname. This method can be used to place SHT_SUNW_COMDAT sections into the .text, .data, or any other section as their final destination.
Group Section
Some sections occur in interrelated groups. For example, an out-of-line definition of an inline function might require additional information besides the section containing executable instructions. This additional information can be a read-only data section containing literals referenced, one or more debugging information sections, or other informational sections.
There can be internal references among group sections. However, these references make no sense if one of the sections were removed, or one of the sections were replaced by a duplicate from another object. Therefore, these groups are included, or these groups are omitted, from the linked object as a unit.
A section of type SHT_GROUP defines such a grouping of sections. The name of a symbol from one of the containing object's symbol tables provides a signature for the section group. The section header of the SHT_GROUP section specifies the identifying symbol entry. Thesh_link member contains the section header index of the symbol table section that contains the entry. The sh_info member contains the symbol table index of the identifying entry. The sh_flags member of the section header contains the value zero. The name of the section (sh_name) is not specified.
The section data of a SHT_GROUP section is an array of Elf32_Word entries. The first entry is a flag word. The remaining entries are a sequence of section header indices.
The following flag is currently defined.
Table 7–11 ELF Group Section Flag Name | Value |
---|---|
GRP_COMDAT | 0x1 |
-
GRP_COMDAT
-
GRP_COMDAT is a COMDAT group. This group can duplicate another COMDAT group in another object file, where duplication is defined as having the same group signature. In such cases, only one of the duplicate groups is retained by the link-editor. The members of the remaining groups are discarded.
The section header indices in the SHT_GROUP section, identify the sections that make up the group. These sections must have theSHF_GROUP flag set in their sh_flags section header member. If the link-editor decides to remove the section group, the link-editor removes all members of the group.
To facilitate removing a group without leaving dangling references and with only minimal processing of the symbol table, the following rules are followed.
-
References to the sections comprising a group from sections outside of the group must be made through symbol table entries withSTB_GLOBAL or STB_WEAK binding and section index SHN_UNDEF. A definition of the same symbol in the object containing the reference must have a separate symbol table entry from the reference. Sections outside of the group can not reference symbols withSTB_LOCAL binding for addresses that are contained in the group's sections, including symbols with type STT_SECTION.
-
Non-symbol references to the sections comprising a group are not allowed from outside the group. For example, you cannot use a group member's section header index in an sh_link or sh_info member.
-
A symbol table entry defined relative to one of the group's sections can be removed if the group members are discarded. This removal occurs if the symbol table entry is contained in a symbol table section that is not part of the group.
Hardware and Software Capabilities Section
A SHT_SUNW_cap section identifies the hardware and software capabilities of an object. This section contains an array of the following structures. See sys/link.h.
typedef struct { Elf32_Word c_tag; union { Elf32_Word c_val; Elf32_Addr c_ptr; } c_un; } Elf32_Cap; typedef struct { Elf64_Xword c_tag; union { Elf64_Xword c_val; Elf64_Addr c_ptr; } c_un; } Elf64_Cap;
For each object with this type, c_tag controls the interpretation of c_un.
-
c_val
-
These objects represent integer values with various interpretations.
c_ptr
-
These objects represent program virtual addresses.
The following capabilities tags exist.
Table 7–12 ELF Capability Array Tags Name | Value | c_un |
---|---|---|
CA_SUNW_NULL | 0 | Ignored |
CA_SUNW_HW_1 | 1 | c_val |
CA_SUNW_SF_1 | 2 | c_val |
-
CA_SUNW_NULL
-
Marks the end of the capabilities array.
CA_SUNW_HW_1
-
Indicates hardware capability values. The c_val element contains a value that represents the associated hardware capabilities. On SPARC platforms, hardware capabilities are defined in sys/auxv_SPARC.h. On x86 platforms, hardware capabilities are defined insys/auxv_386.h.
CA_SUNW_SF_1
-
Indicates software capability values. The c_val element contains a value that represents the associated software capabilities that are defined in sys/elf.h.
Relocatable objects can contain a capabilities section. The link-editor combines any capabilities sections from multiple input relocatable objects into a single capabilities section. The link-editor also allows capabilities to be defined at the time an object is built. See Identifying Hardware and Software Capabilities.
A dynamic object that contains a capabilities section that contains hardware capabilities information, has a PT_SUNWCAP program header associated to the section. This program header allows the runtime linker to validate the object against the hardware capabilities that are available to the process.
Dynamic objects that exploit different hardware capabilities can provide a flexible runtime environment using filters. See Hardware Capability Specific Shared Objects.
Hash Table Section
A hash table consists of Elf32_Word or Elf64_Word objects that provide for symbol table access. The SHT_HASH section provides this hash table. The symbol table to which the hashing is associated is specified in the sh_link entry of the hash table's section header. Labels are used in the following figure to help explain the hash table organization, but these labels are not part of the specification.
Figure 7–4 Symbol Hash Table
![ELF hash table information example. ELF hash table information example.](https://i-blog.csdnimg.cn/blog_migrate/620a77636278f51c72ba42b69a48665d.gif)
The bucket array contains nbucket entries, and the chain array contains nchain entries. Indexes start at 0. Both bucket andchain hold symbol table indexes. Chain table entries parallel the symbol table. The number of symbol table entries should equalnchain, so symbol table indexes also select chain table entries.
A hashing function that accepts a symbol name, returns a value to compute a bucket index. Consequently, if the hashing function returns the value x for some name, bucket [x% nbucket] gives an index y. This index is an index into both the symbol table and the chain table. If the symbol table entry is not the name desired, chain[y] gives the next symbol table entry with the same hash value.
The chain links can be followed until the selected symbol table entry holds the desired name, or the chain entry contains the valueSTN_UNDEF.
The hash function is as follows.
unsigned long elf_Hash(const unsigned char *name) { unsigned long h = 0, g; while (*name) { h = (h << 4) + *name++; if (g = h & 0xf0000000) h ^= g >> 24; h &= ~g; } return h; }
Move Section
Typically, within ELF files, initialized data variables are maintained within the object file. If a data variable is very large, and contains only a small number of initialized (nonzero) elements, the entire variable is still maintained in the object file.
Objects that contain large partially initialized data variables, such as FORTRAN COMMON blocks, can result in a significant disk space overhead. The SHT_SUNW_move section provides a mechanism of compressing these data variables. This compression reduces the disk size of the associated object.
The SHT_SUNW_move section contains multiple entries of the type ELF32_Move or Elf64_Move. These entries allow data variables to be defined as tentative items (.bss). These items occupy no space in the object file, but contribute to the object's memory image at runtime. The move records establish how the memory image is initialized with data to construct the complete data variable.
ELF32_Move and Elf64_Move entries are defined as follows.
typedef struct { Elf32_Lword m_value; Elf32_Word m_info; Elf32_Word m_poffset; Elf32_Half m_repeat; Elf32_Half m_stride; } Elf32_Move; #define ELF32_M_SYM(info) ((info)>>8) #define ELF32_M_SIZE(info) ((unsigned char)(info)) #define ELF32_M_INFO(sym, size) (((sym)<<8)+(unsigned char)(size)) typedef struct { Elf64_Lword m_value; Elf64_Xword m_info; Elf64_Xword m_poffset; Elf64_Half m_repeat; Elf64_Half m_stride; } Elf64_Move; #define ELF64_M_SYM(info) ((info)>>8) #define ELF64_M_SIZE(info) ((unsigned char)(info)) #define ELF64_M_INFO(sym, size) (((sym)<<8)+(unsigned char)(size))
The elements of these structures are as follows.
-
m_value
-
The initialization value, which is the value that is moved into the memory image.
m_info
-
The symbol table index, with respect to which the initialization is applied, together with the size, in bytes, of the offset being initialized. The lower 8 bits of the member define the size, which can be 1, 2, 4 or 8. The upper bytes define the symbol index.
m_poffset
-
The offset relative to the associated symbol to which the initialization is applied.
m_repeat
-
A repetition count.
m_stride
-
The stride count. This value indicates the number of units that should be skipped when performing a repetitive initialization. A unit is the size of an initialization object as defined by m_info. An m_stride value of zero indicates that the initialization be performed contiguously for units.
The following data definition would traditionally consume 0x8000 bytes within an object file.
typedef struct { int one; char two; } Data; Data move[0x1000] = { {0, 0}, {1, '1'}, {0, 0}, {0xf, 'F'}, {0xf, 'F'}, {0, 0}, {0xe, 'E'}, {0, 0}, {0xe, 'E'} };
A SHT_SUNW_move section can be used to describe this data. The data item is defined within the .bss section. The non-zero elements of the data item are initialized with the appropriate move entries.
$ elfdump -s data | fgrep move [17] 0x00020868 0x00008000 OBJT GLOB 0 .bss move $ elfdump -m data Move Section: .SUNW_move symndx offset size repeat stride value with respect to [17] 8 4 1 1 0x000000000000000001 move [17] 12 4 1 1 0x000000000031000000 move [17] 24 4 2 1 0x00000000000000000f move [17] 28 4 2 1 0x000000000046000000 move [17] 48 4 1 1 0x00000000000000000e move [17] 52 4 1 1 0x000000000045000000 move [17] 64 4 1 1 0x00000000000000000e move [17] 68 4 1 1 0x000000000045000000 move |
Move sections that are supplied from relocatable objects are concatenated and output in the object being created by the link-editor. However, the following conditions cause the link-editor to process the move entries. This processing expands the move entry contents into a traditional data item.
-
The output file is a static executable.
-
The size of the move entries is greater than the size of the symbol into which the move data would be expanded.
Note Section
A vendor or system engineer might need to mark an object file with special information that other programs can check for conformance or compatibility. Sections of type SHT_NOTE and program header elements of type PT_NOTE can be used for this purpose.
The note information in sections and program header elements holds any number of entries, as shown in the following figure. For 64–bit objects and 32–bit objects, each entry is an array of 4-byte words in the format of the target processor. Labels are shown in Figure 7–6 to help explain note information organization, but are not part of the specification.
Figure 7–5 Note Information
![ELF note section information. ELF note section information.](https://i-blog.csdnimg.cn/blog_migrate/11e8fca9352260c78133d7b42f8a9d56.gif)
-
namesz and
name
-
The first namesz bytes in name contain a null-terminated character representation of the entry's owner or originator. No formal mechanism exists for avoiding name conflicts. By convention, vendors use their own name, such as “XYZ Computer Company,” as the identifier. If no name is present, namesz contains the value zero. Padding is present, if necessary, to ensure 4-byte alignment for the descriptor. Such padding is not included in namesz.
descsz and
desc
-
The first descsz bytes in desc hold the note descriptor. If no descriptor is present, descsz contains the value zero. Padding is present, if necessary, to ensure 4-byte alignment for the next note entry. Such padding is not included in descsz.
type
-
Provides the interpretation of the descriptor. Each originator controls its own types. Multiple interpretations of a single type value can exist. A program must recognize both the name and the type to understand a descriptor. Types currently must be nonnegative.
The note segment that is shown in the following figure holds two entries.
Figure 7–6 Example Note Segment
![ELF note section example. ELF note section example.](https://i-blog.csdnimg.cn/blog_migrate/4f6e64bf4cc96dd4d6cda9f6725f299c.gif)
Note –
The system reserves note information with no name (namesz == 0) and with a zero-length name (name[0] == '\0'), but currently defines no types. All other names must have at least one non-null character.
Relocation Sections
Relocation is the process of connecting symbolic references with symbolic definitions. For example, when a program calls a function, the associated call instruction must transfer control to the proper destination address at execution. Relocatable files must have information that describes how to modify their section contents. This information allows executable and shared object files to hold the right information for a process's program image. Relocation entries are these data.
Relocation entries can have the following structure. See sys/elf.h.
typedef struct { Elf32_Addr r_offset; Elf32_Word r_info; } Elf32_Rel; typedef struct { Elf32_Addr r_offset; Elf32_Word r_info; Elf32_Sword r_addend; } Elf32_Rela; typedef struct { Elf64_Addr r_offset; Elf64_Xword r_info; } Elf64_Rel; typedef struct { Elf64_Addr r_offset; Elf64_Xword r_info; Elf64_Sxword r_addend; } Elf64_Rela;
-
r_offset
-
This member gives the location at which to apply the relocation action. Different object files have slightly different interpretations for this member.
For a relocatable file, the value indicates a section offset. The relocation section describes how to modify another section in the file. Relocation offsets designate a storage unit within the second section.
For an executable or shared object, the value indicates the virtual address of the storage unit affected by the relocation. This information makes the relocation entries more useful for the runtime linker.
Although the interpretation of the member changes for different object files to allow efficient access by the relevant programs, the meanings of the relocation types stay the same.
r_info
-
This member gives both the symbol table index, with respect to which the relocation must be made, and the type of relocation to apply. For example, a call instruction's relocation entry holds the symbol table index of the function being called. If the index isSTN_UNDEF, the undefined symbol index, the relocation uses zero as the symbol value.
Relocation types are processor-specific. A relocation entry's relocation type or symbol table index is the result of applyingELF32_R_TYPE or ELF32_R_SYM, respectively, to the entry's r_info member.
#define ELF32_R_SYM(info) ((info)>>8) #define ELF32_R_TYPE(info) ((unsigned char)(info)) #define ELF32_R_INFO(sym, type) (((sym)<<8)+(unsigned char)(type)) #define ELF64_R_SYM(info) ((info)>>32) #define ELF64_R_TYPE(info) ((Elf64_Word)(info)) #define ELF64_R_INFO(sym, type) (((Elf64_Xword)(sym)<<32)+ \ (Elf64_Xword)(type))
For 64–bit SPARC Elf64_Rela structures, the r_info field is further broken down into an 8–bit type identifier and a 24–bit type dependent data field. For the existing relocation types, the data field is zero. New relocation types, however, might make use of the data bits.
#define ELF64_R_TYPE_DATA(info) (((Elf64_Xword)(info)<<32)>>40) #define ELF64_R_TYPE_ID(info) (((Elf64_Xword)(info)<<56)>>56) #define ELF64_R_TYPE_INFO(data, type) (((Elf64_Xword)(data)<<8)+ \ (Elf64_Xword)(type))
r_addend
-
This member specifies a constant addend used to compute the value to be stored into the relocatable field.
Rela entries contain an explicit addend. Entries of type Rel store an implicit addend in the location to be modified. 32–bit SPARC use only Elf32_Rela relocation enteries. 64–bit SPARC and 64–bit x86 use only Elf64_Rela relocation entries. Thus, the r_addendmember serves as the relocation addend. x86 uses only Elf32_Rel relocation entries. The field to be relocated holds the addend. In all cases, the addend and the computed result use the same byte order.
A relocation section can reference two other sections: a symbol table, identified by the sh_link section header entry, and a section to modify, identified by the sh_info section header entry. Sections specifies these relationships. A sh_info entry is required when a relocation section exists in a relocatable object, but is optional for executables and shared objects. The relocation offset is sufficient to perform the relocation.
Relocation Types (Processor-Specific)
Relocation entries describe how to alter instruction and data fields in the following figures. Bit numbers appear in the lower box corners.
On the SPARC platform, relocation entries apply to bytes (byte8), half-words (half16), or words.
![32–bit relocation entries. 32–bit relocation entries.](https://i-blog.csdnimg.cn/blog_migrate/51866e3be3bfe5dc17f99977c5bd2eed.gif)
On 64–bit SPARC and x64, relocations also apply to extended-words (xword64).
![64–bit relocation entries. 64–bit relocation entries.](https://i-blog.csdnimg.cn/blog_migrate/3ff96311990976dabff38ea6f712cccb.gif)
On x86, relocation entries apply to words (word32).
![x86 relocation entry. x86 relocation entry.](https://i-blog.csdnimg.cn/blog_migrate/c26ab8390d859f738bed845d2d5c30af.gif)
word32 specifies a 32–bit field occupying 4 bytes with an arbitrary byte alignment. These values use the same byte order as other word values in the x86 architecture.
![x86 relocation entry. x86 relocation entry.](https://i-blog.csdnimg.cn/blog_migrate/a8f0986c4828178868b05ae93a193bc2.gif)
In all cases, the r_offset value designates the offset or virtual address of the first byte of the affected storage unit. The relocation type specifies which bits to change and how to calculate their values.
Calculations for the following relocation types assume the actions are transforming a relocatable file into either an executable or a shared object file. Conceptually, the link-editor merges one or more relocatable files to form the output. The link-editor first decides how to combine and locate the input files. The link-editor then updates the symbol values and performs the relocation. Relocations applied to executable or shared object files are similar and accomplish the same result. Descriptions in the tables in this section use the following notation.
-
A
-
The addend used to compute the value of the relocatable field.
B
-
The base address at which a shared object is loaded into memory during execution. Generally, a shared object file is built with a base virtual address of 0. However, the execution address of the shared object is different. See Program Header.
G
-
The offset into the global offset table at which the address of the relocation entry's symbol resides during execution. See Global Offset Table (Processor-Specific).
GOT
-
The address of the global offset table. See Global Offset Table (Processor-Specific).
L
-
The section offset or address of the procedure linkage table entry for a symbol. See Procedure Linkage Table (Processor-Specific).
P
-
The section offset or address of the storage unit being relocated, computed using r_offset.
S
-
The value of the symbol whose index resides in the relocation entry.
Z
-
The size of the symbol whose index resides in the relocation entry.
SPARC: Relocation Types
Field names in the following table tell whether the relocation type checks for overflow. A calculated relocation value can be larger than the intended field, and a relocation type can verify (V) the value fits or truncate (T) the result. As an example, V-simm13 means that the computed value can not have significant, nonzero bits outside the simm13 field.
Table 7–13 SPARC: ELF Relocation Types Name | Value | Field | Calculation |
---|---|---|---|
R_SPARC_NONE | 0 | None | None |
R_SPARC_8 | 1 | V-byte8 | S + A |
R_SPARC_16 | 2 | V-half16 | S + A |
R_SPARC_32 | 3 | V-word32 | S + A |
R_SPARC_DISP8 | 4 | V-byte8 | S + A - P |
R_SPARC_DISP16 | 5 | V-half16 | S + A - P |
R_SPARC_DISP32 | 6 | V-disp32 | S + A - P |
R_SPARC_WDISP30 | 7 | V-disp30 | (S + A - P) >> 2 |
R_SPARC_WDISP22 | 8 | V-disp22 | (S + A - P) >> 2 |
R_SPARC_HI22 | 9 | T-imm22 | (S + A) >> 10 |
R_SPARC_22 | 10 | V-imm22 | S + A |
R_SPARC_13 | 11 | V-simm13 | S + A |
R_SPARC_LO10 | 12 | T-simm13 | (S + A) & 0x3ff |
R_SPARC_GOT10 | 13 | T-simm13 | G & 0x3ff |
R_SPARC_GOT13 | 14 | V-simm13 | G |
R_SPARC_GOT22 | 15 | T-simm22 | G >> 10 |
R_SPARC_PC10 | 16 | T-simm13 | (S + A - P) & 0x3ff |
R_SPARC_PC22 | 17 | V-disp22 | (S + A - P) >> 10 |
R_SPARC_WPLT30 | 18 | V-disp30 | (L + A - P) >> 2 |
R_SPARC_COPY | 19 | None | Refer to the explanation following this table. |
R_SPARC_GLOB_DAT | 20 | V-word32 | S + A |
R_SPARC_JMP_SLOT | 21 | None | Refer to the explanation following this table. |
R_SPARC_RELATIVE | 22 | V-word32 | B + A |
R_SPARC_UA32 | 23 | V-word32 | S + A |
R_SPARC_PLT32 | 24 | V-word32 | L + A |
R_SPARC_HIPLT22 | 25 | T-imm22 | (L + A) >> 10 |
R_SPARC_LOPLT10 | 26 | T-simm13 | (L + A) & 0x3ff |
R_SPARC_PCPLT32 | 27 | V-word32 | L + A - P |
R_SPARC_PCPLT22 | 28 | V-disp22 | (L + A - P) >> 10 |
R_SPARC_PCPLT10 | 29 | V-simm13 | (L + A - P) & 0x3ff |
R_SPARC_10 | 30 | V-simm10 | S + A |
R_SPARC_11 | 31 | V-simm11 | S + A |
R_SPARC_HH22 | 34 | V-imm22 | (S + A) >> 42 |
R_SPARC_HM10 | 35 | T-simm13 | ((S + A) >> 32) & 0x3ff |
R_SPARC_LM22 | 36 | T-imm22 | (S + A) >> 10 |
R_SPARC_PC_HH22 | 37 | V-imm22 | (S + A - P) >> 42 |
R_SPARC_PC_HM10 | 38 | T-simm13 | ((S + A - P) >> 32) & 0x3ff |
R_SPARC_PC_LM22 | 39 | T-imm22 | (S + A - P) >> 10 |
R_SPARC_WDISP16 | 40 | V-d2/disp14 | (S + A - P) >> 2 |
R_SPARC_WDISP19 | 41 | V-disp19 | (S + A - P) >> 2 |
R_SPARC_7 | 43 | V-imm7 | S + A |
R_SPARC_5 | 44 | V-imm5 | S + A |
R_SPARC_6 | 45 | V-imm6 | S + A |
R_SPARC_HIX22 | 48 | V-imm22 | ((S + A) ^ 0xffffffffffffffff) >> 10 |
R_SPARC_LOX10 | 49 | T-simm13 | ((S + A) & 0x3ff) | 0x1c00 |
R_SPARC_H44 | 50 | V-imm22 | (S + A) >> 22 |
R_SPARC_M44 | 51 | T-imm10 | ((S + A) >> 12) & 0x3ff |
R_SPARC_L44 | 52 | T-imm13 | (S + A) & 0xfff |
R_SPARC_REGISTER | 53 | V-word32 | S + A |
R_SPARC_UA16 | 55 | V-half16 | S + A |
R_SPARC_GOTDATA_HIX22 | 80 | T-imm22 | ((S + A - GOT) >> 10) ^ ((S + A - GOT) >> 31) |
R_SPARC_GOTDATA_LOX10 | 81 | T-imm13 | ((S + A - GOT) & 0x3ff) | (((S + A - GOT) >> 31) & 0x1c00) |
R_SPARC_GOTDATA_OP_HIX22 | 82 | T-imm22 | (G >> 10) ^ (G >> 31) |
R_SPARC_GOTDATA_OP_LOX10 | 83 | T-imm13 | (G & 0x3ff) | ((G >> 31) & 0x1c00) |
R_SPARC_GOTDATA_OP | 84 | Word32 | Refer to the explanation following this table. |
Note –
Additional relocations are available for thread-local storage references. These relocations are covered in Chapter 8, Thread-Local Storage.
Some relocation types have semantics beyond simple calculation.
-
R_SPARC_GOT10
-
Resembles R_SPARC_LO10, except that the relocation refers to the address of the symbol's GOT entry. Additionally,R_SPARC_GOT10 instructs the link-editor to create a global offset table.
R_SPARC_GOT13
-
Resembles R_SPARC_13, except that the relocation refers to the address of the symbol's GOT entry. Additionally,R_SPARC_GOT13 instructs the link-editor to create a global offset table.
R_SPARC_GOT22
-
Resembles R_SPARC_22, except that the relocation refers to the address of the symbol's GOT entry. Additionally,R_SPARC_GOT22 instructs the link-editor to create a global offset table.
R_SPARC_WPLT30
-
Resembles R_SPARC_WDISP30, except that the relocation refers to the address of the symbol's procedure linkage table entry. Additionally, R_SPARC_WPLT30 instructs the link-editor to create a procedure linkage table.
R_SPARC_COPY
-
Created by the link-editor for dynamic executables to preserve a read-only text segment. The relocation offset member refers to a location in a writable segment. The symbol table index specifies a symbol that should exist both in the current object file and in a shared object. During execution, the runtime linker copies data associated with the shared object's symbol to the location specified by the offset. See Copy Relocations.
R_SPARC_GLOB_DAT
-
Resembles R_SPARC_32, except that the relocation sets a GOT entry to the address of the specified symbol. The special relocation type enables you to determine the correspondence between symbols and GOT entries.
R_SPARC_JMP_SLOT
-
Created by the link-editor for dynamic objects to provide lazy binding. The relocation offset member gives the location of a procedure linkage table entry. The runtime linker modifies the procedure linkage table entry to transfer control to the designated symbol address.
R_SPARC_RELATIVE
-
Created by the link-editor for dynamic objects. The relocation offset member gives the location within a shared object that contains a value representing a relative address. The runtime linker computes the corresponding virtual address by adding the virtual address at which the shared object is loaded to the relative address. Relocation entries for this type must specify a value of zero for the symbol table index.
R_SPARC_UA32
-
Resembles R_SPARC_32, except that the relocation refers to an unaligned word. The word to be relocated must be treated as four separate bytes with arbitrary alignment, not as a word aligned according to the architecture requirements.
R_SPARC_LM22
-
Resembles R_SPARC_HI22, except that the relocation truncates rather than validates.
R_SPARC_PC_LM22
-
Resembles R_SPARC_PC22, except that the relocation truncates rather than validates.
R_SPARC_HIX22
-
Used with R_SPARC_LOX10 for executables that are confined to the uppermost 4 gigabytes of the 64–bit address space. Similar toR_SPARC_HI22, but supplies ones complement of linked value.
R_SPARC_LOX10
-
Used with R_SPARC_HIX22. Similar to R_SPARC_LO10, but always sets bits 10 through 12 of the linked value.
R_SPARC_L44
-
Used with the R_SPARC_H44 and R_SPARC_M44 relocation types to generate a 44-bit absolute addressing model.
R_SPARC_REGISTER
-
Used to initialize a register symbol. The relocation offset member contains the register number to be initialized. A corresponding register symbol must exist for this register. The symbol must be of type SHN_ABS.
R_SPARC_GOTDATA_OP_HIX22,
R_SPARC_GOTDATA_OP_LOX10, and
R_SPARC_GOTDATA_OP
-
These relocations provide for code transformations.
64-bit SPARC: Relocation Types
The following notation, used in relocation calculation, is unique to 64–bit SPARC.
-
O
-
The secondary addend used to compute the value of the relocation field. This addend is extracted from the r_info field by applying the ELF64_R_TYPE_DATA macro.
The relocations that are listed in the following table extend, or alter, the relocations defined for 32–bit SPARC. See SPARC: Relocation Types.
Table 7–14 64-bit SPARC: ELF Relocation Types Name | Value | Field | Calculation |
---|---|---|---|
R_SPARC_HI22 | 9 | V-imm22 | (S + A) >> 10 |
R_SPARC_GLOB_DAT | 20 | V-xword64 | S + A |
R_SPARC_RELATIVE | 22 | V-xword64 | B + A |
R_SPARC_64 | 32 | V-xword64 | S + A |
R_SPARC_OLO10 | 33 | V-simm13 | ((S + A) & 0x3ff) + O |
R_SPARC_DISP64 | 46 | V-xword64 | S + A - P |
R_SPARC_PLT64 | 47 | V-xword64 | L + A |
R_SPARC_REGISTER | 53 | V-xword64 | S + A |
R_SPARC_UA64 | 54 | V-xword64 | S + A |
R_SPARC_H34 | 85 | V-imm22 | (S + A) >> 12 |
The following relocation type has semantics beyond simple calculation.
-
R_SPARC_OLO10
-
Resembles R_SPARC_LO10, except that an extra offset is added to make full use of the 13-bit signed immediate field.
32-bit x86: Relocation Types
The relocations that are listed in the following table are defined for 32–bit x86.
Table 7–15 32-bit x86: ELF Relocation Types Name | Value | Field | Calculation |
---|---|---|---|
R_386_NONE | 0 | None | None |
R_386_32 | 1 | word32 | S + A |
R_386_PC32 | 2 | word32 | S + A - P |
R_386_GOT32 | 3 | word32 | G + A |
R_386_PLT32 | 4 | word32 | L + A - P |
R_386_COPY | 5 | None | Refer to the explanation following this table. |
R_386_GLOB_DAT | 6 | word32 | S |
R_386_JMP_SLOT | 7 | word32 | S |
R_386_RELATIVE | 8 | word32 | B + A |
R_386_GOTOFF | 9 | word32 | S + A - GOT |
R_386_GOTPC | 10 | word32 | GOT + A - P |
R_386_32PLT | 11 | word32 | L + A |
R_386_16 | 20 | word16 | S + A |
R_386_PC16 | 21 | word16 | S + A - P |
R_386_8 | 22 | word8 | S + A |
R_386_PC8 | 23 | word8 | S + A - P |
Note –
Additional relocations are available for thread-local storage references. These relocations are covered in Chapter 8, Thread-Local Storage.
Some relocation types have semantics beyond simple calculation.
-
R_386_GOT32
-
Computes the distance from the base of the GOT to the symbol's GOT entry. The relocation also instructs the link-editor to create a global offset table.
R_386_PLT32
-
Computes the address of the symbol's procedure linkage table entry and instructs the link-editor to create a procedure linkage table.
R_386_COPY
-
Created by the link-editor for dynamic executables to preserve a read-only text segment. The relocation offset member refers to a location in a writable segment. The symbol table index specifies a symbol that should exist both in the current object file and in a shared object. During execution, the runtime linker copies data associated with the shared object's symbol to the location specified by the offset. See Copy Relocations.
R_386_GLOB_DAT
-
Used to set a GOT entry to the address of the specified symbol. The special relocation type enable you to determine the correspondence between symbols and GOT entries.
R_386_JMP_SLOT
-
Created by the link-editor for dynamic objects to provide lazy binding. The relocation offset member gives the location of a procedure linkage table entry. The runtime linker modifies the procedure linkage table entry to transfer control to the designated symbol address.
R_386_RELATIVE
-
Created by the link-editor for dynamic objects. The relocation offset member gives the location within a shared object that contains a value representing a relative address. The runtime linker computes the corresponding virtual address by adding the virtual address at which the shared object is loaded to the relative address. Relocation entries for this type must specify a value of zero for the symbol table index.
R_386_GOTOFF
-
Computes the difference between a symbol's value and the address of the GOT. The relocation also instructs the link-editor to create the global offset table.
R_386_GOTPC
-
Resembles R_386_PC32, except that it uses the address of the GOT in its calculation. The symbol referenced in this relocation normally is _GLOBAL_OFFSET_TABLE_, which also instructs the link-editor to create the global offset table.
x64: Relocation Types
The relocations that are listed in the following table are defined for x64.
Table 7–16 x64: ELF Relocation Types Name | Value | Field | Calculation |
---|---|---|---|
R_AMD64_NONE | 0 | None | None |
R_AMD64_64 | 1 | word64 | S + A |
R_AMD64_PC32 | 2 | word32 | S + A - P |
R_AMD64_GOT32 | 3 | word32 | G + A |
R_AMD64_PLT32 | 4 | word32 | L + A - P |
R_AMD64_COPY | 5 | None | Refer to the explanation following this table. |
R_AMD64_GLOB_DAT | 6 | word64 | S |
R_AMD64_JUMP_SLOT | 7 | word64 | S |
R_AMD64_RELATIVE | 8 | word64 | B + A |
R_AMD64_GOTPCREL | 9 | word32 | G + GOT + A - P |
R_AMD64_32 | 10 | word32 | S + A |
R_AMD64_32S | 11 | word32 | S + A |
R_AMD64_16 | 12 | word16 | S + A |
R_AMD64_PC16 | 13 | word16 | S + A - P |
R_AMD64_8 | 14 | word8 | S + A |
R_AMD64_PC8 | 15 | word8 | S + A - P |
R_AMD64_PC64 | 24 | word64 | S + A - P |
R_AMD64_GOTOFF64 | 25 | word64 | S + A - GOT |
R_AMD64_GOTPC32 | 26 | word32 | GOT + A + P |
Note –
Additional relocations are available for thread-local storage references. These relocations are covered in Chapter 8, Thread-Local Storage.
The special semantics for most of these relocation types are identical to those used for x86. Some relocation types have semantics beyond simple calculation.
-
R_AMD64_GOTPCREL
-
This relocations has different semantics from the R_AMD64_GOT32 or equivalent R_386_GOTPC relocation. The x64 architecture provides an addressing mode that is relative to the instruction pointer. Therefore, an address can be loaded from the GOT using a single instruction.
The calculation for the R_AMD64_GOTPCREL relocation provides the difference between the location in the GOT where the symbol's address is given, and the location where the relocation is applied.
R_AMD64_32
-
The computed value is truncated to 32–bits. The link-editor verifies that the generated value for the relocation zero-extends to the original 64–bit value.
R_AMD64_32S
-
The computed value is truncated to 32–bits. The link-editor verifies that the generated value for the relocation sign-extends to the original 64–bit value.
R_AMD64_8,
R_AMD64_16,
R_AMD64_PC16, and
R_AMD64_PC8
-
These relocations are not conformant to the x64 ABI, but are added here for documentation purposes. The R_AMD64_8 relocation truncates the computed value to 8-bits. The R_AMD64_16 relocation truncates the computed value to 16-bits.
String Table Section
String table sections hold null-terminated character sequences, commonly called strings. The object file uses these strings to represent symbol and section names. You reference a string as an index into the string table section.
The first byte, which is index zero, holds a null character. Likewise, a string table's last byte holds a null character, ensuring null termination for all strings. A string whose index is zero specifies either no name or a null name, depending on the context.
An empty string table section is permitted. The section header's sh_size member contains zero. Nonzero indexes are invalid for an empty string table.
A section header's sh_name member holds an index into the section header string table section. The section header string table is designated by the e_shstrndx member of the ELF header. The following figure shows a string table with 25 bytes and the strings associated with various indexes.
Figure 7–7 ELF String Table
![ELF string table example. ELF string table example.](https://i-blog.csdnimg.cn/blog_migrate/33fd881f01ac8446446467f747cc33fe.gif)
The following table shows the strings of the string table that are shown in the preceding figure.
Table 7–17 ELF String Table Indexes Index | String |
---|---|
0 | None |
1 | name |
7 | Variable |
11 | able |
16 | able |
24 | null string |
As the example shows, a string table index can refer to any byte in the section. A string can appear more than once. References to substrings can exist. A single string can be referenced multiple times. Unreferenced strings also are allowed.
Symbol Table Section
An object file's symbol table holds information needed to locate and relocate a program's symbolic definitions and symbolic references. A symbol table index is a subscript into this array. Index 0 both designates the first entry in the table and serves as the undefined symbol index. See Table 7–21.
A symbol table entry has the following format. See sys/elf.h.
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; typedef struct { Elf64_Word st_name; unsigned char st_info; unsigned char st_other; Elf64_Half st_shndx; Elf64_Addr st_value; Elf64_Xword st_size; } Elf64_Sym;
-
st_name
-
An index into the object file's symbol string table, which holds the character representations of the symbol names. If the value is nonzero, the value represents a string table index that gives the symbol name. Otherwise, the symbol table entry has no name.
st_value
-
The value of the associated symbol. The value can be an absolute value or an address, depending on the context. See Symbol Values.
st_size
-
Many symbols have associated sizes. For example, a data object's size is the number of bytes that are contained in the object. This member holds the value zero if the symbol has no size or an unknown size.
st_info
-
The symbol's type and binding attributes. A list of the values and meanings appears in Table 7–18. The following code shows how to manipulate the values. See sys/elf.h.
#define ELF32_ST_BIND(info) ((info) >> 4) #define ELF32_ST_TYPE(info) ((info) & 0xf) #define ELF32_ST_INFO(bind, type) (((bind)<<4)+((type)&0xf)) #define ELF64_ST_BIND(info) ((info) >> 4) #define ELF64_ST_TYPE(info) ((info) & 0xf) #define ELF64_ST_INFO(bind, type) (((bind)<<4)+((type)&0xf))
st_other
-
A symbol's visibility. A list of the values and meanings appears in Table 7–20. The following code shows how to manipulate the values for both 32–bit objects and 64–bit objects. Other bits are set to zero, and have no defined meaning.
#define ELF32_ST_VISIBILITY(o) ((o)&0x3) #define ELF64_ST_VISIBILITY(o) ((o)&0x3)
st_shndx
-
Every symbol table entry is defined in relation to some section. This member holds the relevant section header table index. Some section indexes indicate special meanings. See Table 7–4.
If this member contains SHN_XINDEX, then the actual section header index is too large to fit in this field. The actual value is contained in the associated section of type SHT_SYMTAB_SHNDX.
A symbol's binding, determined from its st_info field, determines the linkage visibility and behavior.
Table 7–18 ELF Symbol Binding, ELF32_ST_BIND and ELF64_ST_BIND Name | Value |
---|---|
STB_LOCAL | 0 |
STB_GLOBAL | 1 |
STB_WEAK | 2 |
STB_LOOS | 10 |
STB_HIOS | 12 |
STB_LOPROC | 13 |
STB_HIPROC | 15 |
-
STB_LOCAL
-
Local symbol. These symbols are not visible outside the object file containing their definition. Local symbols of the same name can exist in multiple files without interfering with each other.
STB_GLOBAL
-
Global symbols. These symbols are visible to all object files being combined. One file's definition of a global symbol satisfies another file's undefined reference to the same global symbol.
STB_WEAK
-
Weak symbols. These symbols resemble global symbols, but their definitions have lower precedence.
STB_LOOS -
STB_HIOS
-
Values in this inclusive range are reserved for operating system-specific semantics.
STB_LOPROC -
STB_HIPROC
-
Values in this inclusive range are reserved for processor-specific semantics.
Global symbols and weak symbols differ in two major ways.
-
When the link-editor combines several relocatable object files, multiple definitions of STB_GLOBAL symbols with the same name are not allowed. However, if a defined global symbol exists, the appearance of a weak symbol with the same name does not cause an error. The link-editor honors the global definition and ignores the weak definitions.
Similarly, if a common symbol exists, the appearance of a weak symbol with the same name does not cause an error. The link-editor uses the common definition and ignores the weak definition. A common symbol has the st_shndx field holding SHN_COMMON. SeeSymbol Resolution.
-
When the link-editor searches archive libraries, archive members that contain definitions of undefined or tentative global symbols are extracted. The member's definition can be either a global or a weak symbol.
The link-editor, by default, does not extract archive members to resolve undefined weak symbols. Unresolved weak symbols have a zero value. The use of -z weakextract overrides this default behavior. This options enables weak references to cause the extraction of archive members.
Note –
Weak symbols are intended primarily for use in system software. Their use in application programs is discouraged.
In each symbol table, all symbols with STB_LOCAL binding precede the weak symbols and global symbols. As Sections describes, a symbol table section's sh_info section header member holds the symbol table index for the first non-local symbol.
A symbol's type, as determined from its st_info field, provides a general classification for the associated entity.
Table 7–19 ELF Symbol Types, ELF32_ST_TYPE and ELF64_ST_TYPE Name | Value |
---|---|
STT_NOTYPE | 0 |
STT_OBJECT | 1 |
STT_FUNC | 2 |
STT_SECTION | 3 |
STT_FILE | 4 |
STT_COMMON | 5 |
STT_TLS | 6 |
STT_LOOS | 10 |
STT_HIOS | 12 |
STT_LOPROC | 13 |
STT_SPARC_REGISTER | 13 |
STT_HIPROC | 15 |
-
STT_NOTYPE
-
The symbol type is not specified.
STT_OBJECT
-
This symbol is associated with a data object, such as a variable, an array, and so forth.
STT_FUNC
-
This symbol is associated with a function or other executable code.
STT_SECTION
-
This symbol is associated with a section. Symbol table entries of this type exist primarily for relocation and normally haveSTB_LOCAL binding.
STT_FILE
-
Conventionally, the symbol's name gives the name of the source file that is associated with the object file. A file symbol hasSTB_LOCAL binding and a section index of SHN_ABS. This symbol, if present, precedes the other STB_LOCAL symbols for the file.
Symbol index 1 of the SHT_SYMTAB is an STT_FILE symbol representing the object file. Conventionally, this symbol is followed by the files STT_SECTION symbols. These section symbols are then followed by any global symbols that have been reduced to locals.
STT_COMMON
-
This symbol labels an uninitialized common block. This symbol is treated exactly the same as STT_OBJECT.
STT_TLS
-
The symbol specifies a thread-local storage entity. When defined, this symbol gives the assigned offset for the symbol, not the actual address.
Thread-local storage relocations can only reference symbols with type STT_TLS. A reference to a symbol of type STT_TLS from an allocatable section, can only be achieved by using special thread-local storage relocations. See Chapter 8, Thread-Local Storagefor details. A reference to a symbol of type STT_TLS from a non-allocatable section does not have this restriction.
STT_LOOS -
STT_HIOS
-
Values in this inclusive range are reserved for operating system-specific semantics.
STT_LOPROC -
STT_HIPROC
-
Values in this inclusive range are reserved for processor-specific semantics.
A symbol's visibility is determined from its st_other field. This visibility can be specified in a relocatable object. This visibility defines how that symbol can be accessed once the symbol has become part of an executable or shared object.
Table 7–20 ELF Symbol Visibility Name | Value |
---|---|
STV_DEFAULT | 0 |
STV_INTERNAL | 1 |
STV_HIDDEN | 2 |
STV_PROTECTED | 3 |
-
STV_DEFAULT
-
The visibility of symbols with the STV_DEFAULT attribute is as specified by the symbol's binding type. Global symbols and weak symbols are visible outside of their defining component, the executable file or shared object. Local symbols are hidden. Global symbols and weak symbols can also be preempted. These symbols can by interposed by definitions of the same name in another component.
STV_PROTECTED
-
A symbol that is defined in the current component is protected if the symbol is visible in other components, but cannot be preempted. Any reference to such a symbol from within the defining component must be resolved to the definition in that component. This resolution must occur, even if a symbol definition exists in another component that would interpose by the default rules. A symbol withSTB_LOCAL binding will not have STV_PROTECTED visibility.
STV_HIDDEN
-
A symbol that is defined in the current component is hidden if its name is not visible to other components. Such a symbol is necessarily protected. This attribute is used to control the external interface of a component. An object named by such a symbol can still be referenced from another component if its address is passed outside.
A hidden symbol contained in a relocatable object is either removed or converted to STB_LOCAL binding when the object is included in an executable file or shared object.
STV_INTERNAL
-
This visibility attribute is currently reserved.
The visibility attributes do not affect the resolution of symbols within an executable or shared object during link-editing. Such resolution is controlled by the binding type. Once the link-editor has chosen its resolution, these attributes impose two requirements. Both requirements are based on the fact that references in the code being linked might have been optimized to take advantage of the attributes.
-
All of the non-default visibility attributes, when applied to a symbol reference, imply that a definition to satisfy that reference must be provided within the object being linked. If this type of symbol reference has no definition within the object being linked, then the reference must have STB_WEAK binding. In this case, the reference is resolved to zero.
-
If any reference to a name, or definition of a name is a symbol with a non-default visibility attribute, the visibility attribute is propagated to the resolving symbol in the object being linked. If different visibility attributes are specified for distinct instances of a symbol, the most constraining visibility attribute is propagated to the resolving symbol in the object being linked. The attributes, ordered from least to most constraining, are STV_PROTECTED, STV_HIDDEN and STV_INTERNAL.
If a symbol's value refers to a specific location within a section, the symbols's section index member, st_shndx, holds an index into the section header table. As the section moves during relocation, the symbol's value changes as well. References to the symbol continue to point to the same location in the program. Some special section index values give other semantics.
-
SHN_ABS
-
This symbol has an absolute value that does not change because of relocation.
SHN_COMMON, and
SHN_AMD64_LCOMMON
-
This symbol labels a common block that has not yet been allocated. The symbol's value gives alignment constraints, similar to a section's sh_addralign member. The link-editor allocates the storage for the symbol at an address that is a multiple ofst_value. The symbol's size tells how many bytes are required.
SHN_UNDEF
-
This section table index indicates that the symbol is undefined. When the link-editor combines this object file with another object that defines the indicated symbol, this file's references to the symbol is bound to the definition.
As mentioned previously, the symbol table entry for index 0 (STN_UNDEF) is reserved. This entry holds the values listed in the following table.
Table 7–21 ELF Symbol Table Entry: Index 0 Name | Value | Note |
---|---|---|
st_name | 0 | No name |
st_value | 0 | Zero value |
st_size | 0 | No size |
st_info | 0 | No type, local binding |
st_other | 0 |
|
st_shndx | SHN_UNDEF | No section |
Symbol Values
Symbol table entries for different object file types have slightly different interpretations for the st_value member.
-
In relocatable files, st_value holds alignment constraints for a symbol whose section index is SHN_COMMON.
-
In relocatable files, st_value holds a section offset for a defined symbol. st_value is an offset from the beginning of the section that st_shndx identifies.
-
In executable and shared object files, st_value holds a virtual address. To make these files' symbols more useful for the runtime linker, the section offset (file interpretation) gives way to a virtual address (memory interpretation) for which the section number is irrelevant.
Although the symbol table values have similar meanings for different object files, the data allow efficient access by the appropriate programs.
Symbol Table Layout and Conventions
The symbols in a symbol table are written in the following order.
-
Index 0 in any symbol table is used to represent undefined symbols. This first entry in a symbol table is always completely zeroed. The symbol type is therefore STT_NOTYPE.
-
If the symbol table contains any local symbols, the second entry of the symbol table is an STT_FILE symbol giving the name of the file.
-
Section symbols of type STT_SECTION.
-
Register symbols of type STT_REGISTER.
-
Global symbols that have been reduced to local scope.
-
For each input file that supplies local symbols, a STT_FILE symbol giving the name of the input file, followed by the symbols in question.
-
The global symbols immediately follow the local symbols in the symbol table. The first global symbol is identified by the symbol tablesh_info value. Local and global symbols are always kept separate in this manner, and cannot be mixed together.
Two symbol tables are of special interest in the Solaris OS.
-
.symtab (
SHT_SYMTAB)
-
This symbol table contains every symbol that describes the associated ELF file. This symbol table is typically non-allocable, and is therefore not available in the memory image of the process.
Global symbols can be eliminated from the .symtab by using a mapfile together with the ELIMINATE keyword. See Defining Additional Symbols with a mapfile. Local symbols can also be eliminated by using the link-editor -z redlocsym option.
.dynsym (
SHT_DYNSYM)
-
This table contains a subset of the symbols from the .symtab table that are needed to support dynamic linking. This symbol table is allocable, and is therefore available in the memory image of the process.
The .dynsym table begins with the standard NULL symbol, followed by the files global symbols. STT_FILE symbols are typically not present in this symbol table. STT_SECTION symbols might be present if required by relocation entries.
Register Symbols
The SPARC architecture supports register symbols, which are symbols that initialize a global register. A symbol table entry for a register symbol contains the entries that are listed in the following table.
Table 7–22 SPARC: ELF Symbol Table Entry: Register Symbol Field | Meaning |
---|---|
st_name | Index into the string table for the name of the symbol, or the value 0 for a scratch register. |
st_value | Register number. See the ABI manual for integer register assignments. |
st_size | Unused (0). |
st_info | Bind is typically STB_GLOBAL, type must be STT_SPARC_REGISTER. |
st_other | Unused (0). |
st_shndx | SHN_ABS if this object initializes this register symbol,SHN_UNDEF otherwise. |
The register values that are defined for SPARC are listed in the following table.
Table 7–23 SPARC: ELF Register Numbers Name | Value | Meaning |
---|---|---|
STO_SPARC_REGISTER_G2 | 0x2 | %g2 |
STO_SPARC_REGISTER_G3 | 0x3 | %g3 |
Absence of an entry for a particular global register means that the particular global register is not used at all by the object.
Syminfo Table Section
The syminfo section contains multiple entries of the type Elf32_Syminfo or Elf64_Syminfo. The .SUNW_syminfo section contains one entry for every entry in the associated symbol table (sh_link).
If this section is present in an object, additional symbol information is to be found by taking the symbol index from the associated symbol table and using that to find the corresponding Elf32_Syminfo entry or Elf64_Syminfo entry in this section. The associated symbol table and the Syminfo table will always have the same number of entries.
Index 0 is used to store the current version of the Syminfo table, which is SYMINFO_CURRENT. Since symbol table entry 0 is always reserved for the UNDEF symbol table entry, this usage does not pose any conflicts.
An Syminfo entry has the following format. See sys/link.h.
typedef struct { Elf32_Half si_boundto; Elf32_Half si_flags; } Elf32_Syminfo; typedef struct { Elf64_Half si_boundto; Elf64_Half si_flags; } Elf64_Syminfo;
-
si_boundto
-
An index to an entry in the .dynamic section, identified by the sh_info field, which augments the Syminfo flags. For example, a DT_NEEDED entry identifies a dynamic object associated with the Syminfo entry. The entries that follow are reserved values for si_boundto.
Name
Value
Meaning
SYMINFO_BT_SELF
0xffff
Symbol bound to self.
SYMINFO_BT_PARENT
0xfffe
Symbol bound to parent. The parent is the first object to cause this dynamic object to be loaded.
SYMINFO_BT_NONE
0xfffd
Symbol has no special symbol binding.
si_flags
-
This bit-field can have flags set, as shown in the following table.
Name
Value
Meaning
SYMINFO_FLG_DIRECT
0x01
Symbol reference has a direct association to the object containing the definition.
SYMINFO_FLG_COPY
0x04
Symbol definition is the result of a copy-relocation.
SYMINFO_FLG_LAZYLOAD
0x08
Symbol reference is to an object that should be lazily loaded.
SYMINFO_FLG_DIRECTBIND
0x10
Symbol reference should be bound directly to the definition.
SYMINFO_FLG_NOEXTDIRECT
0x20
Do not allow an external reference to directly bind to this symbol definition.
Versioning Sections
Objects created by the link-editor can contain two types of versioning information.
-
Version definitions provide associations of global symbols and are implemented using sections of type SHT_SUNW_verdef andSHT_SUNW_versym.
-
Version dependencies indicate the version definition requirements from other object dependencies and are implemented using sections of type SHT_SUNW_verneed.
The structures that form these sections are defined in sys/link.h. Sections that contain versioning information are named.SUNW_version.
Version Definition Section
This section is defined by the type SHT_SUNW_verdef. If this section exists, a SHT_SUNW_versym section must also exist. These two structures provide an association of symbols to version definitions within the file. See Creating a Version Definition. Elements of this section have the following structure.
typedef struct { Elf32_Half vd_version; Elf32_Half vd_flags; Elf32_Half vd_ndx; Elf32_Half vd_cnt; Elf32_Word vd_hash; Elf32_Word vd_aux; Elf32_Word vd_next; } Elf32_Verdef; typedef struct { Elf32_Word vda_name; Elf32_Word vda_next; } Elf32_Verdaux; typedef struct { Elf64_Half vd_version; Elf64_Half vd_flags; Elf64_Half vd_ndx; Elf64_Half vd_cnt; Elf64_Word vd_hash; Elf64_Word vd_aux; Elf64_Word vd_next; } Elf64_Verdef; typedef struct { Elf64_Word vda_name; Elf64_Word vda_next; } Elf64_Verdaux;
-
vd_version
-
This member identifies the version of the structure, as listed in the following table.
Name
Value
Meaning
VER_DEF_NONE
0
Invalid version.
VER_DEF_CURRENT
>=1
Current version.
The value 1 signifies the original section format. Extensions require new versions with higher numbers. The value ofVER_DEF_CURRENT changes as necessary to reflect the current version number.
vd_flags
-
This member holds version definition-specific information, as listed in the following table.
Name
Value
Meaning
VER_FLG_BASE
0x1
Version definition of the file.
VER_FLG_WEAK
0x2
Weak version identifier.
The base version definition is always present when version definitions, or symbol auto-reduction, have been applied to the file. The base version provides a default version for the files reserved symbols. A weak version definition has no symbols associated with the version. See Creating a Weak Version Definition.
vd_ndx
-
The version index. Each version definition has a unique index that is used to associate SHT_SUNW_versym entries to the appropriate version definition.
vd_cnt
-
The number of elements in the Elf32_Verdaux array.
vd_hash
-
The hash value of the version definition name. This value is generated using the same hashing function that is described in Hash Table Section.
vd_aux
-
The byte offset from the start of this Elf32_Verdef entry to the Elf32_Verdaux array of version definition names. The first element of the array must exist. This element points to the version definition string this structure defines. Additional elements can be present. The number of elements is indicated by the vd_cnt value. These elements represent the dependencies of this version definition. Each of these dependencies will have its own version definition structure.
vd_next
-
The byte offset from the start of this Elf32_Verdef structure to the next Elf32_Verdef entry.
vda_name
-
The string table offset to a null-terminated string, giving the name of the version definition.
vda_next
-
The byte offset from the start of this Elf32_Verdaux entry to the next Elf32_Verdaux entry.
Version Dependency Section
The version dependency section is defined by the type SHT_SUNW_verneed. This section complements the dynamic dependency requirements of the file by indicating the version definitions required from these dependencies. A recording is made in this section only if a dependency contains version definitions. Elements of this section have the following structure.
typedef struct { Elf32_Half vn_version; Elf32_Half vn_cnt; Elf32_Word vn_file; Elf32_Word vn_aux; Elf32_Word vn_next; } Elf32_Verneed; typedef struct { Elf32_Word vna_hash; Elf32_Half vna_flags; Elf32_Half vna_other; Elf32_Word vna_name; Elf32_Word vna_next; } Elf32_Vernaux; typedef struct { Elf64_Half vn_version; Elf64_Half vn_cnt; Elf64_Word vn_file; Elf64_Word vn_aux; Elf64_Word vn_next; } Elf64_Verneed; typedef struct { Elf64_Word vna_hash; Elf64_Half vna_flags; Elf64_Half vna_other; Elf64_Word vna_name; Elf64_Word vna_next; } Elf64_Vernaux;
-
vn_version
-
This member identifies the version of the structure, as listed in the following table.
Name
Value
Meaning
VER_NEED_NONE
0
Invalid version.
VER_NEED_CURRENT
>=1
Current version.
The value 1 signifies the original section format. Extensions require new versions with higher numbers. The value ofVER_NEED_CURRENT changes as necessary to reflect the current version number.
vn_cnt
-
The number of elements in the Elf32_Vernaux array.
vn_file
-
The string table offset to a null-terminated string, providing the file name of a version dependency. This name matches one of the.dynamic dependencies found in the file. See Dynamic Section.
vn_aux
-
The byte offset, from the start of this Elf32_Verneed entry, to the Elf32_Vernaux array of version definitions that are required from the associated file dependency. At least one version dependency must exist. Additional version dependencies can be present, the number being indicated by the vn_cnt value.
vn_next
-
The byte offset, from the start of this Elf32_Verneed entry, to the next Elf32_Verneed entry.
vna_hash
-
The hash value of the version dependency name. This value is generated using the same hashing function that is described in Hash Table Section.
vna_flags
-
Version dependency specific information, as listed in the following table.
Name
Value
Meaning
VER_FLG_WEAK
0x2
Weak version identifier.
A weak version dependency indicates an original binding to a weak version definition.
vna_other
-
Presently unused.
vna_name
-
The string table offset to a null-terminated string, giving the name of the version dependency.
vna_next
-
The byte offset from the start of this Elf32_Vernaux entry to the next Elf32_Vernaux entry.
Version Symbol Section
The version symbol section is defined by the type SHT_SUNW_versym. This section consists of an array of elements of the following structure.
typedef Elf32_Half Elf32_Versym; typedef Elf64_Half Elf64_Versym;
The number of elements of the array must equal the number of symbol table entries that are contained in the associated symbol table. This number is determined by the section's sh_link value. Each element of the array contains a single index that can have the values shown in the following table.
Table 7–24 ELF Version Dependency Indexes Name | Value | Meaning |
---|---|---|
VER_NDX_LOCAL | 0 | Symbol has local scope. |
VER_NDX_GLOBAL | 1 | Symbol has global scope and is assigned to the base version definition. |
| >1 | Symbol has global scope and is assigned to a user-defined version definition. |
Any index values that are greater than VER_NDX_GLOBAL must correspond to the vd_ndx value of an entry in the SHT_SUNW_verdefsection. If no index values that are greater than VER_NDX_GLOBAL exist, then no SHT_SUNW_verdef section need be present.
Dynamic Linking
This section describes the object file information and system actions that create running programs. Most information here applies to all systems. Information specific to one processor resides in sections marked accordingly.
Executable and shared object files statically represent application programs. To execute such programs, the system uses the files to create dynamic program representations, or process images. A process image has segments that contain its text, data, stack, and so on. The following major subsections are provided.
-
Program Header describes object file structures that are directly involved in program execution. The primary data structure, a program header table, locates segment images in the file and contains other information that is needed to create the memory image of the program.
-
Program Loading (Processor-Specific) describes the information used to load a program into memory.
-
Runtime Linker describes the information used to specify and resolve symbolic references among the object files of the process image.
Program Header
An executable or shared object file's program header table is an array of structures. Each structure describes a segment or other information that the system needs to prepare the program for execution. An object file segment contains one or more sections, as described in Segment Contents.
Program headers are meaningful only for executable and shared object files. A file specifies its own program header size with the ELF header's e_phentsize and e_phnum members.
A program header has the following structure. See sys/elf.h.
typedef struct { Elf32_Word p_type; Elf32_Off p_offset; Elf32_Addr p_vaddr; Elf32_Addr p_paddr; Elf32_Word p_filesz; Elf32_Word p_memsz; Elf32_Word p_flags; Elf32_Word p_align; } Elf32_Phdr; typedef struct { Elf64_Word p_type; Elf64_Word p_flags; Elf64_Off p_offset; Elf64_Addr p_vaddr; Elf64_Addr p_paddr; Elf64_Xword p_filesz; Elf64_Xword p_memsz; Elf64_Xword p_align; } Elf64_Phdr;
-
p_type
-
The kind of segment this array element describes or how to interpret the array element's information. Type values and their meanings are specified in Table 7–25.
p_offset
-
The offset from the beginning of the file at which the first byte of the segment resides.
p_vaddr
-
The virtual address at which the first byte of the segment resides in memory.
p_paddr
-
The segment's physical address for systems in which physical addressing is relevant. Because the system ignores physical addressing for application programs, this member has unspecified contents for executable files and shared objects.
p_filesz
-
The number of bytes in the file image of the segment, which can be zero.
p_memsz
-
The number of bytes in the memory image of the segment, which can be zero.
p_flags
-
Flags that are relevant to the segment. Type values and their meanings are specified in Table 7–26.
p_align
-
Loadable process segments must have congruent values for p_vaddr and p_offset, modulo the page size. This member gives the value to which the segments are aligned in memory and in the file. Values 0 and 1 mean no alignment is required. Otherwise,p_align should be a positive, integral power of 2, and p_vaddr should equal p_offset, modulo p_align. See Program Loading (Processor-Specific).
Some entries describe process segments. Other entries give supplementary information and do not contribute to the process image. Segment entries can appear in any order, except as explicitly noted. Defined type values are listed in the following table.
Table 7–25 ELF Segment Types Name | Value |
---|---|
PT_NULL | 0 |
PT_LOAD | 1 |
PT_DYNAMIC | 2 |
PT_INTERP | 3 |
PT_NOTE | 4 |
PT_SHLIB | 5 |
PT_PHDR | 6 |
PT_TLS | 7 |
PT_LOOS | 0x60000000 |
PT_SUNW_UNWIND | 0x6464e550 |
PT_LOSUNW | 0x6ffffffa |
PT_SUNWBSS | 0x6ffffffa |
PT_SUNWSTACK | 0x6ffffffb |
PT_SUNWDTRACE | 0x6ffffffc |
PT_SUNWCAP | 0x6ffffffd |
PT_HISUNW | 0x6fffffff |
PT_HIOS | 0x6fffffff |
PT_LOPROC | 0x70000000 |
PT_HIPROC | 0x7fffffff |
-
PT_NULL
-
Unused. Member values are undefined. This type enables the program header table to contain ignored entries.
PT_LOAD
-
Specifies a loadable segment, described by p_filesz and p_memsz. The bytes from the file are mapped to the beginning of the memory segment. If the segment's memory size (p_memsz) is larger than the file size (p_filesz), the extra bytes are defined to hold the value 0. These bytes follow the initialized area of the segment. The file size can not be larger than the memory size. Loadable segment entries in the program header table appear in ascending order, and are sorted on the p_vaddr member.
PT_DYNAMIC
-
Specifies dynamic linking information. See Dynamic Section.
PT_INTERP
-
Specifies the location and size of a null-terminated path name to invoke as an interpreter. This type is mandatory for dynamic executable files. This type can occur in shared objects. This type cannot occur more than once in a file. This type, if present, must precede any loadable segment entries. See Program Interpreter for details.
PT_NOTE
-
Specifies the location and size of auxiliary information. See Note Section for details.
PT_SHLIB
-
Reserved but has unspecified semantics.
PT_PHDR
-
Specifies the location and size of the program header table, both in the file and in the memory image of the program. This segment type cannot occur more than once in a file. Moreover, this segment can occur only if the program header table is part of the memory image of the program. This type, if present, must precede any loadable segment entry. See Program Interpreter for details.
PT_TLS
-
Specifies a thread-local storage template. See Thread-Local Storage Section for details.
PT_LOOS -
PT_HIOS
-
Values in this inclusive range are reserved for OS-specific semantics.
PT_SUNW_UNWIND
-
This segment contains the stack unwind tables.
PT_LOSUNW -
PT_HISUNW
-
Values in this inclusive range are reserved for Sun-specific semantics.
PT_SUNWBSS
-
The same attributes as a PT_LOAD element and used to describe a .SUNW_bss section.
PT_SUNWSTACK
-
Describes a process stack. Only one PT_SUNWSTACK element can exist. Only access permissions, as defined in the p_flagsfield, are meaningful.
PT_SUNWDTRACE
-
Reserved for internal use by dtrace(1M).
PT_SUNWCAP
-
Specifies hardware capability requirements. See Hardware and Software Capabilities Section for details.
PT_LOPROC -
PT_HIPROC
-
Values in this inclusive range are reserved for processor-specific semantics.
Note –
Unless specifically required elsewhere, all program header segment types are optional. A file's program header table can contain only those elements that are relevant to its contents.
Base Address
Executable and shared object files have a base address, which is the lowest virtual address associated with the memory image of the program's object file. One use of the base address is to relocate the memory image of the program during dynamic linking.
An executable or shared object file's base address is calculated during execution from three values: the memory load address, the maximum page size, and the lowest virtual address of a program's loadable segment. The virtual addresses in the program headers might not represent the actual virtual addresses of the program's memory image. See Program Loading (Processor-Specific).
To compute the base address, you determine the memory address that are associated with the lowest p_vaddr value for a PT_LOADsegment. You then obtain the base address by truncating the memory address to the nearest multiple of the maximum page size. Depending on the kind of file being loaded into memory, the memory address might not match the p_vaddr values.
Segment Permissions
A program to be loaded by the system must have at least one loadable segment, although this restriction is not required by the file format. When the system creates loadable segment memory images, the system gives access permissions, as specified in the p_flags member. All bits that are included in the PF_MASKPROC mask are reserved for processor-specific semantics.
Table 7–26 ELF Segment Flags Name | Value | Meaning |
---|---|---|
PF_X | 0x1 | Execute |
PF_W | 0x2 | Write |
PF_R | 0x4 | Read |
PF_MASKPROC | 0xf0000000 | Unspecified |
If a permission bit is 0, that bit's type of access is denied. Actual memory permissions depend on the memory management unit, which can vary between systems. Although all flag combinations are valid, the system can grant more access than requested. In no case, however, will a segment have write permission unless this permission is specified explicitly. The following table lists both the exact flag interpretation and the allowable flag interpretation.
Table 7–27 ELF Segment Permissions Flags | Value | Exact | Allowable |
---|---|---|---|
None | 0 | All access denied | All access denied |
PF_X | 1 | Execute only | Read, execute |
PF_W | 2 | Write only | Read, write, execute |
PF_W + PF_X | 3 | Write, execute | Read, write, execute |
PF_R | 4 | Read only | Read, execute |
PF_R + PF_X | 5 | Read, execute | Read, execute |
PF_R + PF_W | 6 | Read, write | Read, write, execute |
PF_R + PF_W + PF_X | 7 | Read, write, execute | Read, write, execute |
For example, typical text segments have read and execute, but not write permissions. Data segments normally have read, write, and execute permissions.
Segment Contents
An object file segment consists of one or more sections, though this fact is transparent to the program header. Whether the file segment holds one section or many sections, is also immaterial to program loading. Nonetheless, various data must be present for program execution, dynamic linking, and so on. The following diagrams illustrate segment contents in general terms. The order and membership of sections within a segment can vary.
Text segments contain read-only instructions and data. Data segments contain writable-data and instructions. See Table 7–10 for a list of all special sections.
A PT_DYNAMIC program header element points at the .dynamic section. The .got and .plt sections also hold information related to position-independent code and dynamic linking.
The .plt can reside in a text or a data segment, depending on the processor. See Global Offset Table (Processor-Specific) and Procedure Linkage Table (Processor-Specific) for details.
Sections of type SHT_NOBITS occupy no space in the file, but contribute to the segment's memory image. Normally, these uninitialized data reside at the end of the segment, thereby making p_memsz larger than p_filesz in the associated program header element.
Program Loading (Processor-Specific)
As the system creates or augments a process image, the system logically copies a file's segment to a virtual memory segment. When, and if, the system physically reads the file depends on the program's execution behavior, system load, and so forth.
A process does not require a physical page unless the process references the logical page during execution. Processes commonly leave many pages unreferenced. Therefore, delaying physical reads can improve system performance. To obtain this efficiency in practice, executable files and shared object files must have segment images whose file offsets and virtual addresses are congruent, modulo the page size.
Virtual addresses and file offsets for 32–bit segments are congruent modulo 64K (0x10000). Virtual addresses and file offsets for 64–bit segments are congruent modulo 1 megabyte (0x100000). By aligning segments to the maximum page size, the files are suitable for paging regardless of physical page size.
By default, 64–bit SPARC programs are linked with a starting address of 0x100000000. The whole program is located above 4 gigabytes, including its text, data, heap, stack, and shared object dependencies. This helps ensure that 64–bit programs are correct because the program will fault in the least significant 4 gigabytes of its address space if the program truncates any of its pointers. While 64–bit programs are linked above 4 gigabytes, you can still link programs below 4 gigabytes by using a mapfile and the -M option to the link-editor. See/usr/lib/ld/sparcv9/map.below4G.
The following figure presents the SPARC version of the executable file.
Figure 7–8 SPARC: Executable File (64K alignment)
![SPARC executable file layout example. SPARC executable file layout example.](https://i-blog.csdnimg.cn/blog_migrate/a3c048e8f0e11f1cbe05448a8740e362.gif)
The following table defines the loadable segment elements for the previous figure.
Table 7–28 SPARC: ELF Program Header Segments (64K alignment) Member | Text | Data |
---|---|---|
p_type | PT_LOAD | PT_LOAD |
p_offset | 0x0 | 0x4000 |
p_vaddr | 0x10000 | 0x24000 |
p_paddr | Unspecified | Unspecified |
p_filesize | 0x3a82 | 0x4f5 |
p_memsz | 0x3a82 | 0x10a4 |
p_flags | PF_R + PF_X | PF_R + PF_W + PF_X |
p_align | 0x10000 | 0x10000 |
The following figure presents the x86 version of the executable file.
Figure 7–9 32-bit x86: Executable File (64K alignment)
![x86 executable file layout example. x86 executable file layout example.](https://i-blog.csdnimg.cn/blog_migrate/7bb8c345da4b96d6fb2f98f045cccf0b.gif)
The following table defines the loadable segment elements for the previous figure.
Table 7–29 32-bit x86: ELF Program Header Segments (64K alignment) Member | Text | Data |
---|---|---|
p_type | PT_LOAD | PT_LOAD |
p_offset | 0x0 | 0x4000 |
p_vaddr | 0x8050000 | 0x8064000 |
p_paddr | Unspecified | Unspecified |
p_filesize | 0x32fd | 0x3a0 |
p_memsz | 0x32fd | 0xdc4 |
p_flags | PF_R + PF_X | PF_R + PF_W + PF_X |
p_align | 0x10000 | 0x10000 |
The example's file offsets and virtual addresses are congruent modulo the maximum page size for both text and data. Up to four file pages hold impure text or data depending on page size and file system block size.
-
The first text page contains the ELF header, the program header table, and other information.
-
The last text page holds a copy of the beginning of data.
-
The first data page has a copy of the end of text.
-
The last data page can contain file information not relevant to the running process. Logically, the system enforces the memory permissions as if each segment were complete and separate The segments addresses are adjusted to ensure that each logical page in the address space has a single set of permissions. In the previous examples, the region of the file holding the end of text and the beginning of data is mapped twice: at one virtual address for text and at a different virtual address for data.
Note –
The previous examples reflect typical Solaris OS binaries that have their text segments rounded.
The end of the data segment requires special handling for uninitialized data, which the system defines to begin with zero values. 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 unknown contents of the executable file.
Impurities in the other three pages are not logically part of the process image. Whether the system expunges these impurities is unspecified. The memory image for this program is shown in the following figures, assuming 4 Kbyte (0x1000) pages. For simplicity, these figures illustrate only one page size.
Figure 7–10 32-bit SPARC: Process Image Segments
![SPARC process image segments example. SPARC process image segments example.](https://i-blog.csdnimg.cn/blog_migrate/7c9d61d1d4c7223152f33068d96250b9.gif)
Figure 7–11 x86: Process Image Segments
![x86 process image segments example. x86 process image segments example.](https://i-blog.csdnimg.cn/blog_migrate/a4e912b39be6c6b4d8dd1cc89397a473.gif)
One aspect of segment loading differs between executable files and shared objects. Executable file segments typically contain absolute code. For the process to execute correctly, the segments must reside at the virtual addresses used to create the executable file. The system uses the p_vaddr values unchanged as virtual addresses.
On the other hand, shared object segments typically contain position-independent code. This code enables a segment's virtual address change between different processes, without invalidating execution behavior.
Though the system chooses virtual addresses for individual processes, it maintains the relative positions of the segments. Because position-independent code uses relative addressing between segments, the difference between virtual addresses in memory must match the difference between virtual addresses in the file.
The following tables show possible shared object virtual address assignments for several processes, illustrating constant relative positioning. The tables also include the base address computations.
Table 7–30 32-bit SPARC: ELF Example Shared Object Segment Addresses Source | Text | Data | Base Address |
---|---|---|---|
File | 0x0 | 0x4000 | 0x0 |
Process 1 | 0xc0000000 | 0xc0024000 | 0xc0000000 |
Process 2 | 0xc0010000 | 0xc0034000 | 0xc0010000 |
Process 3 | 0xd0020000 | 0xd0024000 | 0xd0020000 |
Process 4 | 0xd0030000 | 0xd0034000 | 0xd0030000 |
Source | Text | Data | Base Address |
---|---|---|---|
File | 0x0 | 0x4000 | 0x0 |
Process 1 | 0x8000000 | 0x8004000 | 0x80000000 |
Process 2 | 0x80081000 | 0x80085000 | 0x80081000 |
Process 3 | 0x900c0000 | 0x900c4000 | 0x900c0000 |
Process 4 | 0x900c6000 | 0x900ca000 | 0x900c6000 |
Program Interpreter
A dynamic executable or shared object that initiates dynamic linking can have one PT_INTERP program header element. During exec(2), the system retrieves a path name from the PT_INTERP segment and creates the initial process image from the interpreter file's segments. The interpreter is responsible for receiving control from the system and providing an environment for the application program.
In the Solaris OS, the interpreter is known as the runtime linker, ld.so.1(1).
Runtime Linker
When creating a dynamic object that initiates dynamic linking, the link-editor adds a program header element of type PT_INTERP to an executable file. This element instructing the system to invoke the runtime linker as the program interpreter. exec(2) and the runtime linker cooperate to create the process image for the program.
The link-editor constructs various data for executable and shared object files that assist the runtime linker. These data reside in loadable segments, thus making the data available during execution. These segments include.
-
A .dynamic section with type SHT_DYNAMIC that holds various data. The structure residing at the beginning of the section holds the addresses of other dynamic linking information.
-
The .got and .plt sections with type SHT_PROGBITS that hold two separate tables: the global offset table and the procedure linkage table. Sections that follow, explain how the runtime linker uses and changes the tables to create memory images for object files.
-
The .hash section with type SHT_HASH that holds a symbol hash table.
Shared objects can occupy virtual memory addresses that are different from the addresses that are recorded in the file's program header table. The runtime linker relocates the memory image, updating absolute addresses before the application gains control.
Dynamic Section
If an object file participates in dynamic linking, its program header table will have an element of type PT_DYNAMIC. This segment contains the .dynamic section. A special symbol, _DYNAMIC, labels the section, which contains an array of the following structures. Seesys/link.h.
typedef struct { Elf32_Sword d_tag; union { Elf32_Word d_val; Elf32_Addr d_ptr; Elf32_Off d_off; } d_un; } Elf32_Dyn; typedef struct { Elf64_Xword d_tag; union { Elf64_Xword d_val; Elf64_Addr d_ptr; } d_un; } Elf64_Dyn;
For each object with this type, d_tag controls the interpretation of d_un.
-
d_val
-
These objects represent integer values with various interpretations.
d_ptr
-
These objects represent program virtual addresses. A file's virtual addresses might not match the memory virtual addresses during execution. When interpreting addresses contained in the dynamic structure, the runtime linker computes actual addresses, based on the original file value and the memory base address. For consistency, files do not contain relocation entries to correct addresses in the dynamic structure.
The value of each dynamic tag, except for those tags in two special compatibility ranges, determines the interpretation of the d_un union. This convention provides for simpler interpretation of dynamic tags by external tools. A tag whose value is an even number indicates a dynamic section entry that uses d_ptr. A tag whose value is an odd number indicates a dynamic section entry that uses d_val, or that the tag uses neither d_ptr nor d_val. Tags whose values are less than the special value DT_ENCODING and tags whose values fall between DT_HIOS and DT_LOPROC do not follow these rules.
The following table summarizes the tag requirements for executable and shared object files. If a tag is marked mandatory, then the dynamic linking array must have an entry of that type. Likewise, optional means an entry for the tag can appear but is not required.
Table 7–32 ELF Dynamic Array Tags Name | Value | d_un | Executable | Shared Object |
---|---|---|---|---|
DT_NULL | 0 | Ignored | Mandatory | Mandatory |
DT_NEEDED | 1 | d_val | Optional | Optional |
DT_PLTRELSZ | 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 | 7 | d_ptr | Mandatory | Optional |
DT_RELASZ | 8 | d_val | Mandatory | Optional |
DT_RELAENT | 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 | Optional |
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 | 20 | d_val | Optional | Optional |
DT_DEBUG | 21 | d_ptr | Optional | Ignored |
DT_TEXTREL | 22 | Ignored | Optional | Optional |
DT_JMPREL | 23 | d_ptr | Optional | Optional |
DT_BIND_NOW | 24 | Ignored | Optional | Optional |
DT_INIT_ARRAY | 25 | d_ptr | Optional | Optional |
DT_FINI_ARRAY | 26 | d_ptr | Optional | Optional |
DT_INIT_ARRAYSZ | 27 | d_val | Optional | Optional |
DT_FINI_ARRAYSZ | 28 | d_val | Optional | Optional |
DT_RUNPATH | 29 | d_val | Optional | Optional |
DT_FLAGS | 30 | d_val | Optional | Optional |
DT_ENCODING | 32 | Unspecified | Unspecified | Unspecified |
DT_PREINIT_ARRAY | 32 | d_ptr | Optional | Ignored |
DT_PREINIT_ARRAYSZ | 33 | d_val | Optional | Ignored |
DT_MAXPOSTAGS | 34 | Unspecified | Unspecified | Unspecified |
DT_LOOS | 0x6000000d | Unspecified | Unspecified | Unspecified |
DT_SUNW_AUXILIARY | 0x6000000d | d_ptr | Unspecified | Optional |
DT_SUNW_RTLDINF | 0x6000000e | d_ptr | Optional | Optional |
DT_SUNW_FILTER | 0x6000000e | d_ptr | Unspecified | Optional |
DT_SUNW_CAP | 0x60000010 | d_ptr | Optional | Optional |
DT_HIOS | 0x6ffff000 | Unspecified | Unspecified | Unspecified |
DT_VALRNGLO | 0x6ffffd00 | Unspecified | Unspecified | Unspecified |
DT_CHECKSUM | 0x6ffffdf8 | d_val | Optional | Optional |
DT_PLTPADSZ | 0x6ffffdf9 | d_val | Optional | Optional |
DT_MOVEENT | 0x6ffffdfa | d_val | Optional | Optional |
DT_MOVESZ | 0x6ffffdfb | d_val | Optional | Optional |
DT_FEATURE_1 | 0x6ffffdfc | d_val | Optional | Optional |
DT_POSFLAG_1 | 0x6ffffdfd | d_val | Optional | Optional |
DT_SYMINSZ | 0x6ffffdfe | d_val | Optional | Optional |
DT_SYMINENT | 0x6ffffdff | d_val | Optional | Optional |
DT_VALRNGHI | 0x6ffffdff | Unspecified | Unspecified | Unspecified |
DT_ADDRRNGLO | 0x6ffffe00 | Unspecified | Unspecified | Unspecified |
DT_CONFIG | 0x6ffffefa | d_ptr | Optional | Optional |
DT_DEPAUDIT | 0x6ffffefb | d_ptr | Optional | Optional |
DT_AUDIT | 0x6ffffefc | d_ptr | Optional | Optional |
DT_PLTPAD | 0x6ffffefd | d_ptr | Optional | Optional |
DT_MOVETAB | 0x6ffffefe | d_ptr | Optional | Optional |
DT_SYMINFO | 0x6ffffeff | d_ptr | Optional | Optional |
DT_ADDRRNGHI | 0x6ffffeff | Unspecified | Unspecified | Unspecified |
DT_RELACOUNT | 0x6ffffff9 | d_val | Optional | Optional |
DT_RELCOUNT | 0x6ffffffa | d_val | Optional | Optional |
DT_FLAGS_1 | 0x6ffffffb | d_val | Optional | Optional |
DT_VERDEF | 0x6ffffffc | d_ptr | Optional | Optional |
DT_VERDEFNUM | 0x6ffffffd | d_val | Optional | Optional |
DT_VERNEED | 0x6ffffffe | d_ptr | Optional | Optional |
DT_VERNEEDNUM | 0x6fffffff | d_val | Optional | Optional |
DT_LOPROC | 0x70000000 | Unspecified | Unspecified | Unspecified |
DT_SPARC_REGISTER | 0x70000001 | d_val | Optional | Optional |
DT_AUXILIARY | 0x7ffffffd | d_val | Unspecified | Optional |
DT_USED | 0x7ffffffe | d_val | Optional | Optional |
DT_FILTER | 0x7fffffff | d_val | Unspecified | Optional |
DT_HIPROC | 0x7fffffff | Unspecified | Unspecified | Unspecified |
-
DT_NULL
-
Marks the end of the _DYNAMIC array.
DT_NEEDED
-
The DT_STRTAB string table offset of a null-terminated string, giving the name of a needed dependency. The dynamic array can contain multiple entries of this type. The relative order of these entries is significant, though their relation to entries of other types is not. See Shared Object Dependencies.
DT_PLTRELSZ
-
The total size, in bytes, of the relocation entries associated with the procedure linkage table. See Procedure Linkage Table (Processor-Specific).
DT_PLTGOT
-
An address associated with the procedure linkage table or the global offset table. See Procedure Linkage Table (Processor-Specific)and Global Offset Table (Processor-Specific).
DT_HASH
-
The address of the symbol hash table. This table refers to the symbol table indicated by the DT_SYMTAB element. See Hash Table Section.
DT_STRTAB
-
The address of the string table. Symbol names, dependency names, and other strings required by the runtime linker reside in this table. See String Table Section.
DT_SYMTAB
-
The address of the symbol table. See Symbol Table Section.
DT_RELA
-
The address of a relocation table. See Relocation Sections.
An object file can have multiple relocation sections. When creating the relocation table for an executable or shared object file, the link-editor catenates those sections to form a single table. Although the sections can remain independent in the object file, the runtime linker sees a single table. When the runtime linker creates the process image for an executable file or adds a shared object to the process image, the runtime linker reads the relocation table and performs the associated actions.
This element requires the DT_RELASZ and DT_RELAENT elements also be present. When relocation is mandatory for a file, eitherDT_RELA or DT_REL can occur.
DT_RELASZ
-
The total size, in bytes, of the DT_RELA relocation table.
DT_RELAENT
-
The size, in bytes, of the DT_RELA relocation entry.
DT_STRSZ
-
The total size, in bytes, of the DT_STRTAB string table.
DT_SYMENT
-
The size, in bytes, of the DT_SYMTAB symbol entry.
DT_INIT
-
The address of an initialization function. See Initialization and Termination Sections.
DT_FINI
-
The address of a termination function. See Initialization and Termination Sections.
DT_SONAME
-
The DT_STRTAB string table offset of a null-terminated string, identifying the name of the shared object. See Recording a Shared Object Name.
DT_RPATH
-
The DT_STRTAB string table offset of a null-terminated library search path string. This element's use has been superseded byDT_RUNPATH. See Directories Searched by the Runtime Linker.
DT_SYMBOLIC
-
Indicates the object contains symbolic bindings that were applied during its link-edit. This elements use has been superseded by theDF_SYMBOLIC flag. See Using the -B symbolic Option.
DT_REL
-
Similar to DT_RELA, except its table has implicit addends. This element requires that the DT_RELSZ and DT_RELENT elements also be present.
DT_RELSZ
-
The total size, in bytes, of the DT_REL relocation table.
DT_RELENT
-
The size, in bytes, of the DT_REL relocation entry.
DT_PLTREL
-
Indicates the type of relocation entry to which the procedure linkage table refers, either DT_REL or DT_RELA. All relocations in a procedure linkage table must use the same relocation. See Procedure Linkage Table (Processor-Specific). This element requires aDT_JMPREL element also be present.
DT_DEBUG
-
Used for debugging.
DT_TEXTREL
-
Indicates that one or more relocation entries might request modifications to a non-writable segment, and the runtime linker can prepare accordingly. This element's use has been superseded by the DF_TEXTREL flag. See Position-Independent Code.
DT_JMPREL
-
The address of relocation entries that are associated solely with the procedure linkage table. See Procedure Linkage Table (Processor-Specific). The separation of these relocation entries enables the runtime linker to ignore these entries when the object is loaded with lazy binding enabled. This element requires the DT_PLTRELSZ and DT_PLTREL elements also be present.
DT_POSFLAG_1
-
Various state flags which are applied to the DT_ element immediately following. See Table 7–35.
DT_BIND_NOW
-
Indicates that all relocations for this object must be processed before returning control to the program. The presence of this entry takes precedence over a directive to use lazy binding when specified through the environment or by means of dlopen(3C). This element's use has been superseded by the DF_BIND_NOW flag. See When Relocations Are Performed.
DT_INIT_ARRAY
-
The address of an array of pointers to initialization functions. This element requires that a DT_INIT_ARRAYSZ element also be present. See Initialization and Termination Sections.
DT_FINI_ARRAY
-
The address of an array of pointers to termination functions. This element requires that a DT_FINI_ARRAYSZ element also be present. See Initialization and Termination Sections.
DT_INIT_ARRAYSZ
-
The total size, in bytes, of the DT_INIT_ARRAY array.
DT_FINI_ARRAYSZ
-
The total size, in bytes, of the DT_FINI_ARRAY array.
DT_RUNPATH
-
The DT_STRTAB string table offset of a null-terminated library search path string. See Directories Searched by the Runtime Linker.
DT_FLAGS
-
Flag values specific to this object. See Table 7–33.
DT_ENCODING
-
Dynamic tag values that are greater than or equal to DT_ENCODING, and less than or equal to DT_LOOS, follow the rules for the interpretation of the d_un union.
DT_PREINIT_ARRAY
-
The address of an array of pointers to pre-initialization functions. This element requires that a DT_PREINIT_ARRAYSZ element also be present. This array is processed only in an executable file. This array is ignored if contained in a shared object. See Initialization and Termination Sections.
DT_PREINIT_ARRAYSZ
-
The total size, in bytes, of the DT_PREINIT_ARRAY array.
DT_MAXPOSTAGS
-
The number of positive dynamic array tag values.
DT_LOOS -
DT_HIOS
-
Values in this inclusive range are reserved for operating system-specific semantics. All such values follow the rules for the interpretation of the d_un union.
DT_SUNW_AUXILIARY
-
The DT_STRTAB string table offset of a null-terminated string that names one or more per-symbol, auxiliary filtees. See Generating Auxiliary Filters.
DT_SUNW_RTLDINF
-
Reserved for internal use by the runtime-linker.
DT_SUNW_FILTER
-
The DT_STRTAB string table offset of a null-terminated string that names one or more per-symbol, standard filtees. See Generating Standard Filters.
DT_SUNW_CAP
-
The address of the hardware and software capabilities section. See Hardware and Software Capabilities Section.
DT_SYMINFO
-
The address of the symbol information table. This element requires that the DT_SYMINENT and DT_SYMINSZ elements also be present. See Syminfo Table Section.
DT_SYMINENT
-
The size, in bytes, of the DT_SYMINFO information entry.
DT_SYMINSZ
-
The total size, in bytes, of the DT_SYMINFO table.
DT_VERDEF
-
The address of the version definition table. Elements within this table contain indexes into the string table DT_STRTAB. This element requires that the DT_VERDEFNUM element also be present. See Version Definition Section.
DT_VERDEFNUM
-
The number of entries in the DT_VERDEF table.
DT_VERNEED
-
The address of the version dependency table. Elements within this table contain indexes into the string table DT_STRTAB. This element requires that the DT_VERNEEDNUM element also be present. See Version Dependency Section.
DT_VERNEEDNUM
-
The number of entries in the DT_VERNEEDNUM table.
DT_RELACOUNT
-
Indicates the RELATIVE relocation count, which is produced from the concatenation of all Elf32_Rela, or Elf64_Relarelocations. See Combined Relocation Sections.
DT_RELCOUNT
-
Indicates the RELATIVE relocation count, which is produced from the concatenation of all Elf32_Rel relocations. See Combined Relocation Sections.
DT_AUXILIARY
-
The DT_STRTAB string table offset of a null-terminated string that names one or more auxiliary filtees. See Generating Auxiliary Filters.
DT_FILTER
-
The DT_STRTAB string table offset of a null-terminated string that names one or more standard filtees. See Generating Standard Filters.
DT_CHECKSUM
-
A simple checksum of selected sections of the object. See gelf_checksum(3ELF).
DT_MOVEENT
-
The size, in bytes, of the DT_MOVETAB move entries.
DT_MOVESZ
-
The total size, in bytes, of the DT_MOVETAB table.
DT_MOVETAB
-
The address of a move table. This element requires that the DT_MOVEENT and DT_MOVESZ elements also be present. See Move Section.
DT_CONFIG
-
The DT_STRTAB string table offset of a null-terminated string defining a configuration file. The configuration file is only meaningful in an executable, and is typically unique to this object. See Configuring the Default Search Paths.
DT_DEPAUDIT
-
The DT_STRTAB string table offset of a null-terminated string defining one or more audit libraries. See Runtime Linker Auditing Interface.
DT_AUDIT
-
The DT_STRTAB string table offset of a null-terminated string defining one or more audit libraries. See Runtime Linker Auditing Interface.
DT_FLAGS_1
-
Flag values specific to this object. See Table 7–34.
DT_FEATURE_1
-
Feature values specific to this object. See Table 7–36.
DT_VALRNGLO -
DT_VALRNGHI
-
Values in this inclusive range use the d_un.d_val field of the dynamic structure.
DT_ADDRRNGLO -
DT_ADDRRNGHI
-
Values in this inclusive range use the d_un.d_ptr field of the dynamic structure. If any adjustment is made to the ELF object after the object has been built, these entries must be updated accordingly.
DT_SPARC_REGISTER
-
The index of an STT_SPARC_REGISTER symbol within the DT_SYMTAB symbol table. One dynamic entry exists for everySTT_SPARC_REGISTER symbol in the symbol table. See Register Symbols.
DT_LOPROC -
DT_HIPROC
-
Values in this inclusive range are reserved for processor-specific semantics.
Except for the DT_NULL element at the end of the dynamic array and the relative order of DT_NEEDED and DT_POSFLAG_1 elements, entries can appear in any order. Tag values not appearing in the table are reserved.
Table 7–33 ELF Dynamic Flags, DT_FLAGS Name | Value | Meaning |
---|---|---|
DF_ORIGIN | 0x1 | $ORIGIN processing required |
DF_SYMBOLIC | 0x2 | Symbolic symbol resolution required |
DF_TEXTREL | 0x4 | Text relocations exist |
DF_BIND_NOW | 0x8 | Non-lazy binding required |
DF_STATIC_TLS | 0x10 | Object uses static thread-local storage scheme |
-
DF_ORIGIN
-
Indicates that the object requires $ORIGIN processing. See Locating Associated Dependencies.
DF_SYMBOLIC
-
Indicates that the object contains symbolic bindings that were applied during its link-edit. See Using the -B symbolic Option.
DF_TEXTREL
-
Indicates that one or more relocation entries might request modifications to a non-writable segment, and the runtime linker can prepare accordingly. See Position-Independent Code.
DF_BIND_NOW
-
Indicates that all relocations for this object must be processed before returning control to the program. The presence of this entry takes precedence over a directive to use lazy binding when specified through the environment or by means of dlopen(3C). See When Relocations Are Performed.
DF_STATIC_TLS
-
Indicates that the object contains code using a static thread-local storage scheme. Static thread-local storage should not be used in objects that are dynamically loaded, either using dlopen(3C), or using lazy loading.
Name | Value | Meaning |
---|---|---|
DF_1_NOW | 0x1 | Perform complete relocation processing. |
DF_1_GLOBAL | 0x2 | Unused. |
DF_1_GROUP | 0x4 | Indicate object is a member of a group. |
DF_1_NODELETE | 0x8 | Object cannot be deleted from a process. |
DF_1_LOADFLTR | 0x10 | Ensure immediate loading of filtees. |
DF_1_INITFIRST | 0x20 | Objects' initialization occurs first. |
DF_1_NOOPEN | 0x40 | Object can not be used with dlopen(3C). |
DF_1_ORIGIN | 0x80 | $ORIGIN processing required. |
DF_1_DIRECT | 0x100 | Direct bindings enabled. |
DF_1_INTERPOSE | 0x400 | Object is an interposer. |
DF_1_NODEFLIB | 0x800 | Ignore the default library search path. |
DF_1_NODUMP | 0x1000 | Object cannot be dumped with dldump(3C). |
DF_1_CONFALT | 0x2000 | Object is a configuration alternative. |
DF_1_ENDFILTEE | 0x4000 | Filtee terminates filter's search. |
DF_1_DISPRELDNE | 0x8000 | Displacement relocation has been carried out. |
DF_1_DISPRELPND | 0x10000 | Displacement relocation pending. |
DF_1_NODIRECT | 0x20000 | Object contains non-direct bindings. |
DF_1_IGNMULDEF | 0x40000 | Internal use. |
DF_1_NOKSYMS | 0x80000 | Internal use. |
DF_1_NOHDR | 0x100000 | Internal use. |
DF_1_NORELOC | 0x400000 | Internal use. |
DF_1_GLOBAUDIT | 0x1000000 | Establish global auditing. |
-
DF_1_NOW
-
Indicates that all relocations for this object must be processed before returning control to the program. The presence of this flag takes precedence over a directive to use lazy binding when specified through the environment or by means of dlopen(3C). See When Relocations Are Performed.
DF_1_GROUP
-
Indicates that the object is a member of a group. This flag is recorded in the object using the link-editor's -B group option. SeeObject Hierarchies.
DF_1_NODELETE
-
Indicates that the object cannot be deleted from a process. If the object is loaded in a process, either directly or as a dependency, with dlopen(3C), the object cannot be unloaded with dlclose(3C). This flag is recorded in the object using the link-editor -z nodelete option.
DF_1_LOADFLTR
-
Meaningful only for filters. Indicates that all associated filtees be processed immediately. This flag is recorded in the object using the link-editor's -z loadfltr option. See Filtee Processing.
DF_1_INITFIRST
-
Indicates that this object's initialization section be run before any other objects loaded. This flag is intended for specialized system libraries only, and is recorded in the object using the link-editor's -z initfirst option.
DF_1_NOOPEN
-
Indicates that the object cannot be added to a running process with dlopen(3C). This flag is recorded in the object using the link-editor's -z nodlopen option.
DF_1_ORIGIN
-
Indicates that the object requires $ORIGIN processing. See Locating Associated Dependencies.
DF_1_DIRECT
-
Indicates that the object should use direct binding information. See Direct Bindings.
DF_1_INTERPOSE
-
Indicates that the objects symbol table is to interpose before all symbols except the primary load object, which is typically the executable. This flag is recorded with the link-editor's -z interpose option. See Runtime Interposition.
DF_1_NODEFLIB
-
Indicates that the search for dependencies of this object ignores any default library search paths. This flag is recorded in the object using the link-editor's -z nodefaultlib option. See Directories Searched by the Runtime Linker.
DF_1_NODUMP
-
Indicates that this object is not dumped by dldump(3C). Candidates for this option include objects with no relocations that might get included when generating alternative objects using crle(1). This flag is recorded in the object using the link-editor's -z nodumpoption.
DF_1_CONFALT
-
Identifies this object as a configuration alternative object generated by crle(1). This flag triggers the runtime linker to search for a configuration file $ORIGIN/ld.config.app-name.
DF_1_ENDFILTEE
-
Meaningful only for filtees. Terminates a filters search for any further filtees. This flag is recorded in the object using the link-editor's-z endfiltee option. See Reducing Filtee Searches.
DF_1_DISPRELDNE
-
Indicates that this object has displacement relocations applied. The displacement relocation records no longer exist within the object as the records were discarded once the relocation was applied. See Displacement Relocations.
DF_1_DISPRELPND
-
Indicates that this object has displacement relocations pending. The displacement relocations exits within the object so the relocation can be completed at runtime. See Displacement Relocations.
DF_1_NODIRECT
-
Indicates that this object contains symbols that can not be directly bound to. See Defining Additional Symbols with a mapfile.
DF_1_IGNMULDEF
-
Reserved for internal use by the kernel runtime-linker.
DF_1_NOKSYMS
-
Reserved for internal use by the kernel runtime-linker.
DF_1_NOHDR
-
Reserved for internal use by the kernel runtime-linker.
DF_1_NORELOC
-
Reserved for internal use by the kernel runtime-linker.
DF_1_GLOBAUDIT
-
Indicates that the dynamic executable requires global auditing. See Recording Global Auditors.
Name | Value | Meaning |
---|---|---|
DF_P1_LAZYLOAD | 0x1 | Identify lazy loaded dependency. |
DF_P1_GROUPPERM | 0x2 | Identify group dependency. |
-
DF_P1_LAZYLOAD
-
Identifies the following DT_NEEDED entry as an object to be lazy loaded. This flag is recorded in the object using the link-editor's -z lazyload option. See Lazy Loading of Dynamic Dependencies.
DF_P1_GROUPPERM
-
Identifies the following DT_NEEDED entry as an object to be loaded as a group. This flag is recorded in the object using the link-editor's -z groupperm option. See Isolating a Group.
Name | Value | Meaning |
---|---|---|
DTF_1_PARINIT | 0x1 | Partial initialization is required. |
DTF_1_CONFEXP | 0x2 | A Configuration file is expected. |
-
DTF_1_PARINIT
-
Indicates that the object requires partial initialization. See Move Section.
DTF_1_CONFEXP
-
Identifies this object as a configuration alternative object generated by crle(1). This flag triggers the runtime linker to search for a configuration file $ORIGIN/ld.config.app-name. This flag has the same affect as DF_1_CONFALT.
Global Offset Table (Processor-Specific)
Position-independent code cannot, in general, contain absolute virtual addresses. Global offset tables hold absolute addresses in private data. Addresses are therefore available without compromising the position-independence and shareability of a program's text. A program references its GOT using position-independent addressing and extracts absolute values. This technique redirects position-independent references to absolute locations.
Initially, the GOT holds information as required by its relocation entries. After the system creates memory segments for a loadable object file, the runtime linker processes the relocation entries. Some relocations can be of type R_xxxx_GLOB_DAT, referring to the GOT.
The runtime linker determines the associated symbol values, calculates their absolute addresses, and sets the appropriate memory table entries to the proper values. Although the absolute addresses are unknown when the link-editor creates an object file, the runtime linker knows the addresses of all memory segments and can thus calculate the absolute addresses of the symbols contained therein.
If a program requires direct access to the absolute address of a symbol, that symbol will have a GOT entry. Because the executable file and shared objects have separate a GOT, a symbol's address can appear in several tables. The runtime linker processes all the GOTrelocations before giving control to any code in the process image. This processing ensures that absolute addresses are available during execution.
The table's entry zero is reserved to hold the address of the dynamic structure, referenced with the symbol _DYNAMIC. This symbol enables a program, such as the runtime linker, to find its own dynamic structure without having yet processed its relocation entries. This method is especially important for the runtime linker, because it must initialize itself without relying on other programs to relocate its memory image.
The system can choose different memory segment addresses for the same shared object in different programs. The system can 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 GOT format and interpretation are processor-specific. The symbol _GLOBAL_OFFSET_TABLE_ can be used to access the table. This symbol can reside in the middle of the .got section, allowing both negative and nonnegative subscripts into the array of addresses. The symbol type is an array of Elf32_Addr for 32–bit code, and an array of Elf64_Addr for 64–bit code.
extern Elf32_Addr _GLOBAL_OFFSET_TABLE_[]; extern Elf64_Addr _GLOBAL_OFFSET_TABLE_[];
Procedure Linkage Table (Processor-Specific)
The global offset table converts position-independent address calculations to absolute locations. Similarly the procedure linkage table converts position-independent function calls to absolute locations. The link-editor cannot resolve execution transfers such as function calls between different dynamic objects. So, the link-editor arranges to have the program transfer control to entries in the procedure linkage table. The runtime linker thus redirects the entries without compromising the position-independence and shareability of the program's text. Executable files and shared object files have separate procedure linkage tables.
32-bit SPARC: Procedure Linkage Table
For 32–bit SPARC dynamic objects, the procedure linkage table resides in private data. The runtime linker determines the absolute addresses of the destinations and modifies the procedure linkage table's memory image accordingly.
The first four procedure linkage table entries are reserved. The original contents of these entries are unspecified, despite the example that is shown in Table 7–37. Each entry in the table occupies 3 words (12 bytes), and the last table entry is followed by a nop instruction.
A relocation table is associated with the procedure linkage table. The DT_JMP_REL entry in the _DYNAMIC array gives the location of the first relocation entry. The relocation table has one entry, in the same sequence, for each non-reserved procedure linkage table entry. The relocation type of each of these entries is R_SPARC_JMP_SLOT. The relocation offset specifies the address of the first byte of the associated procedure linkage table entry. The symbol table index refers to the appropriate symbol.
To illustrate procedure linkage tables, Table 7–37 shows four entries. Two of the four are initial reserved entries. The third entry is a call toname101. The fourth entry is a call to name102. The example assumes that the entry for name102 is the table's last entry. A nopinstruction follows this last entry. The left column shows the instructions from the object file before dynamic linking. The right column illustrates a possible instruction sequence that the runtime linker might use to fix the procedure linkage table entries.
Table 7–37 32-bit SPARC: Procedure Linkage Table ExampleThe following steps describe how the runtime linker and program jointly resolve the symbolic references through the procedure linkage table. The steps that are described are for explanation only. The precise execution-time behavior of the runtime linker is not specified.
-
When the memory image of the program is initially created, the runtime linker changes the initial procedure linkage table entries. These entries are modified so that control can be transferred to one of the runtime linker's own routines. The runtime linker also stores a word of identification information in the second entry. When the runtime linker receives control, this word is examined to identify the caller.
-
All other procedure linkage table entries initially transfer to the first entry. Thus, the runtime linker gains control at the first execution of a table entry. For example, the program calls name101, which transfers control to the label .PLT101.
-
The sethi instruction computes the distance between the current and the initial procedure linkage table entries, .PLT101 and.PLT0, respectively. This value occupies the most significant 22 bits of the %g1 register.
-
Next, the ba,a instruction jumps to .PLT0, establishing a stack frame, and calls the runtime linker.
-
With the identification value, the runtime linker gets its data structures for the object, including the relocation table.
-
By shifting the %g1 value and dividing by the size of the procedure linkage table entries, the runtime linker calculates the index of the relocation entry for name101. Relocation entry 101 has type R_SPARC_JMP_SLOT. This relocation offset specifies the address of.PLT101, and its symbol table index refers to name101. Thus, the runtime linker gets the symbol's real value, unwinds the stack, modifies the procedure linkage table entry, and transfers control to the desired destination.
The runtime linker does not have to create the instruction sequences under the memory segment column. If the runtime linkers does, some points deserve more explanation.
-
To make the code re-entrant, the procedure linkage table's instructions are changed in a particular sequence. If the runtime linker is fixing a function's procedure linkage table entry and a signal arrives, the signal handling code must be able to call the original function with predictable and correct results.
-
The runtime linker changes three words to convert an entry. The runtime linker can update only a single word atomically with regard to instruction execution. Therefore, re-entrancy is achieved by updating each word in reverse order. If a re-entrant function call occurs just prior to the last patch, the runtime linker gains control a second time. Although both invocations of the runtime linker modify the same procedure linkage table entry, their changes do not interfere with each other.
-
The first sethi instruction of a procedure linkage table entry can fill the delay slot of the previous entry's jmp1 instruction. Although the sethi changes the value of the %g1 register, the previous contents can be safely discarded.
-
After conversion, the last procedure linkage table entry, .PLT102, needs a delay instruction for its jmp1. The required, trailing nopfills this delay slot.
Note –
The different instruction sequences that are shown for .PLT101, and .PLT102 demonstrate how the update can be optimized for the associated destination.
The LD_BIND_NOW environment variable changes dynamic linking behavior. If its value is non-null, the runtime linker processesR_SPARC_JMP_SLOT relocation entries before transferring control to the program.
64-bit SPARC: Procedure Linkage Table
For 64–bit SPARC dynamic objects, the procedure linkage table resides in private data. The runtime linker determines the absolute addresses of the destination and modifies the procedure linkage table's memory image accordingly.
The first four procedure linkage table entries are reserved. The original contents of these entries are unspecified, despite the example that is shown in Table 7–38. Each of the first 32,768 entries in the table occupies 8 words (32 bytes), and must be aligned on a 32–byte boundary. The table as a whole must be aligned on a 256–byte boundary. If more than 32,768 entries are required, the remaining entries consist of 6 words (24 bytes) and 1 pointer (8 bytes). The instructions are collected together in blocks of 160 entries followed by 160 pointers. The last group of entries and pointers can contain less than 160 items. No padding is required.
Note –
The numbers 32,768 and 160 are based on the limits of branch and load displacements respectively with the second rounded down to make the divisions between code and data fall on 256–byte boundaries so as to improve cache performance.
A relocation table is associated with the procedure linkage table. The DT_JMP_REL entry in the _DYNAMIC array gives the location of the first relocation entry. The relocation table has one entry, in the same sequence, for each non-reserved procedure linkage table entry. The relocation type of each of these entries is R_SPARC_JMP_SLOT. For the first 32,767 slots, the relocation offset specifies the address of the first byte of the associated procedure linkage table entry, the addend field is zero. The symbol table index refers to the appropriate symbol. For slots 32,768 and beyond, the relocation offset specifies the address of the first byte of the associated pointer. The addend field is the unrelocated value -(.PLTN + 4). The symbol table index refers to the appropriate symbol.
To illustrate procedure linkage tables, Table 7–38 shows several entries. The first three show initial reserved entries. The following three show examples of the initial 32,768 entries together with possible resolved forms that might apply if the target address was +/- 2 Gbytes of the entry, within the lower 4 Gbytes of the address space, or anywhere respectively. The final two show examples of later entries, which consist of instruction and pointer pairs. The left column shows the instructions from the object file before dynamic linking. The right column demonstrates a possible instruction sequence that the runtime linker might use to fix the procedure linkage table entries.
Table 7–38 64-bit SPARC: Procedure Linkage Table ExampleThe following steps describe how the runtime linker and program jointly resolve the symbolic references through the procedure linkage table. The steps that are described are for explanation only. The precise execution-time behavior of the runtime linker is not specified.
-
When the memory image of the program is initially created, the runtime linker changes the initial procedure linkage table entries. These entries are modified so that control is transfer to the runtime linker's own routines. The runtime linker also stores an extended word of identification information in the third entry. When the runtime linker receives control, this word is examined to identify the caller.
-
All other procedure linkage table entries initially transfer to the first or second entry. These entries establish a stack frame and call the runtime linker.
-
With the identification value, the runtime linker gets its data structures for the object, including the relocation table.
-
The runtime linker computes the index of the relocation entry for the table slot.
-
With the index information, the runtime linker gets the symbol's real value, unwinds the stack, modifies the procedure linkage table entry, and transfers control to the desired destination.
The runtime linker does not have to create the instruction sequences under the memory segment column. If the runtime linker does, some points deserve more explanation.
-
To make the code re-entrant, the procedure linkage table's instructions are changed in a particular sequence. If the runtime linker is fixing a function's procedure linkage table entry and a signal arrives, the signal handling code must be able to call the original function with predictable and correct results.
-
The runtime linker can change up to eight words to convert an entry. The runtime linker can update only a single word atomically with regard to instruction execution. Therefore, re-entrancy is achieved by first overwriting the nop instructions with their replacement instructions, and then patching the ba,a, and the sethi if using a 64–bit store. If a re-entrant function call occurs just prior to the last patch, the runtime linker gains control a second time. Although both invocations of the runtime linker modify the same procedure linkage table entry, their changes do not interfere with each other.
-
If the initial sethi instruction is changed, the instruction can only be replaced by a nop.
Changing the pointer as done for the second form of entry is done using a single atomic 64–bit store.
Note –
The different instruction sequences that are shown for .PLT101, .PLT102, and .PLT103 demonstrate how the update can be optimized for the associated destination.
The LD_BIND_NOW environment variable changes dynamic linking behavior. If its value is non-null, the runtime linker processesR_SPARC_JMP_SLOT relocation entries before transferring control to the program.
32-bit x86: Procedure Linkage Table
For 32–bit x86 dynamic objects, the procedure linkage table resides in shared text but uses addresses in the private global offset table. The runtime linker determines the absolute addresses of the destinations and modifies the global offset table's memory image accordingly. The runtime linker thus redirects the entries without compromising the position-independence and shareability of the program's text. Executable files and shared object files have separate procedure linkage tables.
Table 7–39 32-bit x86: Absolute Procedure Linkage Table Example .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 |
.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 preceding examples show, the procedure linkage table instructions use different operand addressing modes for absolute code and for position-independent code. Nonetheless, their interfaces to the runtime linker are the same.
The following steps describe how the runtime linker and program cooperate to resolve the symbolic references through the procedure linkage table and the global offset table.
-
When the memory image of the program is initially created, the runtime linker sets the second and third entries in the global offset table to special values. The following steps explain these values.
-
If the procedure linkage table is position-independent, the address of the global offset table must be in %ebx. Each shared object file in the process image has its own procedure linkage table, and control transfers to a procedure linkage table entry only from within the same object file. So, the calling function must set the global offset table base register before calling the procedure linkage table entry.
-
For example, the program calls name1, which transfers control to the label .PLT1.
-
The first instruction jumps to the address in the global offset table entry for name1. Initially, the global offset table holds the address of the following pushl instruction, not the real address of name1.
-
The program pushes a relocation offset (offset) on the stack. The relocation offset is a 32–bit, nonnegative byte offset into the relocation table. The designated relocation entry has the type R_386_JMP_SLOT, and its offset specifies the global offset table entry used in the previous jmp instruction. The relocation entry also contains a symbol table index, which the runtime linker uses to get the referenced symbol, name1.
-
After pushing the relocation offset, the program jumps to .PLT0, the first entry in the procedure linkage table. The pushl instruction pushes the value of the second global offset table entry (got_plus_4 or 4(%ebx)) on the stack, giving the runtime linker one word of identifying information. The program then jumps to the address in the third global offset table entry (got_plus_8 or 8(%ebx)), to jump to the runtime linker.
-
The runtime linker unwinds the stack, checks the designated relocation entry, gets the symbol's value, stores the actual address ofname1 in its global offset entry table, and jumps to the destination.
-
Subsequent executions of the procedure linkage table entry transfer directly to name1, without calling the runtime linker again. Thejmp instruction at .PLT1 jumps to name1 instead of falling through to the pushl instruction.
The LD_BIND_NOW environment variable changes dynamic linking behavior. If its value is non-null, the runtime linker processesR_386_JMP_SLOT relocation entries before transferring control to the program.
x64: Procedure Linkage Table
For x64 dynamic objects, the procedure linkage table resides in shared text but uses addresses in the private global offset table. The runtime linker determines the absolute addresses of the destinations and modifies the global offset table's memory image accordingly. The runtime linker thus redirects the entries without compromising the position-independence and shareability of the program's text. Executable files and shared object files have separate procedure linkage tables.
Table 7–41 x64: Procedure Linkage Table ExampleThe following steps describe how the runtime linker and program cooperate to resolve the symbolic references through the procedure linkage table and the global offset table.
-
When the memory image of the program is initially created, the runtime linker sets the second and third entries in the global offset table to special values. The following steps explain these values.
-
Each shared object file in the process image has its own procedure linkage table, and control transfers to a procedure linkage table entry only from within the same object file.
-
For example, the program calls name1, which transfers control to the label .PLT1.
-
The first instruction jumps to the address in the global offset table entry for name1. Initially, the global offset table holds the address of the following pushq instruction, not the real address of name1.
-
The program pushes a relocation index (index1) on the stack. The relocation offset is a 32–bit, nonnegative index into the relocation table. The relocation table is identified by the DT_JUMPREL dynamic section entry. The designated relocation entry has the typeR_AMD64_JMP_SLOT, and its offset specifies the global offset table entry used in the previous jmp instruction. The relocation entry also contains a symbol table index, which the runtime linker uses to get the referenced symbol, name1.
-
After pushing the relocation index, the program jumps to .PLT0, the first entry in the procedure linkage table. The pushq instruction pushes the value of the second global offset table entry (GOT+8) on the stack, giving the runtime linker one word of identifying information. The program then jumps to the address in the third global offset table entry (GOT+16), to jump to the runtime linker.
-
The runtime linker unwinds the stack, checks the designated relocation entry, gets the symbol's value, stores the actual address ofname1 in its global offset entry table, and jumps to the destination.
-
Subsequent executions of the procedure linkage table entry transfer directly to name1, without calling the runtime linker again. Thejmp instruction at .PLT1 jumps to name1 instead of falling through to the pushq instruction.
The LD_BIND_NOW environment variable changes dynamic linking behavior. If its value is non-null, the runtime linker processesR_AMD64_JMP_SLOT relocation entries before transferring control to the program.