SPRAB89A September 2011 – March 2014
GNU symbol versioning allows a user to specify a version name for a symbol exported from a DSO. This allows more than one version of the same symbol definition in a DSO. Exactly one of them is marked the default. When linked against this symbol definition, the default version is always used to bind the symbol references.
For example, assume a library implementer defines an API function api_do_encode in codec_1_0.dso. Initially there is only one version, say VER1. When an application links against this DSO, all the references to api_do_encode are resolved by VER1 of api_do_encode. Later the implementer enhances the API by adding an updated, but incompatible, version of api_do_encode, but still wants to support previously built applications using the older API. The implementer can create a new codec_2_0.dso with both the original VER1 api_do_encode and a new VER2 definition of the same symbol, which now becomes the designated default version. When a new application links against codec_2_0.dso, references to api_do_encode are resolved by VER2 api_do_encode. The original VER1 api_do_encode is still available to satisfy references from older applications built against codec_1_0.dso.
Please refer to Drepper's paper for details on the mechanics to specify the symbol versions.
GNU symbol versioning information is recorded in the three ELF sections:
This section defines version names associated with symbols exported from this executable file. The version of the file is also defined in this section.
This section can be located via the DT_VERDEF tag entry in the dynamic section. The tag DT_VERDEFNUM contains the number of version definitions this section contains. The version definition section has the section type SHT_TI_verdef. Note that this section type value 0x6FFFFFFD is the same as SHT_GNU_verdef. This specification recommends the name .gnu.version_d for this section. However, only the section type should be used to identify this section; the name should not be used.
This section records the versions needed by undefined symbols references in this executable file. Each entry names a DSO and points to a list of versions needed from it. When the dynamic linker loads an executable, it will find and load all the DSOs needed. Before making such DSOs public, the dynamic linker will first check if the version needed by the executable is satisfied by this DSO's version definitions. This version needed information is recorded by the static linker when it binds references to definitions from DSOs.
This section extends the dynamic symbol table by adding the version number to the dynamic symbol entries. This section contains the same number of entries as the dynamic symbol table. The symbol id is used to index this table of version numbers. If the symbol is undefined, the version number matches a version needed entry in the version needed section. If the symbol is defined, the version number matches a version definition entry in the version definition section. The version definition is default when bit 15 is clear.
ELF provides a mechanism to locate and identify these symbol version sections in an ELF executable. These sections are located by the dynamic tags from the dynamic section and are identified using special section types.
For example, the version definition section is located by the dynamic tag DT_VERDEF. The DT_VERDEFNUM tag contains the number of version definitions in the version definition section. This section shall have the section type SHT_GNU_verdef (0x6FFFFFFD). The name of this section is nominally .gnu.version_d, but implementations should rely on the section type rather than the name.