|
Description
|
Our handling of the GNU style of symbol versioning is in need of
some refinement. The current implementation is sufficient for
the moment, but misses a few details that may cause problems for us
going forward if not addressed.
The GNU linkers use the same DT_ codes and versioning structure definitions
as we do. This is a good thing, as it allows for significant interoperability
with files produced by the GNU toolchain (gcc, GNU ld). However, their
implementation of versioning differs in some important ways from ours:
- The top bit of the 16-bit Versym index is not part of the version,
but is interpreted as a "hidden bit", indicating a symbol that should
be ignored by the linkers.
- External (SHN_UNDEF) symbols can have non-zero Versym values, which
specify versions in referenced objects, via the Verneed section.
- The vna_other field of the Vernaux structures found in the Verneed
section are not zero as with Solaris, but instead contain the version
index to be used by Versym indices to reference the given external version.
- They use the '@' character in symbol names to indicate that a symbol belongs
to a specific version. Assembler pseudo ops are used to generate these
symbols.
A previous attempt to improve our handling of these files was made in
6516665 The link-editors should be more resilient against gcc's symbol versioning)
That fix solved part of the problem, but it has also triggered a different
problem (6548144, 6565476, 6569636, which are duplicates). The reasons for
this are:
- ELF objects are not marked as using "Solaris versioning" or "GNU versioning",
so our fix to 6516665 relied on a generic test for symbol versions being out
of range. Without a definative way to identify a file as following the GNU
rules, the generic test was the best we could do.
- The GNU style of versioning assigns version indexes to external (UNDEF) symbols,
making use of the vna_other field of the Vernaux structures, as mentioned
above. Solaris versioning does not do this, and our fix for 6516665 did not
take it into account. This caused valid (under GNU versioning, but not Solaris)
symbol version indexes to be flagged as being out of range.
I now have the answer to how to definatively identify a file that uses GNU
versioning rules: The runtime linker needs access to the data in the objects
Versym section in order to do GNU versioning. Solaris versioning does not need
this. Therefore, a file that uses GNU versioning rules will have a DT_VERSYM
dynamic section element. The Solaris linker never issues DT_VERSYM. Therefore,
we can interpret the presence of DT_VERSYM as explicitly identifying a file
that uses the GNU versioning style.
Our solution to 6516665 needs to be modified to take this information into
account:
- DT_VERSYM should be used to properly identify which style of versioning
is used by a given object.
- When handling a file that uses GNU versioning, we need to properly
understand the external version indexes defined in the Verneed section.
|