I am sponsoring the following self-reviewed case for myself. It makes the following user visible changes:
- Solaris ELF objects will henceforth set the e_ident[EI_OSABI] field of the ELF header to ELFOSABI_SOLARIS, instead of the historical value of ELFOSABI_NONE. - elfdump will get a new -O option to allow the user to specify the ELF operating system ABI to use when interpreting the file. For reasons discussed in detail below, the EI_OSABI field of the ELF header is not used by the link-editor, runtime linker, or operating system kernel to affect how it is used by the system. As such, tagging our object as ELFOSABI_SOLARIS is purely documentation, of value to tools such elfdump that are used to examine them, and for compliance with the ELF standard. This change will not alter the runtime behavior of the operating system. ----- Release Binding: Patch/Micro ELF OSABI tagging Committed elfdump -O option Committed ----------------------------------------------------------------------------- The longevity of the ELF standard is largely due to the fact that it was designed to be extended. Operating systems are able to add new features in a controlled and backward compatible manner. However, the original version of the ELF standard, as designed by AT&T, and implemented in Solaris 2.0, did not tackle the question of how different operating systems can do this without suffering from namespace collisions with each other. A few years later, representatives from the various Unix vendors gathered to work out these details (Mike Walker represented Sun). The numeric ranges of ELF constants (representing program header types, section types, and so forth) were partitioned into three separate ranges: Generic: Core ELF features, common to all ELF implementations OS: Operating system specific features, unique to each operating system (at least at first --- good ideas often cross pollinate). This is called the Operating System ABI (OSABI). The OSABI of a given object is recorded in the EI_OSABI field of the ELF header e_ident array --- a byte array of 16 characters that is found at offset 0 of the file. (The ELF magic number is found in e_ident[0:3]). Platform: Hardware specific features. The platform ABI for a given ELF object is identified by the e_machine field of the ELF header. These specifics are defined by the platform ABI. The e_machine field already existed, but the gABI group needed to create a place to record the OSABI. The original ELF specification had defined the ELF e_ident[] array to have 16 bytes, but only the first 7 (indexes 0-6) were used. The remaining 9 bytes were always set to 0. The gABI group decided to use two of these bytes: #define EI_OSABI 7 /* Operating system/ABI identification */ #define EI_ABIVERSION 8 /* ABI version */ Given a self identifying object (via e_ident[EI_OSABI]), and a specific range for OS extensions, different ELF based operating systems are free to evolve, in theory without conflict. Unfortunately for this theory, the OSABI addition to ELF was not an original feature, but one that was added later. All operating systems that existed prior to that change had existing objects in the field with e_ident[EI_OSABI] set to 0 (ELFOSABI_NONE). The ELF standard says that ELFOSABI_NONE objects only use the generic part of the ELF standard. However, for backward compatibility with their own objects, the OS vendors have always applied a somewhat different interpretation. The real world definition of an ELFOSABI_NONE object is that it is a native object that doesn't self identify itself --- all OSABI features are supported, and will work if used. Given the fact that ELFOSABI_NONE in the real world means "native" and not "generic", OS vendors did not move to set the EI_OSABI for their objects. Solaris and Linux both still set this field to ELFOSABI_NONE, even though it is a rare object for either system that does not use an operating system specific ELF feature. This mostly works: - People know that a given object is for a given system because they built it for that system. In a heterogeneous networked environment, things can sometimes get confused, but normally there's little issue. - The ELF community has tried very hard to give their extensions unique non-colliding values. For example, when Linux added symbol versioning, they did it in a manner compatible with Solaris, using the same numeric ELF values to represent the same items. Similarly, we try to track their changes. However, as with any "best effort" solution, there are issues: - I have recently discovered that best efforts notwithstanding, the Solaris and Linux systems have diverged incompatibly: Value Solaris Linux ---------------------------------------------------------------- 0x6ffffff5 SHT_SUNW_cap SHT_GNU_ATTRIBUTES 0x6ffffff6 SHT_SUNW_SIGNATURE SHT_GNU_HASH 0x6ffffff7 SHT_SUNW_ANNOTATE SHT_GNU_LIBLIST 0x6ffffff8 SHT_SUNW_DEBUGSTR SHT_CHECKSUM - When tools like elfdump try to display a non-Solaris object, they will use Solaris names for the items. This looks strange when the names in question represent the same concept. It is simply wrong when they don't. Consider this elfdump output from an Ubuntu Linux executable: Section Header[4]: sh_name: .gnu.hash sh_addr: 0x400320 sh_flags: [ SHF_ALLOC ] sh_size: 0x40 sh_type: [ SHT_SUNW_SIGNATURE ] sh_offset: 0x320 sh_entsize: 0 sh_link: 5 sh_info: 0 sh_addralign: 0x8 It has been apparent for some time that we should be marking our objects as ELFOSABI_SOLARIS. The divergence between Solaris and Linux underscores the fact that even when there is no conflict, there is no reason not to properly identify our objects. This must be a "documentation only" change: Although we will tag our objects as ELFOSABI_SOLARIS, the link-editor, runtime linker, and OS kernel will never be free of the requirement that ELFOSABI_NONE objects must be treated as ELFOSABI_SOLARIS. There is therefore no reason for any of these components to read e_ident[EI_OSABI], or alter their behavior based on its value. ----- The elfdump program has been modified to take the OSABI of the objects it displays into account. When an object identifies as non-Solaris OSABI, elfdump will display the proper strings for that OSABI if it knows them. For example, it will display a Linux versym section type as 'SHT_GNU_versym' instead of 'SHT_SUNW_versym'. If it does not have knowledge of the specified OSABI, it will present such information in numeric form, rather than mapping to Solaris names inappropriately. This ability will enhance elfdump's value when we examine non-Solaris objects (something linker developers do regularly). Since most ELF objects do not properly identify their OSABI, elfdump will receive a new command line option, '-O osabi', allowing the user to tell it which OSABI to apply. The elfdump(1) manpage will document this feature as follows: OPTIONS The following options are supported: ... -O osabi Specifies the Operating System ABI to apply when interpreting the object. osabi can be the name or value of any of the ELFOSABI_ constants found in <sys/elf.h>. For convenience, the ELFOSABI_ prefix may be omitted from these names. If -O is not specified, and the object does not specify an OSABI in the ELF header, the Solaris ABI will be used. Two osabi values are fully supported: 'solaris' is the native OSABI of the Solaris operating system. 'none' is a fully generic ELF ABI --- all values outside the generic range are displayed numerically. Support for other OSABIs may be incomplete or missing. In all cases, elfdump will display items for which strings are unavailable in numeric form.