64-bit ELF Object File Specification

Draft Version 2.5
MIPS Technologies / Silicon Graphics Computer Systems
Caveat: This document is Draft 2.5. It is incomplete and subject to change. In particular, lists of constants, sections, and attributes may be incomplete or inaccurate in detail. Reference to the header files elf.h and sys/elf.h is recommended before reliance on the information herein.

Section 1: Introduction

This document specifies the format of MIPS object files for 64-bit code. We assume as a basis the documents [ABI32], [ABI32M], and [ABI64]. In addition, Silicon Graphics uses the DWARF debugging information format as specified in [DWARF]. Information in those documents should be considered valid unless contradicted here.

The remainder of this section summarizes our objectives, approach, and open issues. Section 2 corresponds to ABI Section 4, describing ELF-64 object files, and Section 3 corresponds to ABI Section 5, describing program loading and dynamic linking. Section 4 describes the 64-bit archive file format (from MIPS ABI Section 7), though it is not technically part of ELF.

1.1 Objectives

The objectives of this format definition fall in two categories. The first is simply to extend the base 32-bit ELF format, by increasing field sizes where appropriate, so that there will be no problems dealing with very large 64-bit programs. The second is to extend the kinds of information included in the object file to facilitate new features.

  1. Remove 32-bit constraints on object file sizes.
  2. Support checking and potential conversion of subprogram call interfaces.
  3. Support efficient and reliable application of performance monitoring tools like pixie and object code optimization tools like cord.
  4. Support efficient and reliable debugging facilities.

1.2 Approach

We start from the basis of the System V ABI and the MIPS symbol table format, extending them in the obvious ways to support very large objects. We will then add additional information (generally new sections) to support the extended objectives described above. We generally recognize three levels of support:

  1. Some information is required for all ABI-compliant object files.
  2. Some information is optional, but its absence will prevent use of system functionality, e.g. cache optimization reordering, etc.
  3. Some information is entirely optional; its absence interferes only with functionality unrelated to program construction, e.g. debugging, performance measurement, etc.

To clarify the distinction between these levels, we have defined a new section header flag, SHF_MIPS_NOSTRIP, which is applied to sections in the first two levels. The intent is that a strip(1) tool or its equivalent should never remove these sections by default, and should warn the user if their removal is explicitly requested.

We have followed a number of principles and assumptions in this specification:

  1. Sections expected to be used by runtime facilities, e.g. stack traceback, have the SHF_ALLOC attribute. Such sections also have symbols automatically generated by the linker which may be used to reference them in code. This allows simple virtual addressing in the process address space for any required access.
  2. Sections are NOT given the SHF_WRITE attribute simply because rld may need to relocate their contents. We assume that rld can request write access and change it back if necessary, and prefer this approach for a more robust runtime environment.
  3. We require that the executable code for a single executable or DSO will never be larger than 256MB, and that it will never be loaded across a 256MB boundary. This requirement allows various beneficial assumptions about valid addressing code within an executable/DSO, and also allows the use of single-word addresses (to be interpreted relative to the containing 4GB address range) for code in an object file.

1.3 Conventions

In all of the tables in this document, unshaded information is that derived directly from external documents (i.e. the generic ABI and the DWARF specification), lightly shaded information is derived directly from 32-bit MIPS specifications (ELF, header files), and heavily shaded information is new or substantially changed from these existing formats.

We use the usual wording to describe requirements, distinguishing between must (mandatory), should (recommended), and may (allowed).

1.4 Open Issues

Unresolved issues and missing information are marked in this document. The most significant ones at this time are:

  1. Should there be a distinct EK_PBEGIN event in case a program unit does not begin with an entrypoint (Section 2.10)?
  2. Should memory events be segregated to a distinct events section so that tools which use the default events and those which use the memory events aren't impacted by the other data (Section 2.10)?

Section 2: ELF-64 Object File Format

The ELF-64 object file format is based on the document [ABI64]. The relevant declarations are contained in the header file /usr/include/elf.h. (Note that /usr/include/sys/elf.h is logically part of /usr/include/elf.h, and is the actual location of most of these declarations.)

We call attention to the [ABI32] requirement that all data structures be naturally aligned in the file (see p. 4-3). This implies that all headers, sections, and other major components must be 8-byte aligned, with padding if necessary to accomplish this. Although 4-byte alignment is probably adequate currently for ELF-32, 8-byte alignment should also be used there to avoid future extension problems.

2.1 Infrastructure

ELF-64 is defined in terms of the types in Table 1:

Table 1: ELF-64 Data Types
Name Size Alignment Purpose
Elf64_Addr 8 8 Unsigned program address
Elf64_Half 2 2 Unsigned small integer
Elf64_Off 8 8 Unsigned file offset
Elf64_Sword 4 4 Signed medium integer
Elf64_Sxword 8 8 Signed large integer
Elf64_Word 4 4 Unsigned medium integer
Elf64_Xword 8 8 Unsigned large integer
Elf64_Byte 1 1 Unsigned tiny integer
Elf64_Section 2 2 Section index (unsigned)

There are places in ELF-64 files where fundamental data types must be encoded, for instance in subprogram interface descriptors. We generally use the constants in Table 2 to identify them, based on DWARF version 1 (but not identical).

Table 2: Fundamental Data Types
Name(s) Value Comments
FT_unknown 0x0000 unknown type
FT_signed_char 0x0001 8-bit signed character
FT_unsigned_char 0x0002 8-bit unsigned character
FT_signed_short 0x0003 16-bit signed short integer
FT_unsigned_short 0x0004 16-bit unsigned short integer
FT_signed_int32 0x0005 32-bit signed integer
FT_unsigned_int32 0x0006 32-bit unsigned integer
FT_signed_int64 0x0007 64-bit signed integer
FT_unsigned_int64 0x0008 64-bit unsigned integer
FT_pointer32 0x0009 32-bit pointer
FT_pointer64 0x000a 64-bit pointer
FT_float32 0x000b 32-bit floating point (IEEE)
FT_float64 0x000c 64-bit floating point (IEEE)
FT_float128 0x000d 128-bit floating point
FT_complex64 0x000e 64-bit complex floating point
FT_complex128 0x000f 128-bit complex floating point
FT_complex256 0x0010 256-bit complex floating point
FT_void 0x0011 void

2.2 ELF-64 Header

The header format is as defined in [ABI64]; it is reproduced here for reference purposes.

Table 4: ELF-64 Header Structure
Field Name Type Comments
e_ident[EI_NIDENT] unsigned char See Table 5
e_type Elf64_Half See [ABI32]
e_machine Elf64_Half Machine (EM_MIPS = 8)
e_version Elf64_Word File format version
e_entry Elf64_Addr Process entry address
e_phoff Elf64_Off Program header table file offset
e_shoff Elf64_Off Section header table file offset
e_flags Elf64_Word Flags — see Table 6
e_ehsize Elf64_Half ELF header size (bytes)
e_phentsize Elf64_Half Program header entry size
e_phnum Elf64_Half Number of program headers
e_shentsize Elf64_Half Section header entry size
e_shnum Elf64_Half Number of section headers
e_shstrndx Elf64_Half Section name string table section header index

The structure of the e_ident field is given by Table 5.

Table 5: ELF-64 Header: e_ident[] Contents
Offset Name Index Value or Interpretation
EI_MAG0-3 0-3 Magic string: 0x7f, 'E', 'L', 'F'
EI_CLASS 4 Class of format: ELFCLASS64 = 2
EI_DATA 5 Endianness: ELFDATAMSB = 2
EI_VERSION 6 Version of format: EV_CURRENT = 1
EI_PAD 7-15 Reserved, must be zero

2.3 ELF-64 Section Header

The section header format is as defined in [ABI64]; it is reproduced here for reference purposes.

Table 7: Section Header Structure (Elf64_Shdr)
Name Type Description
sh_name Elf64_Word Section name (index into section header string table section)
sh_type Elf64_Word Section type: see Table 8
sh_flags Elf64_Xword Section flags: see Table 9
sh_addr Elf64_Addr Address of first byte, or zero
sh_offset Elf64_Off File offset of section
sh_size Elf64_Xword Section's size in bytes
sh_link Elf64_Word Table index link: section-specific
sh_info Elf64_Word Extra information: section-specific
sh_addralign Elf64_Xword Address alignment constraint
sh_entsize Elf64_Xword Size of fixed-size entries in section, or zero

2.5 Symbol Table

A symbol table section is unchanged from [ABI32] except for the types of some of its fields.

A symbol table section and its associated string table section must be present for any executable file with DSO dependencies, or for any DSO. It is permissible to remove from it symbols resolved within itself if they are not preemptible (protected) and not visible outside this object.

Table 11: ELF-64 Symbol Table Structure
Name Type Comments
st_name Elf64_Word Name's index into string table
st_info Elf64_Byte Symbol type and binding: see Table 12 and Table 13
st_other Elf64_Byte Other info: see Table 14
st_shndx Elf64_Section Index of section where defined
st_value Elf64_Addr Symbol value
st_size Elf64_Xword Symbol size

The high-order nibble of the st_info field specifies the symbol's binding (see Table 12), and the low-order nibble specifies its type (see Table 13).

Table 12: Symbol Binding (ELF32_ST_BIND)
Constant Name Value Comments
STB_LOCAL 0 Not visible outside object file where defined
STB_GLOBAL 1 Visible to all object files. Multiple definitions cause errors.
STB_WEAK 2 Visible to all object files. Ignored if STB_GLOBAL with same name found.
STB_LOPROC 13 First processor-specific binding
STB_SPLIT_COMMON 13 Split common symbol
STB_HIPROC 15 Last processor-specific binding
Table 13: Symbol Type (ELF32_ST_TYPE)
Constant Name Value Comments
STT_NOTYPE 0 Not specified
STT_OBJECT 1 Data object: variable, array, etc.
STT_FUNC 2 Function or other executable code
STT_SECTION 3 Section. Exists primarily for relocation
STT_FILE 4 Name (pathname?) of the source file
STT_LOPROC 13 First processor-specific type
STT_HIPROC 15 Last processor-specific type

2.9 Relocation

Any section may have an associated SHT_REL and/or SHT_RELA section, containing relocation operations for objects in the section.

Table 29: Relocation Operation (Elf64_Rel, Elf64_Rela)
Field Name Type Comments
r_offset Elf64_Addr Where to apply relocation
r_sym Elf64_Word Symbol index
r_ssym Elf64_Byte Special symbol
r_type3 Elf64_Byte Relocation type
r_type2 Elf64_Byte Relocation type
r_type Elf64_Byte Relocation type
r_addend Elf64_Sxword Explicit addend (Elf64_Rela only)
The MIPS relocation model allows composing multiple relocation operations in sequence, with each operation taking the result of the previous one as its addend. This powerful mechanism enables complex address calculations without requiring numerous distinct relocation types.

Section 3: Program Linking and Loading

This section deals with aspects of the object file format specific to executable and DSO files (which we refer to collectively as program files), and with the processing required by the static linker ld(1) and the dynamic linker rld(1).

3.1 Linker (ld) Requirements

This section is obviously not an exhaustive list; it is intended to collect miscellaneous requirements which are not traditional and not obviously implied by the format description.

The intent of some of these requirements, along with the specification of most of the sections described above as having the SHF_ALLOC attribute by default, is to allow a program (or another process monitoring it at runtime, like a debugger) to access the information in its program file by simple references to its address space, rather than requiring that it explicitly read the program file.

3.1.1 Headers

The ELF header, program header table, and section header table will be allocated, i.e. they will be treated like sections with the SHF_ALLOC flag set. Although they are considered optional by [ABI32], section headers will be present in a MIPS ABI-compliant program file and may not be stripped.

3.2 Program Header

The program header of an executable/DSO file consists of an array of descriptors, one per loadable segment plus a few extras. The structure (from [ABI64]) is as follows:

Table 40: Elf64_Phdr Structure
Field Name Type Description
p_type Elf64_Word Segment descriptor type
p_flags Elf64_Word Flags for segment
p_offset Elf64_Off File offset of segment
p_vaddr Elf64_Addr Virtual start address
p_paddr Elf64_Addr Physical start address
p_filesz Elf64_Xword Byte size in file (may be zero)
p_memsz Elf64_Xword Byte size in memory (may be zero)
p_align Elf64_Xword Required alignment

3.3 Dynamic Linking

This section discusses the data structures and issues relevant to dynamic linking.

3.3.1 Dynamic Section

The .dynamic section, which must be identified by a PT_DYNAMIC segment descriptor for any executable or DSO with DSO dependencies, consists of a table of pairs with the following structure:

Table 43: Dynamic Structure (Elf64_Dyn)
Field Name Field Type Description
d_tag Elf64_Xword Kind
d_un union of:
d_val Elf64_Xword Kind-dependent value
d_ptr Elf64_Addr Kind-dependent address

3.5 The Global Offset Table

The organization of the GOT generally follows that of [ABI32M]. It is essentially a table of addresses, 64 bits each. We summarize it here primarily for completeness.

The GOT itself is located by the DT_PLTGOT dynamic tag. It is logically two tables. The first (with DT_MIPS_LOCAL_GOTNO entries) consists of local GOT addresses, i.e. non-preemptible (protected) addresses defined within the executable/DSO. They are initialized to their quickstart values, and must be relocated if and only if the DSO is loaded at a different address than that given by its DT_MIPS_BASE_ADDRESS dynamic tag.

The second part of the GOT is the global GOT addresses, i.e. those which are undefined or preemptible. Each entry in this part has an associated symbol entry in the .dynsym section. Those symbols start at the symbol table index given by the DT_MIPS_GOTSYM dynamic tag, and are in the same order as the global GOT entries.

Section 4: Archive File Format

The archive file (i.e. ar(4) format) may be used to collect arbitrary files; we are concerned here with the specific case where those files are ELF object files. This format is based on the System V ABI [ABI32]; in particular, the magic string and member header format are unchanged.

Unlike the COFF archive format, we do not generate an archive hash table, since the IRIX 6.0 linker (ld) does not use it.

The linker (ld) will work more efficiently when component object files (not their file headers) are 8-byte aligned. Generating tools (especially the compilers) are encouraged to arrange this by padding them, i.e. by increasing the length of the component files to a multiple of 8 bytes.

4.1 Basic File Format

An object file archive consists of the following sequence of components. In general, each must start on a 2-byte boundary, and is padded with a newline if necessary to make it even length. Its ar_size in its header, however, does not include the padding byte.

The remaining components are all preceded with a member header as specified by [ELF32].

4.2 Archive Symbol Table Components

We define below two symbol table component formats. These are the current 32-bit ABI format and an analogous 64-bit form for 64-bit ELF object files.

Bibliography

[ABI32] AT&T, SYSTEM V APPLICATION BINARY INTERFACE, 1990, Unix Press (Prentice-Hall).
[ABI32M] AT&T, SYSTEM V APPLICATION BINARY INTERFACE MIPS Processor Supplement, 1991, Unix Press (Prentice-Hall).
[ABI64] SPARC International, SYSTEM V APPLICATION BINARY INTERFACE Generic 64-Bit Extensions, March 7, 1992, Delta Document 1.20 (Draft).
[DWARF] Unix International, Programming Languages SIG, DWARF Debugging Information Format, Version 2, Revision 2.0.0 (July 27, 1993).