https://llvm.org/bugs/show_bug.cgi?id=30432
Bug ID: 30432 Summary: [Rust][MUSL] duplicate symbol: __tls_get_addr Product: lld Version: unspecified Hardware: PC OS: Linux Status: NEW Severity: normal Priority: P Component: ELF Assignee: unassignedb...@nondot.org Reporter: japarici...@gmail.com CC: llvm-bugs@lists.llvm.org Classification: Unclassified Hello! I'm working on embedding lld into rustc [1] with the goal of removing rustc dependence on an external linker, like `cc`/`ld`, wherever possible. One of our target use case is building statically linked Rust executables that are linked to MUSL but using `lld` instead of `ld`. (The ultimate goal is to be able to build/compile/link "foreign", e.g. ARM, binaries without having to install a cross toolchain, e.g. `arm-linux-gnueabihf-gcc`, or a cross compiled C library, but this bug report is about native linking). But when trying to link the simplest Rust program using `lld` instead of `ld`, which works fine, I'm hitting the following error: ``` duplicate symbol: __tls_get_addr in $sysroot/lib/rustlib/x86_64-unknown-linux-musl/lib/liblibc-411f48d3.rlib(__tls_get_addr.lo) and (internal) ``` ### Steps To Reproduce As a bash script but I've also attached the .cpio file generated by these commands: ``` bash main() { install_rust # test program echo 'fn main() {}' > musl.rs # to save some typing local target=x86_64-unknown-linux-musl # compile only, we'll link manually rm -f musl.o rustc --target $target --emit=obj musl.rs # store the path to the sysroot in a variable to make the following commands shorter local sysroot=$(rustc --print sysroot) # link # NOTE The arguments used here are what `rustc` (and `cc`) would ultimately pass to `ld` when # directly building an executable via the `rustc --target $target musl.rs` command. You can see # what flags `rustc` passes to `cc` with the `rustc --target $target -Z print-link-args musl.rs` # command. ld.lld \ --build-id \ --hash-style=gnu \ -m \ elf_x86_64 \ -static \ -o \ musl \ -L$sysroot/lib/rustlib/x86_64-unknown-linux-musl/lib \ -L$sysroot/lib/rustlib/x86_64-unknown-linux-musl/lib \ -L/usr/lib/gcc/x86_64-pc-linux-gnu/6.2.1 \ -L/usr/lib/gcc/x86_64-pc-linux-gnu/6.2.1/../../../../lib \ -L/lib/../lib \ -L/usr/lib/../lib \ -L/usr/lib/gcc/x86_64-pc-linux-gnu/6.2.1/../../.. \ --as-needed \ -z \ noexecstack \ --eh-frame-hdr \ "-(" \ $sysroot/lib/rustlib/x86_64-unknown-linux-musl/lib/crt1.o \ $sysroot/lib/rustlib/x86_64-unknown-linux-musl/lib/crti.o \ musl.o \ --gc-sections \ -Bstatic \ -Bdynamic \ $sysroot/lib/rustlib/x86_64-unknown-linux-musl/lib/libstd-411f48d3.rlib \ $sysroot/lib/rustlib/x86_64-unknown-linux-musl/lib/libpanic_unwind-411f48d3.rlib \ $sysroot/lib/rustlib/x86_64-unknown-linux-musl/lib/libunwind-411f48d3.rlib \ $sysroot/lib/rustlib/x86_64-unknown-linux-musl/lib/librand-411f48d3.rlib \ $sysroot/lib/rustlib/x86_64-unknown-linux-musl/lib/libcollections-411f48d3.rlib \ $sysroot/lib/rustlib/x86_64-unknown-linux-musl/lib/librustc_unicode-411f48d3.rlib \ $sysroot/lib/rustlib/x86_64-unknown-linux-musl/lib/liballoc-411f48d3.rlib \ $sysroot/lib/rustlib/x86_64-unknown-linux-musl/lib/liballoc_jemalloc-411f48d3.rlib \ $sysroot/lib/rustlib/x86_64-unknown-linux-musl/lib/liblibc-411f48d3.rlib \ $sysroot/lib/rustlib/x86_64-unknown-linux-musl/lib/libcore-411f48d3.rlib \ $sysroot/lib/rustlib/x86_64-unknown-linux-musl/lib/libcompiler_builtins-411f48d3.rlib \ $sysroot/lib/rustlib/x86_64-unknown-linux-musl/lib/crtn.o \ "-)" \ --reproduce musl uninstall_rust } install_rust() { curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain nightly-2016-09-15 --no-modify-path -y source ~/.cargo/env rustup target add x86_64-unknown-linux-musl } uninstall_rust() { rustup self uninstall } main ``` ### Meta ``` $ ld.lld --version LLD 4.0 (git://github.com/llvm-mirror/lld.git a499b2da2436789a9136f046f193caad0801ed93) ``` ### Background information - On Linux, `rustc` uses `cc` to link executables. - By default `rustc` produces executables that are *dynamically* linked to *glibc*. - But, if the `--target x86_64-unknown-linux-musl` flag is used, `rustc` will produce a *statically* linked executable that's linked to *MUSL*. - A `.rlib` file is just an archive (the stuff `ar` produces) that contain (ELF) objects + Rust metadata. - A copy of MUSL's `libc.a` lives in `liblibc.rlib`, which we distribute with our toolchain. That's why we don't pass `-lc` to the linker. Happy to provide more information! [1]: https://github.com/rust-lang/rust/pull/36120 -- You are receiving this mail because: You are on the CC list for the bug.
_______________________________________________ llvm-bugs mailing list llvm-bugs@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs