rust-lang / rust-lang/rust

Compiler support for Windows TLS destructors

Open
#123,907 2 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

A-thread-locals C-enhancement O-windows T-compiler
Dominant language
Rust
Stars
119k
Forks
16.2k
PR merge metrics
PR metrics pending

Description

Currently the Windows TLS destructor implementation is held together by hacks in the standard library but it'd be better to have proper compiler support instead. The library implementation is currently in this file: https://github.com/rust-lang/rust/blob/7ab5eb8fe7aee35aea8ed4aed8c34f6abd988cc5/library/std/src/sys/pal/windows/thread_local_key.rs

The short version is that, for #[cfg(target_thread_local)] platforms we need the p_thread_callback to be associated with register_keyless_dtor such that if register_keyless_dtor is used in the final binary then p_thread_callback will also be included. Currently this is done using a volatile load of the assassinated function but this hack is not recommended.

A similar thing is also necessary for the #[cfg(not(target_thread_local))] case. if register_dtor is used in the final binary then p_thread_callback will also needs including.

In you don't want to go digging around the linked file, here are the relevant definitions:

`#[cfg(target_thread_local)]`
unsafe fn register_keyless_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8));
`#[cfg(not(target_thread_local))]`
unsafe fn register_dtor(key: &'static StaticKey);

#[link_section = ".CRT$XLB"]
static p_thread_callback: unsafe extern "system" fn(*mut (), u32, *mut ()) = on_tls_callback;

Making sure p_thread_callback is included with the register destructor function could be done in a few ways:

Object file

We could take advantage of object based linkage by writing a single object file containing both symbols. When put in a lib it'll ensure they're both included together. We would of course need some kind of attribute or magic symbol name to tell the compiler how to find these special symbols.

Probably not a good idea

COMDAT

The Windows COFF object format has IMAGE_COMDAT_SELECT_ASSOCIATIVE that allows associating one function with another. We could have some rustc attribute that std can use to annotate one symbol as being associated with another and then the compiler would emit the necessary comdat.

This is probably not a good idea because I'm not sure mixing COMDAT sections with special linker sections will work.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with library/std/src/sys/pal/windows/thread_local_key.rs and trace register_keyless_dtor, register_dtor, and p_thread_callback. Review the compiler and Windows object/linkage options described in the issue, then define and implement a supported association mechanism so using either destructor registration function includes p_thread_callback in the final binary.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers, operating-systems
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.