Fix broken TLS destructors on 32-bit win7

On the 32-bit win7 target, we use OS TLS instead of native TLS, due to
issues with how the OS handles alignment. Unfortunately, this caused
issues due to the TLS destructors not running, causing memory leaks
among other problems.

On Windows, to support OS TLS, the TlsAlloc family of function is used
by Rust. This function does not support TLS destructors at all. However,
rust has some code to emulate those destructors, by leveraging the TLS
support functionality found in the MSVC CRT (specifically, in tlssup.c
of the CRT). Specifically, the CRT provides the ability to register
callbacks that are called (among other things) on thread destruction. By
registering our own callback, we can run through a list of registered
destructors functions to execute.

To use this functionality, the user must do two things:

1. They must put the address to their callback in a section between
   `.CRT$XLB` and `.CRT$XLY`.
2. They must add a reference to `_tls_used` (or `__tls_used` on x86) to
   make sure the TLS support code in tlssup.c isn't garbage collected by
   the linker.

Prior to this commit, this second bit wasn't being done properly by the
Rust TLS support code. Instead of adding a reference to _tls_used, it
instead had a reference to its own callback to prevent it from getting
GC'd by the linker. While this is _also_ necessary, not having a
reference on _tls_used made the entire support non-functional.

This commit reworks the code to:

1. Add an unconditional `#[used]` attribute on the CALLBACK, which
   should be enough to prevent it from getting GC'd by the linker.
2. Add a reference to `_tls_used`, which should pull the TLS support
   code into the Rust programs and not let it be GC'd by the linker.
1 file changed
tree: 7a734ae8957fcb72b690782635cbf59125815aab
  1. .github/
  2. compiler/
  3. library/
  4. LICENSES/
  5. src/
  6. tests/
  7. .clang-format
  8. .editorconfig
  9. .git-blame-ignore-revs
  10. .gitattributes
  11. .gitignore
  12. .gitmodules
  13. .ignore
  14. .mailmap
  15. bootstrap.example.toml
  16. Cargo.lock
  17. Cargo.toml
  18. CODE_OF_CONDUCT.md
  19. configure
  20. CONTRIBUTING.md
  21. COPYRIGHT
  22. INSTALL.md
  23. LICENSE-APACHE
  24. license-metadata.json
  25. LICENSE-MIT
  26. README.md
  27. RELEASES.md
  28. REUSE.toml
  29. rust-bors.toml
  30. rustfmt.toml
  31. triagebot.toml
  32. typos.toml
  33. x
  34. x.ps1
  35. x.py
README.md

Website | Getting started | Learn | Documentation | Contributing

This is the main source code repository for Rust. It contains the compiler, standard library, and documentation.

Why Rust?

  • Performance: Fast and memory-efficient, suitable for critical services, embedded devices, and easily integrated with other languages.

  • Reliability: Our rich type system and ownership model ensure memory and thread safety, reducing bugs at compile-time.

  • Productivity: Comprehensive documentation, a compiler committed to providing great diagnostics, and advanced tooling including package manager and build tool (Cargo), auto-formatter (rustfmt), linter (Clippy) and editor support (rust-analyzer).

Quick Start

Read “Installation” from The Book.

Installing from Source

If you really want to install from source (though this is not recommended), see INSTALL.md.

Getting Help

See https://www.rust-lang.org/community for a list of chat platforms and forums.

Contributing

See CONTRIBUTING.md.

License

Rust is primarily distributed under the terms of both the MIT license and the Apache License (Version 2.0), with portions covered by various BSD-like licenses.

See LICENSE-APACHE, LICENSE-MIT, and COPYRIGHT for details.

Trademark

The Rust Foundation owns and protects the Rust and Cargo trademarks and logos (the “Rust Trademarks”).

If you want to use these names or brands, please read the Rust language trademark policy.

Third-party logos may be subject to third-party copyrights and trademarks. See Licenses for details.