This document is a specification for the ELF-based Embedded Application Binary Interface (EABI) for the C6000 family of processors from Texas Instruments. The EABI is a broad standard that defines the low-level interface between programs, program components, and the execution environment, including the operating system if one is present. Components of the EABI include calling conventions, data layout and addressing conventions, object file formats, and dynamic linking mechanisms.
This specification aims to enable tool providers, software providers, and users of the C6000 to build tools and programs that can interoperate with each other.
Prior to release 7.0 of TI's C6000 Compiler Tools in 2009, the one and only ABI for C6000 was the original COFF-based ABI. It was strictly a bare-metal ABI; there was no execution-level component, and although various systems implement aspects of dynamic linking, there was no standardization or tools support for such mechanisms.
Release 7.0 of the TI Compiler Tools introduced a new ABI called the C6000 EABI. It is based on the ELF object file format, and includes support for dynamic linking and position independence. It is derived from industry standard models, including the IA-64 C++ ABI and the System V ABI for ELF and Dynamic Linking. The processor-specific aspects of the ABI, such as data layout and calling conventions, are largely unchanged from the COFF ABI, although there are some differences. Needless to say, the COFF ABI and the EABI are incompatible; that is to say, all of the code in a given system must follow the same ABI. TI's compiler tools support both the new EABI and the older COFF ABI, although we encourage migration to the new ABI as support for the COFF ABI may be discontinued in the future.
A platform is the software environment upon which a program runs. The ABI has platform-specific aspects, particularly in the area of conventions related to the execution environment, such as the number and use of program segments, addressing conventions, visibility conventions, pre-emption, dynamic linking, program loading, and initialization. Currently there are two supported platforms: bare metal and Linux. The term bare metal represents the absence of any specific environment. That is not to say there cannot be an OS; it simply says that there are no OS-specific ABI specifications. In other words, how the program is loaded and run, and how it interacts with other parts of the system, is not covered by the bare-metal ABI.
The bare-metal ABI allows substantial variability in many specific aspects. For example, an implementation may provide position independence (PIC), but if a given system does not require position independence, these conventions do not apply. Because of this variability, programs may still be ABI-conforming but incompatible; for example if one program uses PIC but the other does not, they cannot interoperate. Toolchains should endeavor to enforce such incompatibilities.
The Linux ABI augments the bare-metal ABI by narrowing its variability and detailing additional requirements, so that a program or subprogram can run under a Linux-based OS on the C6000.
Figure 1-1 shows the components of the ABI and their relationship. We will briefly describe the components, beginning with the lower part of the diagram and moving upward, and provide references to the appropriate chapter of this ABI specification.
The components in the bottom area relate to object-level interoperability.
The C Language ABI (Chapter 2, Chapter 3, Chapter 4, Chapter 5, Chapter 8 and Chapter 9) specifies function calling conventions, data type representations, addressing conventions, and the interface to the C run-time library.
The C++ ABI (Chapter 10) specifies how the C++ language is implemented; this includes details about virtual function tables, name mangling, how constructors are called, and the exception handling mechanism (Chapter 11). The C6000 C++ ABI is based on the prevalent IA-64 (Itanium) C++ ABI.
The DWARF component (Chapter 12) specifies the representation of object-level debug information. The base standard is the DWARF3 standard. This specification details processor-specific extensions.
The ELF component (Chapter 13) specifies the representation of object files. This specification extends the System V ABI specification with processor specific information.
Build Attributes (Chapter 17) refer to a means of encoding into an object file various parameters that affect inter-object compatibility, such as target device assumptions, memory models, or ABI variants. Toolchains can use build attributes to prevent incompatible object files from being combined or loaded.
The components in the central area of the diagram relate to execution-time interoperability. The dynamic linking components (Chapter 6 and Section 14.4) specify a mechanism whereby separately linked modules can interoperate, including the sharing of their code. Part of the dynamic linking mechanism is a method for data addressing such that separately linked modules can address each other's data without relocation.
Thread-Local Storage (Chapter 7) allows for the creation of thread-specific variables with static storage duration. The specification, representation, and access of thread-local variables is described in this document.
Symbol versioning (Chapter 16) is a mechanism whereby symbolic references include a minimum version, such that they are dynamically resolved with definitions having at least that version, in order to prevent run-time incompatibilities. This ABI adopts the standard GCC/Linux model, with no changes.
The components in the top part of Figure 1-1 augment the ABI with platform-specific conventions that define the requirements for executables to be compatible with an execution environment, such as the number and use of program segments, addressing conventions, visibility conventions, pre-emption, program loading, and initialization. Bare-Metal refers to the absence of any specific environment. The only other environment currently covered by the ABI is the Linux platform (Chapter 15).
Finally, there is a set of specifications that are not formally part of the ABI but are documented here both for reference and so that other toolchains can optionally implement them.
Initialization (Chapter 18) refers to the mechanism whereby initialized variables obtain their initial value. Nominally these variables reside in the .data section and they are initialized directly when the .data section is loaded, requiring no additional participation from the tools. However the TI toolchain supports a mechanism whereby the .data section is encoded into the object file in compressed form, and decompressed at startup time. This is a special use of a general mechanism that programmatically copies compressed code or data from offline storage (e.g. ROM) to its execution address. We refer to this facility as copy tables. While not part of the ABI, the initialization and copy table mechanism is documented here so that other toolchains can support it if desired.
Program Header Attributes (Chapter 19) are an extension to ELF implemented by the TI toolchain in order to represent various additional properties of ELF segments beyond what is specified by the base ELF standard. The TI tools use them to encode memory connectivity/latency requirements, protection, cache behavior, and other system-specific properties. They are designed to be flexible and extensible. Again, we document them here so that other tools can interoperate with them if needed.