thread context 6/n: locate thread-local variables - #1853
Draft
nsavoire wants to merge 3 commits into
Draft
Conversation
Locates a thread-local variable at unwind time: TP-relative when module_id is 0, else an offset within that module's TLS block, completed once libc introspection supplies the DTV layout. resolved is explicit because a zeroed TLSVarInfo is otherwise a valid static descriptor. Fields are private to ensure callers go through the constructors: generate.sh lowercases them after godefs, which exports every field name.
Computes the TP-relative offset of a local-exec thread-local from PT_TLS. Purely ELF-static, so it belongs next to ProgByType rather than in the caller that classifies TLS access models.
Resolve classifies how a thread-local is accessed, once per ELF, covering both TLS dialects and all four access models. Locate then turns that into a TLSVarInfo for one process: resolved for static TLS, awaiting the DTV layout for dynamic TLS. Locate is tested against synthetic process memory per access model, Resolve against purpose-built fixtures for each relocation shape.
nsavoire
force-pushed
the
nsavoire/threadctx-tls
branch
from
September 11, 2026 15:13
160e8c0 to
8689e73
Compare
Pull request dashboard statusWaiting on the author · refreshed 2026-09-11 17:23 UTC Move out of draft to request review. Status above doesn't look right?
|
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.
Part of the PR #1229 split. Stacked on #1843, whose commit is included here.
Adds a
tlspackage that locates a thread-local variable of a running process, given the ELF that defines it.What's here
Process address of TLS variable is computed in 2 steps:
Resolveclassifies how a variable is accessed based only on ELF file.Locateturns that into aTLSVarInfoby reading runtime relocations.Resolve(ef, sym) (Var, error)determine the TLS access model from the relocation type that references the symbol (RelTLSDESC,RelDTPMOD64,RelTPOFF64, from pfelf: add RelTPOFF64 and pass matched RelocType to relocation visitor #1838), and falls back to local-exec for a symbol no relocation references in an executable.Var.Locate(rm, bias) (VarInfo, error)reads the GOT slot holding TP-relative offset,tls_index {module_id, offset}or TLS descriptor depending on the TLS access model, and returns either a resolved static descriptor or a dynamic one awaiting its DTV layout (completed bySetDTVInfo).pfelf.File.StaticTLSOffsetcomputes the TP-relative offset of a local-exec variable fromPT_TLS, for both TLS variants, matching LLD'sgetTlsTpOffsetand glibc's_dl_determine_tlsoffset. Purely ELF-static, so it belongs next toProgByType/VisitRelocationsrather than intls.tlsdesc_aarch64.go: on aarch64 a resolved descriptor's argument is positive whether it is a TP offset or atls_indexpointer. Magnitude settles the common small offset, and above that bound the resolver body does: glibc, musl, bionic and uClibc-ng all write the static resolver asldr x0, [x0, #8]; retin hand-written assembly, so recognizing it is what makes the argument an offset. x86-64 settles the same question by sign.The four access models are covered across both gnu and gnu2 TLS dialects.
Tests
locate_test.go: cases over synthetic process memory, one per access model and TLS variant plus the unresolved and malformed shapes.tls_integration_test.go, behind thehost_integration: fixtures over glibc and musl, every access model, both dialects, startup linkage anddlopen. Each fixture reports where its own thread-locals live, and the descriptor produced for them must resolve to the same address.Where this sits in the stack
TLSVarInfo, and on merged pfelf: add RelTPOFF64 and pass matched RelocType to relocation visitor #1838 for the relocation types.Attachis the next change and the first production caller. Ruby and apmint each hand-roll a subset ofLocatetoday, reading the descriptor's second word unconditionally as a TP offset, migrating them onto this package is a separate change off this one.