mlibc icon indicating copy to clipboard operation
mlibc copied to clipboard

Support TLS segment of ld.so itself

Open avdgrinten opened this issue 2 years ago • 4 comments

Right now, ld.so cannot handle its own TLS segment. This can cause problems in sysdeps that want to use thread_local and should be fixed (although coming up with a clean fix might be difficult).

Currently, the lack of TLS handling causes issues when calling dlopen() from a thread other than the main thread on Managarm. Specifically, the Managarm sysdeps for ld.so maintain global data structures that should actually become thread-local (for example, this applies to the handle that is used to communicate with Managarm's posix-subsystem).

avdgrinten avatar Jun 20 '22 22:06 avdgrinten

This seems really hard to fix completely, since in order to even map or allocate memory for a TLS segment we'd have to call into a sysdep (vm_map or anon_allocate) which could potentially use thread locals. Even just setting the thread pointer requires a syscall on x86.

We could use some kind of cursed static buffer or store the thread locals on the stack maybe?

64 avatar Jun 20 '22 22:06 64

Perhaps we should place concrete limitations on when sysdeps may use thread-locals? Also worth noting is that sysdeps can disable parts of code depending on whether ld.so or libc.so is being built.

qookei avatar Jun 20 '22 22:06 qookei

I agree that it's probably quite hard to fix. Another option is disallowing TLS in sysdeps, but then we need some workaround to make Managarm work. For example, we could have functions mlibc::set_sysdep_tls() / mlibc::get_sysdep_tls() that allows sysdeps to set/retrieve a per-thread pointer that can be used to emulate TLS. We could store this pointer in a global variable before ld.so finishes its initialization and move it to TLS afterwards.

avdgrinten avatar Jun 21 '22 05:06 avdgrinten

Adding the bug label since this breaks Firefox (or at least some fork of it), as reported by @ElectrodeYT.

avdgrinten avatar Jun 21 '22 05:06 avdgrinten