| Summary: | Shared library version script gives warnings from rtld | ||
|---|---|---|---|
| Product: | Base System | Reporter: | mikko <mikko> |
| Component: | bin | Assignee: | John Polstra <jdp> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | 4.0-CURRENT | ||
| Hardware: | Any | ||
| OS: | Any | ||
Responsible Changed From-To: freebsd-bugs->jb John is an ELF guru. John, if I'm treading on your toes here, please feel free to say so. :-) FWIW: It works w/o warnings on linux, using the same compiler and
almost the same linker.
m% uname -a ; ld -v; cc --version
Linux m.dynas.se 2.2.5-15 #1 Mon Apr 19 22:21:09 EDT 1999 i586 unknown
GNU ld version 2.9.1 (with BFD 2.9.1.0.23)
egcs-2.91.66
/Mikko
Responsible Changed From-To: jb->jdp John points out that John Polstra should have been the man I chose to bug. :-) Sheldon, On Mon, 30 Aug 1999, Sheldon Hearn wrote: > Could you test for the existance of the problem you reported on PR 12849 > when next you ``make world'' and install an updated kernel? I see John's > done a little work in this area recently. Short answer: Nope. Long answer: I still haven't found an ELF spec anywhere on the net, but looking at the GNU ld documentation & code, I think I know what is going on: The 0x6ffffffx tags are invented by Sun, adopted by GNU, and are used for the version stuff (as described by the "version script"). The purpose of the version symbols is to allow the dynamic linker to check that a library contains the version(s) that the program needs directly when the library is loaded, rather than during symbol lookup, which may be deferred with RTLD_LAZY. (This is the way it works on Solaris) A quick workaround would be to define the symbols needed (see contrib/binutils/include/elf/common.h), so rtld can at least silently ignore them. As far as I can tell (the GNU ld code is a bit messy) rtld does not actually have to apply any logic to the symbol bindings, so ignoring the version information would just revert to the normal error messages about undefined symbols if the library is incompatible, though maybe not at load time. As it is right now, version scripts are unusable on FreeBSD (I don't really need versions per se -- I just need to limit the exposed API), which means I cannot provide the products we are working on for FreeBSD, unless we do some kind of hack :( Regards, /Mikko Mikko Tyo"la"ja"rvi________________________________mikko@securitydynamics.com SecurityDynamics Mikko Työläjärvi wrote: > A quick workaround would be to define the symbols needed (see > contrib/binutils/include/elf/common.h), so rtld can at least > silently ignore them. I don't mind eliminating the warning. I could put it inside an "#ifdef DEBUG" so that it's still available to developers working on the dynamic linker. That would solve your problem, correct? Please let me know. I can commit that simple change to -current and -stable immediately. > As far as I can tell (the GNU ld code is a bit messy) The pope is a bit of a Catholic. The Pacific Ocean has a bit of water in it. The sun is a bit warm. ;-) > rtld does not actually have to apply any logic to the symbol > bindings, so ignoring the version information would just revert to > the normal error messages about undefined symbols if the library > is incompatible, though maybe not at load time. I haven't really looked into the symbol versioning feature yet, but your statement sounds sensible to me. > As it is right now, version scripts are unusable on FreeBSD (I > don't really need versions per se -- I just need to limit the > exposed API), which means I cannot provide the products we are > working on for FreeBSD, unless we do some kind of hack :( For a hack to limit the exposed API, look at some of the options for "objcopy". It has features to hide specified symbols. If you decide to use it, though, be forewarned that Poul-Henning Kamp found what appears to be a bug in objcopy. He supplied me with this patch, which apparently makes it work right: Index: objcopy.c =================================================================== RCS file: /home/ncvs/src/contrib/binutils/binutils/objcopy.c,v retrieving revision 1.1.1.2 diff -u -r1.1.1.2 objcopy.c --- objcopy.c 1998/09/06 22:56:57 1.1.1.2 +++ objcopy.c 1999/07/04 23:56:24 @@ -544,6 +544,8 @@ && (discard_locals != locals_start_L || ! bfd_is_local_label (abfd, sym)))); + if (strip_symbols == strip_all) + keep = 0; if (keep && is_specified_symbol (name, strip_specific_list)) keep = 0; if (!keep && is_specified_symbol (name, keep_specific_list)) @@ -779,7 +781,7 @@ /* Symbol filtering must happen after the output sections have been created, but before their contents are set. */ - if (strip_symbols == strip_all) + if (strip_symbols == strip_all && keep_specific_list == NULL) { osympp = isympp = NULL; symcount = 0; John --- John Polstra jdp@polstra.com John D. Polstra & Co., Inc. Seattle, Washington USA "No matter how cynical I get, I just can't keep up." -- Nora Ephron State Changed From-To: open->closed Fixed in "src/libexec/rtld-elf/rtld.c" revison 1.38. I used your suggested work-around and simply disabled the warnings. Since this was such a simple change, I will ask the release engineer for permission to merge it into the upcoming 3.3-RELEASE as well. I'll investigate the possibility of actually supporting symbol versioning in the future. Thanks very much for the excellent test case you provided. That was a real time-saver! |
When creating shared libs using version scripts (the --version-script flag to "ld"), I get warning messages on stdout, presumably from "rtld-elf", about unsupported "d_tag". The purpose of using the version script is to limit the number of externally visible symbols in the lib, but even an almost empty version script gives this result. The offending tags seem to be in the range (in hex) 6FFFFFF[0-F] I have no idea whether the problem lies with rtld or ld, or simply is a user error. Programs seem to run ok, though. For example: LD_LIBRARY_PATH=. ./program Ignored d_tag 1879048190 Ignored d_tag 1879048191 Ignored d_tag 1879048176 Ignored d_tag 1879048188 Ignored d_tag 1879048189 Ignored d_tag 1879048176 In main ... Fix: Ask an ELF guru...? How-To-Repeat: Put this makefile in an otherwise empty directory, and run make. That should produce a minimal shared lib and a minimal program linked against it, as well as run the program to show the diagnostics. "make clean; make NOVERSION=yes" repeats the operation, but without the version script and without diagnostics from rtld. ---8<--Makefile -------------------------------------------------------------- .ifndef NOVERSION LD_FLAGS = -Wl,--version-script=version .endif CFLAGS = -fpic OTHERLIBS = -lc program: program.o $(CC) -o $@ $? -L. -lxxx LD_LIBRARY_PATH=. ./program program: libxxx.so program.c: mkfunc.sh sh mkfunc.sh main entry > $@ libxxx.so: libxxx.so.1 ln -sf $? $@ libxxx.so.1: f.o version cc -shared -o $@ -Wl,-soname,$@ f.o $(LD_FLAGS) $(OTHERLIBS) f.c: mkfunc.sh sh mkfunc.sh entry > $@ version: echo 'V_1.0 { global: entry; local: *; };' > $@ mkfunc.sh: (echo 'echo -n "int $$1() { puts(\"In $$1\");"; shift;';\ echo 'for i in $$*; do echo -n "$$i();"; done';\ echo 'echo "return 0; }";'; ) > mkfunc.sh clean: rm -f *.c *.o *.a *.so *.so.? program version mkfunc.sh *.core ---8<----------------------------------------------------------------------