<html>
<head>
<base href="https://llvm.org/bugs/" />
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW --- - [Rust][MUSL] duplicate symbol: __tls_get_addr"
href="https://llvm.org/bugs/show_bug.cgi?id=30432">30432</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>[Rust][MUSL] duplicate symbol: __tls_get_addr
</td>
</tr>
<tr>
<th>Product</th>
<td>lld
</td>
</tr>
<tr>
<th>Version</th>
<td>unspecified
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>Linux
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>normal
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>ELF
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>japaricious@gmail.com
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org
</td>
</tr>
<tr>
<th>Classification</th>
<td>Unclassified
</td>
</tr></table>
<p>
<div>
<pre>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 <a href="https://sh.rustup.rs">https://sh.rustup.rs</a> -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]: <a href="https://github.com/rust-lang/rust/pull/36120">https://github.com/rust-lang/rust/pull/36120</a></pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>