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.

Reply via email to