Bug#998687: lld: --no-allow-shlib-undefined: Doesn't check recursively

Sylvestre Ledru sylvestre at debian.org
Sat Nov 6 14:31:46 GMT 2021


Hello

I think you should report this issue upstream directly.

It doesn't seem to be a packaging bug.

Thanks

Sylvestre


Le 06/11/2021 à 14:00, Alejandro Colomar a écrit :
> Package: lld
> Version: 1:13.0-53~exp1
> Severity: normal
> Tags: upstream
> X-Debbugs-Cc: alx.manpages at gmail.com, Michael Kerrisk (man-pages) <mtk.manpages at gmail.com>, Diego Elio Pettenò <flameeyes at flameeyes.com>, 997999 at bugs.debian.org
>
> Dear Maintainer,
>
> A week ago I detected a bug in ld.gold, where it differs from ld.bfd:
> <https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=997999>.
>
> In the meantime, I've known about ld.lld, and wondered its behavior
> regarding --no-allow-shlib-undefined.  After some experiment, it's
> the same buggy behavior that ld.gold has, and differs from ld.bfd.
>
> I would expect --no-allow-shlib-undefined to search recursively through
> all of my dependencies and check if any of them has undefined symbols,
> and report an error if so.  ld.bfd has that behavior.
>
> Instead, ld.lld (and ld.gold) only check that my direct dependencies
> have their symbols resolved, but they do not check the dependencies
> of my dependencies.
>
> That creates the possibility that an unmet dependency will cause a run-time
> error, as I show in the example below.
>
> Commands to reproduce the bug:
>
> $ ll
> total 20
> -rw-r--r-- 1 user user 29 Oct 28 11:47 bar.c
> -rw-r--r-- 1 user user 60 Oct 28 13:47 foobar.c
> -rw-r--r-- 1 user user 83 Oct 28 11:46 foo.c
> -rw-r--r-- 1 user user 52 Oct 28 13:47 foovar.c
> -rw-r--r-- 1 user user 56 Oct 28 13:31 main.c
> $ 
> $ cat bar.c
> 	int bar(void)
> 	{
> 		return 1;
> 	}
> $ cat foo.c
> 	int bar(void);
>
> 	int foo(void)
> 	{
> 		return 1;
> 	}
>
> 	int foo_bar(void)
> 	{
> 		return bar();
> 	}
> $ cat foobar.c
> 	int foo_bar(void);
>
> 	int foobar(void)
> 	{
> 		return foo_bar();
> 	}
> $ cat foovar.c
> 	int foo(void);
>
> 	int foobar(void)
> 	{
> 		return foo();
> 	}
> $ cat main.c
> 	int foobar(void);
>
> 	int main(void)
> 	{
> 		return foobar();
> 	}
> $ 
> $ cc -c -fpic -Wall -Wextra -Werror main.c foo.c bar.c foobar.c foovar.c
> $ 
> $ cc -shared -Wl,--no-undefined -Wl,--no-allow-shlib-undefined -Wl,--as-needed -Wl,--no-copy-dt-needed-entries -o libbar.so bar.o -fuse-ld=bfd
> $ cc -shared -Wl,--no-undefined -Wl,--no-allow-shlib-undefined -Wl,--as-needed -Wl,--no-copy-dt-needed-entries -o libbar.so bar.o -fuse-ld=gold
> $ 
> $ cc -shared -Wl,--no-undefined -Wl,--no-allow-shlib-undefined -Wl,--as-needed -Wl,--no-copy-dt-needed-entries -o libfoo.so foo.o -fuse-ld=bfd
> /usr/bin/ld.bfd: foo.o: in function `foo_bar':
> foo.c:(.text+0x10): undefined reference to `bar'
> collect2: error: ld returned 1 exit status
> $ cc -shared -Wl,--no-undefined -Wl,--no-allow-shlib-undefined -Wl,--as-needed -Wl,--no-copy-dt-needed-entries -o libfoo.so foo.o -fuse-ld=gold
> foo.o:foo.c:function foo_bar: error: undefined reference to 'bar'
> collect2: error: ld returned 1 exit status
> $ 
> $ cc -shared -Wl,--no-allow-shlib-undefined -Wl,--as-needed -Wl,--no-copy-dt-needed-entries -o libfoo.so foo.o -fuse-ld=bfd
> $ cc -shared -Wl,--no-allow-shlib-undefined -Wl,--as-needed -Wl,--no-copy-dt-needed-entries -o libfoo.so foo.o -fuse-ld=gold
> $ 
> $ cc -shared -Wl,--no-undefined -Wl,--no-allow-shlib-undefined -Wl,--as-needed -Wl,--no-copy-dt-needed-entries -o libfoobar.so foobar.o -L. -lfoo -fuse-ld=bfd
> /usr/bin/ld.bfd: ./libfoo.so: undefined reference to `bar'
> collect2: error: ld returned 1 exit status
> $ cc -shared -Wl,--no-undefined -Wl,--no-allow-shlib-undefined -Wl,--as-needed -Wl,--no-copy-dt-needed-entries -o libfoobar.so foobar.o -L. -lfoo -fuse-ld=gold
> ./libfoo.so: error: undefined reference to 'bar'
> collect2: error: ld returned 1 exit status
> $ 
> $ cc -shared -Wl,--no-undefined -Wl,--as-needed -Wl,--no-copy-dt-needed-entries -o libfoobar.so foobar.o -L. -lfoo -fuse-ld=bfd
> $ cc -shared -Wl,--no-undefined -Wl,--as-needed -Wl,--no-copy-dt-needed-entries -o libfoobar.so foobar.o -L. -lfoo -fuse-ld=gold
> $ 
> $ cc -shared -Wl,--no-undefined -Wl,--no-allow-shlib-undefined -Wl,--as-needed -Wl,--no-copy-dt-needed-entries -o libfoovar.so foovar.o -L. -lfoo -fuse-ld=bfd
> /usr/bin/ld.bfd: ./libfoo.so: undefined reference to `bar'
> collect2: error: ld returned 1 exit status
> $ cc -shared -Wl,--no-undefined -Wl,--no-allow-shlib-undefined -Wl,--as-needed -Wl,--no-copy-dt-needed-entries -o libfoovar.so foovar.o -L. -lfoo -fuse-ld=gold
> ./libfoo.so: error: undefined reference to 'bar'
> collect2: error: ld returned 1 exit status
> $ 
> $ cc -shared -Wl,--no-undefined -Wl,--as-needed -Wl,--no-copy-dt-needed-entries -o libfoovar.so foovar.o -L. -lfoo -fuse-ld=bfd
> $ cc -shared -Wl,--no-undefined -Wl,--as-needed -Wl,--no-copy-dt-needed-entries -o libfoovar.so foovar.o -L. -lfoo -fuse-ld=gold
> $
> $ # NOTE: bfd and gold behave differently here!
> $ # gold will produce a buggy binary!!
> $ cc -Wl,--no-undefined -Wl,--no-allow-shlib-undefined -Wl,--as-needed -Wl,--no-copy-dt-needed-entries -o foobar -Wl,-rpath=. main.o -L. -lfoobar -fuse-ld=bfd
> /usr/bin/ld.bfd: ./libfoo.so: undefined reference to `bar'
> collect2: error: ld returned 1 exit status
> $ cc -Wl,--no-undefined -Wl,--no-allow-shlib-undefined -Wl,--as-needed -Wl,--no-copy-dt-needed-entries -o foobar -Wl,-rpath=. main.o -L. -lfoobar -fuse-ld=gold
> $ 
> $ LD_LIBRARY_PATH=. ./foobar 
> ./foobar: symbol lookup error: ./libfoo.so: undefined symbol: bar
> $ 
> $ # NOTE: bfd and gold behave differently here!
> $ # gold will produce a binary that luckily works here,
> $ # but might break inadvertently if a future libfoovar starts using foo_bar()!
> $ cc -Wl,--no-undefined -Wl,--no-allow-shlib-undefined -Wl,--as-needed -Wl,--no-copy-dt-needed-entries -o foovar -Wl,-rpath=. main.o -L. -lfoovar -fuse-ld=bfd
> /usr/bin/ld.bfd: ./libfoo.so: undefined reference to `bar'
> collect2: error: ld returned 1 exit status
> $ cc -Wl,--no-undefined -Wl,--no-allow-shlib-undefined -Wl,--as-needed -Wl,--no-copy-dt-needed-entries -o foovar -Wl,-rpath=. main.o -L. -lfoovar -fuse-ld=gold
> $ 
> $ LD_LIBRARY_PATH=. ./foovar
> $ 
>
> -- System Information:
> Debian Release: bookworm/sid
>   APT prefers unstable
>   APT policy: (500, 'unstable'), (1, 'experimental')
> Architecture: amd64 (x86_64)
>
> Kernel: Linux 5.14.0-3-amd64 (SMP w/12 CPU threads)
> Kernel taint flags: TAINT_OOT_MODULE, TAINT_UNSIGNED_MODULE
> Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE=en_US:en
> Shell: /bin/sh linked to /usr/bin/dash
> Init: systemd (via /run/systemd/system)
> LSM: AppArmor: enabled
>
> Versions of packages lld depends on:
> ii  lld-13  1:13.0.0-9~exp1
>
> lld recommends no packages.
>
> lld suggests no packages.
>
> -- no debconf information
> _______________________________________________
> Pkg-llvm-team mailing list
> Pkg-llvm-team at alioth-lists.debian.net
> https://alioth-lists.debian.net/cgi-bin/mailman/listinfo/pkg-llvm-team



More information about the Pkg-llvm-team mailing list