Open Quuxplusone opened 6 years ago
Bugzilla Link | PR35841 |
Status | NEW |
Importance | P normal |
Reported by | Bjorn Pagen (bjornpagen@gmail.com) |
Reported on | 2018-01-05 20:39:37 -0800 |
Last modified on | 2020-03-26 12:33:30 -0700 |
Version | trunk |
Hardware | All Linux |
CC | dmajor@bugmail.cc, llvm-bugs@lists.llvm.org, ndesaulniers@google.com, peter@pcc.me.uk, rafael@espindo.la, rnk@google.com, ruiu@google.com, samitolvanen@google.com, srhines@google.com |
Fixed by commit(s) | |
Attachments | |
Blocks | |
Blocked by | |
See also |
To create this error, I compiled musl using a musl/lld/clang/compiler_rt, and
assigned these variables:
CC=clang
CXX=clang++
CFLAGS="-O2 -pipe -flto"
LDFLAGS="-Wl,-O2 -Wl,--as-needed"
AR="llvm-ar"
NM="llvm-nm"
RANLIB="llvm-ranlib"
Musl compiled flawlessly with these variables:
CC=clang
CXX=clang++
CFLAGS="-O2 -pipe"
LDFLAGS=""
AR="llvm-ar"
NM="llvm-nm"
RANLIB="llvm-ranlib"
I could reproduce the issue.
The symbol "__dls2" is referenced only by the following macro that is expanded
to an inline assembly. I believe because of that, LTO doesn't recognize that
the symbol needs to be kept.
#define GETFUNCSYM(fp, sym, got) __asm__ ( \
".hidden " #sym "\n" \
" lea " #sym "(%%rip),%0\n" \
: "=r"(*fp) : : "memory" )
Not sure what is the right way to fix the issue. CCing pcc as he know a lot
more than me about LTO.
The problem is indeed that we currently don't attempt to parse inline asm
(except for module-level inline asm) when building a symbol table for an LTO
object file.
This may be something that we could conceivably do with some effort now that we
support creating LTO symbol tables (basically, we would copy all of a module's
inline asm calls into a function in a second module, replace all non-constant
arguments with undef and codegen the second module with a RecordStreamer to
track the symbol references). There's probably some reason why that wouldn't
work that I haven't thought of, though.
I don't quite understand why musl needs to take the address of a function like
that, but assuming that it is necessary, it looks like you can work around the
problem by adding a module-level asm reference to the symbol.
diff --git a/ldso/dlstart.c b/ldso/dlstart.c
index 4dbe1784..3cb3170a 100644
--- a/ldso/dlstart.c
+++ b/ldso/dlstart.c
@@ -17,6 +17,8 @@
*(fp) = static_func_ptr; } while(0)
#endif
+__asm__(".globl __dls2");
+
__attribute__((__visibility__("hidden")))
void _dlstart_c(size_t *sp, size_t *dynv)
{
Moving the bug and it is something that should be fixed in llvm so that there is an undefined symbol in the bitcode file symbol table.
(In reply to David Major from comment #5)
> Is this the same as bug 35197 and/or bug 35290?
Not sure. Those are MS inline asms, and we do some extra magic for those.
Rui and/or Peter - any thoughts about how complex this would be to fix in LLVM. This bug affects the Linux kernel, so we would like to eventually be able to revert some workarounds when using LLD to link it.