This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Some fun questions about symbol versioning


(1) In the LSB 5.0 spec, Section 10.7, it states that the indexes in
the symbol version table (.gnu.version) should be a value that matches
an entry in one of the other two version sections:

"All other values are used to identify version strings located in one
of the other Symbol Version sections. The value itself is not the
version associated with the symbol. The string identified by the value
defines the version of the symbol."

It's only in the .gnu.version_r section where it talks about setting
the VERSYM_HIDDEN bit:

"vna_other: Object file version identifier used in the .gnu.version
symbol version array. Bit number 15 controls whether or not the object
is hidden; if this bit is set, the object cannot be used and the
static linker will ignore the symbol's presence in the object."

But that makes little sense, and doesn't match readelf or either
linker (or libc.so, I presume without having looked). In practice, we
set the VERSYM_HIDDEN bit in the .gnu.version section entries, and not
in either the vd_ndx field of the .gnu.version_d section or the
vna_other field of the .gnu.version_r section.

Is it safe to assume that this part of the LSB is bogus? Is there any
better documentation for symbol versioning anywhere?

(2) What are the rules for when a version can be added to the
.gnu.version_d table, vs. when the linker should complain about "No
symbol version section for versioned symbol"? I have a test case with
a version script that defines a version used by an undef, but not
linked against a shared library that defines that symbol/version. Gold
happily links it, but Gnu ld complains. This is adapted from the repro
given in PR 16504, removing -flto from the picture:

$ cat libb.c
void new_sd_get_seats(void);
__asm__(".symver new_sd_get_seats,sd_get_seats@LIBSYSTEMD_209");
static void (*resolve_sd_get_seats(void)) (void) {
        return new_sd_get_seats;
}
void sd_get_seats(void) __attribute__((ifunc("resolve_sd_get_seats")));

$ cat libb.sym
LIBSYSTEMD_209 {
};
LIBSYSTEMD_208 {
global:
        sd_get_seats;
};

$ gcc -c -fPIC libb.c

$ ld.gold -shared -o libb.so --version-script libb.sym libb.o  ## works

$ ld.gnu -shared -o libb.so --version-script libb.sym libb.o  ## fails
ld.gnu: a.out: No symbol version section for versioned symbol
`sd_get_seats@LIBSYSTEMD_209'
ld.gnu: final link failed: Nonrepresentable section on output

Is gold wrong to produce an output here? Why? If not, is Gnu ld wrong
to complain?

If I remove the definition of LIBSYSTEMD_209 from the version script,
I get an error from both linkers.

If I add liba.so to the command line (which defines
sd_get_seats@@LIBSYSTEMD_209), both linkers work.

$ cat liba.c
const char* sd_get_seats(void) {return "bla bla";}

$ cat liba.sym
LIBSYSTEMD_209 {
global:
        sd_get_seats;
};

$ gcc -c -fPIC liba.c

$ ld.gold -shared -o liba.so --version-script liba.sym liba.o

$ ld.gold -shared -o libb.so --version-script libb.sym libb.o liba.so  ## works

$ ld.gnu -shared -o libb.so --version-script libb.sym libb.o liba.so  ## works

(This is the case where gold was setting the VERSYM_HIDDEN bit on the
UNDEF for sd_get_seats@LIBSYSTEMD_209, which prompted me to propose a
patch to readelf to handle that until I realized that gold probably
shouldn't be setting the bit for UNDEFs.)

(3) The LSB only makes a fleeting mention of the VER_FLG_WEAK flag. In
the test case above, with liba.so on the command line, Gnu ld sets the
WEAK flag in the .gnu.version_d section for LIBSYSTEMD_209, but gold
does not. What are the rules?

(4) If I turn on -flto, I find that the GCC plugin isn't handing me
the version information, so gold ends up with an internal error due to
an unexpected clash between the two versions. But I need to straighten
this other stuff out before I can get to that problem. I haven't yet
decided whether gold should issue a clean error message or just try to
make it work. I suspect that in more complicated situations, something
nasty could happen if the symbols we get during the claim file phase
don't match the ones we get in the replacement phase.

-cary


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]