Non-PIC code causes ld --shared to fail when using -fsanitize=undefined in trunk but not 3.4.

It is not clear to me which list covers use of this flag, but as it appears to this user as a compiler bug, I am posting here. Please tell me where is the correct place if this is not it.

We use clang to run UBSAN over code for the R project, which makes extensive use of DSOs to dynamically load extensions. This works fine with 3.4, but not with the trunk.

For an empty file test.c, trunk gives

clang -fsanitize=undefined -fpic -g -O2 -mtune=native -c test.c -o test.o
clang -fsanitize=undefined -shared -o test.so test.o
/usr/bin/ld: /usr/local/clang3.5t/bin/../lib/clang/3.5.0/lib/linux/libclang_rt.san-x86_64.a(sanitizer_tls_get_addr.o): relocation R_X86_64_TPOFF32 against `_ZN11__sanitizerL4dtlsE' can not be used when making a shared object; recompile with -fPIC
/usr/local/clang3.5t/bin/../lib/clang/3.5.0/lib/linux/libclang_rt.san-x86_64.a(sanitizer_tls_get_addr.o): could not read symbols: Bad value
clang: error: linker command failed with exit code 1 (use -v to see invocation)

whereas 3.4 successfully compiled test.so.

This is x86_64 Linux, specifically Fedora 20, and trunk compiled starting with clang 3.4. I first saw this around early Feb 2014, and some bisection shows that r200062 was the last version I tried that worked.

Thanks for the report!

I am not a sanitizer expert, but here’s what I think is happening.

The ubsan runtime is linked statically into all DSOs in the user’s program, but the other sanitizer runtimes are only linked statically into the main executable. Because the other sanitizers are only present in the main executable, they can use a more efficient TLS access model. It looks like some of this TLS leaked into the common sanitizer runtime code, and got linked into the ubsan runtime, which doesn’t work.

This should be fixed by r212064. Sorry for delay, and thanks for the report!