Native ELF TLS for the Vita target - #185
Draft
frangarcj wants to merge 5 commits into
Draft
Conversation
Local Exec / TPIDRURO is the model per vitasdk_native_tls_design.md phase 1; verified against a standalone gcc-base build that it emits STT_TLS/SHF_TLS/PT_TLS and R_ARM_TLS_LE32 instead of __emutls_*. Assisted-by: Claude Opus 5
Vita's TP points straight at .tdata, with none of the ARM EABI's 8-byte TCB header in front of it, and the loader expects .tdata/.tbss to share the same (read-only) segment as module_start. Two small patches, scoped to the armvita emulation only, teach the linker both. Assisted-by: Claude Opus 5
Pairs with the newlib side (struct _reent thread-local, kernel TLS slot 0x89 no longer holding it). Assisted-by: Claude Opus 5
Design phase 1 says the main executable uses Local Exec, but nothing enforced it: for a TLS symbol defined in another translation unit gcc falls back to initial-exec, which wants a GOT entry the Vita loader never fills. Linking a newlib with its reent in TLS produced 36 R_ARM_TLS_IE32 against _tls_errno plus 15 R_ARM_TLS_LDO32, and vita-elf-create refused them. CC1_SPEC only supplies the default, so -ftls-model= on the command line still wins. Assisted-by: Claude Opus 5
libstdc++ only defers thread_local destructor registration to libc when HAVE___CXA_THREAD_ATEXIT is defined at its configure time, and the --with-newlib branch never checks for the symbol: it hardcodes its feature list. Without the define, libsupc++ compiles its own fallback, which keeps the destructor list in a pthread key, only runs it when the prebuilt library sees gthreads as active (a weak pthread_cancel reference, satisfied only by a whole-archive libpthread), and never on a raw kernel thread. Newlib on Vita now provides __cxa_thread_atexit, running the destructors from the thread-exit path on every exit path, so define it for arm-vita-eabi in that branch. Patched in both configure.ac and the generated configure, since the build does not regenerate it. Assisted-by: Claude Fable 5
This was referenced Aug 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this change?
The target compiler is built with
--enable-tlsand defaults to-ftls-model=local-exec; binutils gets two patches scoped to thearmvitaemulation (TP points at.tdatawith no TCB;.tdata/.tbssshare the read-only segment withmodule_start); newlib is built with--enable-newlib-reent-thread-local; libstdc++ is configured withHAVE___CXA_THREAD_ATEXITforarm-vita-eabiso it defersthread_localdestructor registration to newlib's__cxa_thread_atexit. [Pending in this PR: the TLS configuration as part of the newlib and pthread-embedded build identity, and a CI job that exercises an old-to-new incremental transition.]Why is this change needed?
Phase B of vitasdk/.github#3: the toolchain side of native ELF TLS.
Testing
arm64-apple-darwin; the installed-toolchain contract, static-library validation and host dependency audit pass.newlib-testsbuilt with this SDK, 88 tests, 82 pass, 0 failures; details in sys/vita: struct _reent in native ELF TLS, thread-exit reclaim, __cxa_thread_atexit newlib#115.--fuzz=0 --forward.Compatibility
Breaks the target ABI (see the RFC); intended to ship as the
nightly-tlschannel first. Depends on vitasdk/newlib#115 and vitasdk/pthread-embedded#24; theNEWLIB_TAG/PTHREAD_TAGpins move to the merged commits before this merges. RFC: vitasdk/.github#3.Third-party material
None.
AI assistance
Additional context
RFC: vitasdk/.github#3. Companions: vitasdk/vita-toolchain#294, vitasdk/newlib#115, vitasdk/pthread-embedded#24.