-z rela is also supported.
Tested with:
cat > ./a.c <<eof #include <assert.h> int foo(); int bar(); int main() { assert(foo() == 2); assert(foo() == 4); assert(bar() == 2); assert(bar() == 4); } eof cat > ./b.c <<eof #include <stdio.h> __thread int tls0; extern __thread int tls1; int foo() { return ++tls0 + ++tls1; } static __thread int tls2, tls3; int bar() { return ++tls2 + ++tls3; } eof echo '__thread int tls1;' > ./c.c sed 's/ /\t/' > ./Makefile <<'eof' .MAKE.MODE = meta curDirOk=true CC := gcc -m32 -g -fpic -mtls-dialect=gnu2 LDFLAGS := -m32 -Wl,-rpath=. all: a0 a1 a2 run: all ./a0 && ./a1 && ./a2 c.so: c.o; ${LINK.c} -shared $> -o $@ bc.so: b.o c.o; ${LINK.c} -shared $> -o $@ b.so: b.o c.so; ${LINK.c} -shared $> -o $@ a0: a.o b.o c.o; ${LINK.c} $> -o $@ a1: a.o b.so; ${LINK.c} $> -o $@ a2: a.o bc.so; ${LINK.c} $> -o $@ eof
and glibc elf/tst-gnu2-tls1.
/usr/local/bin/ld points to the freshly built lld.
bmake run && bmake CFLAGS=-O1 run => ok.