Lld cannot make PIE binaries on x32

The latest clang and lld defaults to PIE binaries, but it doesn’t work for x32 currently (x86_64-linux-gnux32). The error is relocation R_X86_64_32 cannot be used against local symbol; recompile with -fPIC, but ld.bfd works file, and also does passing in -no-pie:

$ clang hello.c 
ld.lld: error: cannot preempt symbol: __dso_handle
>>> defined in /usr/lib/gcc/x86_64-pc-linux-gnux32/11.3.0/crtbeginS.o
>>> referenced by /usr/lib/gcc/x86_64-pc-linux-gnux32/11.3.0/crtbeginS.o:(.data.rel.local+0x0)

ld.lld: error: relocation R_X86_64_32 cannot be used against local symbol; recompile with -fPIC
>>> defined in /usr/lib/gcc/x86_64-pc-linux-gnux32/11.3.0/crtbeginS.o
>>> referenced by /usr/lib/gcc/x86_64-pc-linux-gnux32/11.3.0/crtbeginS.o:(.fini_array+0x0)

ld.lld: error: relocation R_X86_64_32 cannot be used against local symbol; recompile with -fPIC
>>> defined in /usr/lib/gcc/x86_64-pc-linux-gnux32/11.3.0/crtbeginS.o
>>> referenced by /usr/lib/gcc/x86_64-pc-linux-gnux32/11.3.0/crtbeginS.o:(.init_array+0x0)
clang-15: error: linker command failed with exit code 1 (use -v to see invocation)
$ clang -fuse-ld=bfd hello.c 
$ clang -no-pie hello.c 

I did my testing inside gentoo stage3 container with image imported from here: Downloads – Gentoo Linux

I took a look at the code, it seems that lld/ELF/Arch/X86_64.c doesn’t have any x32 logic implemented. I tweaked it to set t->symbolicRel = R_X86_64_32 for 32-bit x86_64 elf files. Now I can get simple binaries to link.

But it seems like more work is needed: most of the TLS optimization logic needs to be rewritten for x32. Right now, some parts of the code are blindly rewriting code for the standard 64-bit ABI and would cause corruptions for x32. If the support isn’t complete yet, should x32 support be disabled? Or at least have some safeguards to check for x32 before doing the TLS optimizations?