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
    Classification: Unclassified


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
and (internal)

### Steps To Reproduce

As a bash script but I've also attached the .cpio file generated by these

``` bash
main() {

    # test program
    echo 'fn main() {}' >

    # 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

    # 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`
command. You can see
    # what flags `rustc` passes to `cc` with the `rustc --target $target -Z
    # 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/libunwind-411f48d3.rlib \
$sysroot/lib/rustlib/x86_64-unknown-linux-musl/lib/librand-411f48d3.rlib \
$sysroot/lib/rustlib/x86_64-unknown-linux-musl/lib/liballoc-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/crtn.o \
        "-)" \
        --reproduce musl


install_rust() {
    curl -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


### Meta

$ ld.lld --version
LLD 4.0 (git://

### Background information

- On Linux, `rustc` uses `cc` to link executables.
- By default `rustc` produces executables that are *dynamically* linked to
- 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!


You are receiving this mail because:
You are on the CC list for the bug.
llvm-bugs mailing list

Reply via email to