[PATCH] [ELF] Fix undefined symbol handling in DSO.

Rui Ueyama ruiu at google.com
Fri Apr 18 14:48:27 PDT 2014


Joerg,

Any comments on this?


On Mon, Apr 7, 2014 at 12:46 PM, Rui Ueyama <ruiu at google.com> wrote:

> On Mon, Apr 7, 2014 at 12:27 PM, Joerg Sonnenberger <
> joerg at britannica.bec.de> wrote:
>
>> On Mon, Apr 07, 2014 at 12:07:20PM -0700, Rui Ueyama wrote:
>> > On Mon, Apr 7, 2014 at 3:32 AM, Joerg Sonnenberger
>> > <joerg at britannica.bec.de>wrote:
>> >
>> > > On Sun, Apr 06, 2014 at 09:58:13PM -0700, Rui Ueyama wrote:
>> > > > Currently LLD ignores undefined symbols found in DSOs when linking
>> > > against
>> > > > DSO files, if -shared flag is given. Internally, it's achieved by
>> > > enabling
>> > > > "useShlibUndefines" flag, which makes the file reader to ignore all
>> > > undefined
>> > > > symbols in DSO, so that Resolver don't see any undefined symbols
>> when
>> > > > handling DSO files.
>> > >
>> > > I don't think your patch fixes the real issue. The correct behavior
>> > > is:
>> > >
>> > > (1) If the undefined symbol comes from an object file (or archive
>> > > library), it is a true undefined symbol. In this case, the behavior
>> > > depends on (a) -z defs (b) the output type. For shared libraries,
>> > > undefined symbols are by default not fatal, for executables, they are.
>> > >
>> >
>> > That's I believe already implemetned correctly. Please take a look at
>> > GnuLdDriver.cpp:295.
>> >
>> >  (2) Undefined symbols in shared libraries pulled in via -l are ignored.
>> > >
>> >
>> > By "ignored", I'd think you mean "undefined symbol from library is not
>> > fatal", right?
>>
>> No, I really meant ignored. The most you can or should do about them is
>> check for consistency of the type. Otherwise they are completely
>> irrelevant. Trying to resolve them is just going to waste time.
>
>
> That's different from my experiment. I reached the conclusion that GNU LD
> tries to resolve undefined symbols in library files by the following test
> case:
>
>   foo.c:
>   extern int bar();
>   int foo() { return bar(); }
>
>   bar.c:
>   int bar() { return 0; }
>
>   baz.c:
>   int baz() { return 0; }
>
>   usefoo.c:
>   extern int foo();
>   int usefoo() { return foo(); }
>
>   Makefile:
>   CFLAGS=-fPIC
>   all: libfoo.so libbar.so libbaz.so libusefoo.so
>   lib%.so: %.o
>           $(CC) -shared -o $@ $< -Wl,-rpath,`pwd`,--soname,$@
>   libusefoo.so: usefoo.o
>           $(CC) -shared -o $@ $< -Wl,-rpath,`pwd`,--soname,$@ -L`pwd`
> -lfoo -lbar -lbaz
>
> libfoo.so has undefined symbol "bar", but usefoo.o doesn't. If "bar" in
> libfoo.so is ignored, -lbar will not be linked to libusefoo.so, because at
> the time when linker processes "-lbar" there's no remaining undefined
> symbols. Reality is libusefoo.so has both "NEEDED libfoo.so" and "NEEDED
> libbar.so" (but not "NEEDED libbaz.so"). My interpretation of this result
> is that the linker tries to resolve undefined symbols in a library file.
>
> > (3) For ELF, shared libraries are processed recursively.
>> >
>> > Are you talking about runtime behavior? Could you elaborate a bit?
>>
>> No, link time behavior. GNU folks decided to break this in recent
>> versions, but ELF has a recursive namespace and the linker should
>> implement that. A simple case is linking against OpenSSL's libssl. That
>> one is linked against libcrypto. For that reason, adding -lssl does
>> add the symbols from libcrypto.so as well. Searching is controlled by
>> the combination of libssl.so's rpath and the -rpath-link flags.
>>
>> Joerg
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140418/f4c2c22a/attachment.html>


More information about the llvm-commits mailing list