[llvm-bugs] [Bug 42442] New: LLD lets a weak reference replace a strong reference in some cases with dynamic libraries.
via llvm-bugs
llvm-bugs at lists.llvm.org
Fri Jun 28 16:43:13 PDT 2019
https://bugs.llvm.org/show_bug.cgi?id=42442
Bug ID: 42442
Summary: LLD lets a weak reference replace a strong reference
in some cases with dynamic libraries.
Product: lld
Version: unspecified
Hardware: PC
OS: Linux
Status: NEW
Severity: normal
Priority: P
Component: ELF
Assignee: unassignedbugs at nondot.org
Reporter: bmoses at google.com
CC: llvm-bugs at lists.llvm.org, peter.smith at linaro.org
Consider the following case: We have a function, bar(), provided by libbar.so.
Our main program (foo.o) has a strong reference to bar. We also have a second
shared library, libbaz.so, which has a weak reference to bar.
If we call "lld foo.o libbar.so", we get a strong reference to bar in the
resulting binary, as expected.
However, if we append libbaz.so to the end of that command line, the resulting
binary now has a weak reference to bar. This is clearly wrong; the code in
foo.o still requires bar to exist, and if the dynamic loader treats it as a
weak symbols and allows it to be unresolved at runtime, it will break. This
should still produce a strong reference.
For reference, this came up originally in the context of bootstrapping Go with
lld, as https://github.com/golang/go/issues/31912.
-------------------------
Sample code:
$ cat foo.c
// A program with a strong reference to bar()
int bar();
int main() { return bar(); }
$ cat bar.c
// A strong definition of bar().
int bar() { return 23; }
$ cat baz.c
// An unused function with a weak reference to bar()
int __attribute__((weak)) bar();
int baz() { return bar ? bar() : 0; }
$ gcc foo.c -c -o foo.o
$ gcc bar.c -shared -o libbar.so
$ gcc baz.c -shared -o libbaz.so
First, to confirm foo.o has a strong reference:
$ readelf -s foo.o | grep bar
10: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND bar
If we link without libbaz.so, we retain a strong reference, as expected:
$ ld.lld foo.o libbar.so -o foo1
ld.lld: warning: cannot find entry symbol _start; defaulting to 0x201000
$ readelf --dyn-sym foo1 | grep bar
1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND bar
However, if we append libbaz.so to the end of the command line, it's a weak
reference:
$ ld.lld foo.o libbar.so libbaz.so -o foo2
ld.lld: warning: cannot find entry symbol _start; defaulting to 0x201000
$ readelf --dyn-sym foo2 | grep bar
1: 0000000000000000 0 FUNC WEAK DEFAULT UND bar
Interestingly, swapping libbaz.so and libbar.so on the command line gets us
back to a strong reference:
$ ld.lld foo.o libbar.so libbaz.so -o foo3
ld.lld: warning: cannot find entry symbol _start; defaulting to 0x201000
$ readelf --dyn-sym foo3 | grep bar
1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND bar
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20190628/211ea6c4/attachment-0001.html>
More information about the llvm-bugs
mailing list