-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
LibELF+LibC: Support loading shared objects with dynamic thread-local storage #19809
Conversation
|
This pull request has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions! |
This comment was marked as outdated.
This comment was marked as outdated.
3cba3d6 to
727d57b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two nitpicks and a build failure, looks good (to the rather untrained observer) otherwise.
727d57b to
9fe73a0
Compare
These should cover all relocation types we can possibly see in an x86_64 or AArch64 final linked ELF image.
LibC is always guaranteed to be loaded at program start, so its thread-local variables live in the static TLS block. This permits us to use the more optimal initial-exec TLS access model.
It's the pointer that should be volatile, not the pointed-to object.
This is a prerequisite for upstreaming our LLVM patches, as our current hack forcing `-ftls-model=initial-exec` in the Clang driver is not acceptable upstream. Currently, our kernel-managed TLS implementation limits us to only having a single block of storage for all thread-local variables that's initialized at load time. This PR merely implements the dynamic TLS interface (`__tls_get_addr` and TLSDESC) on top of our static TLS infrastructure. The current model's limitations still stand: - a single static TLS block is reserved at load time, `dlopen()`-ing shared libraries that define thread-local variables might cause us to run out of space. - the initial TLS image is not changeable post-load, so `dlopen()`-ing libraries with non-zero-initialized TLS variables is not supported. The way we repurpose `ti_module` to mean "offset within static TLS block" instead of "module index" is not ABI-compliant.
The setup is a bit peculiar: both the definition and the use site of these TLS variables have to be in a shared library, otherwise the linker might relax the global-dynamic access mode to something that doesn't require a `__tls_get_addr` call.
9fe73a0 to
e84f44d
Compare
This is a prerequisite for upstreaming our LLVM patches, which currently need to hackily force the
initial-execTLS model in the Clang driver.Currently, our kernel-managed TLS implementation limits us to only having a single block of storage for all thread-local variables that's initialized at load time. Changing that is outside the scope of this PR, but is in my plans, and there have already been design discussions in
#clang-toolchain. This PR merely implements the dynamic TLS interface (__tls_get_addrand TLSDESC) on top of our static TLS infrastructure. The limitation aboutdlopen()ed shared objects with a non-zero-initialized TLS image and having to fit in the static TLS block still stands.