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

Rui Ueyama ruiu at google.com
Mon Apr 7 12:46:21 PDT 2014


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/20140407/882a1e5d/attachment.html>


More information about the llvm-commits mailing list