[all-commits] [llvm/llvm-project] 4584e4: [lld][MachO] Remove `__thread_ptrs` section so TLV...

Peter Rong via All-commits all-commits at lists.llvm.org
Thu Sep 24 11:01:39 PDT 2026


  Branch: refs/heads/main
  Home:   https://github.com/llvm/llvm-project
  Commit: 4584e4bb15bb8bf0c1c190b3cbe85908bcc2a56e
      https://github.com/llvm/llvm-project/commit/4584e4bb15bb8bf0c1c190b3cbe85908bcc2a56e
  Author: Peter Rong <peterrong96 at gmail.com>
  Date:   2026-09-24 (Thu, 24 Sep 2026)

  Changed paths:
    M lld/MachO/InputSection.cpp
    M lld/MachO/InputSection.h
    M lld/MachO/MapFile.cpp
    M lld/MachO/Relocations.cpp
    M lld/MachO/Symbols.cpp
    M lld/MachO/Symbols.h
    M lld/MachO/SyntheticSections.cpp
    M lld/MachO/SyntheticSections.h
    M lld/MachO/Writer.cpp
    M lld/test/MachO/arm64-reloc-tlv-load.s
    M lld/test/MachO/flat-namespace-interposable.s
    A lld/test/MachO/got-to-tlv-reference.s
    M lld/test/MachO/indirect-symtab.s
    R lld/test/MachO/invalid/bad-got-to-dylib-tlv-reference.s
    R lld/test/MachO/invalid/bad-got-to-tlv-reference.s
    M lld/test/MachO/map-file.s
    M lld/test/MachO/tapi-link.s
    M lld/test/MachO/tlv-dylib.s
    A lld/test/MachO/tlv-dynamic-lookup-x86.s
    A lld/test/MachO/tlv-dynamic-lookup.s
    A lld/test/MachO/tlv-non-lazy-pointer.s
    M lld/test/MachO/weak-binding.s
    M lld/test/MachO/weak-reference.s

  Log Message:
  -----------
  [lld][MachO] Remove `__thread_ptrs` section so TLV can relocate against dynamic-lookup symbols (#221364)

lld/MachO rejects a relocation whenever `hasAttr(TLV) != sym->isTlv()`, but
`isTlv()` cannot separate "not thread-local" from "unknown", so that one
inequality rejects three unrelated cases and only one of them is ill-formed.
C++20 `constinit` made another of them common: it lets the compiler elide the
thread-local wrapper and access a cross-TU object directly ([folly 2c666105](https://github.com/facebook/folly/commit/2c666105e9a694aef7290cce3da14ed1ebf14462)),
producing a TLV relocation against a dynamic-lookup symbol. The check was also
masking a defect — `Symbol::gotIndex` is one field indexing whichever of `__got`
or `__thread_ptrs` holds the symbol — and never enforced it anyway, since
`UnwindInfoSection` and the stub paths call `in.got->addEntry` directly, so a
thread-local personality already collided on stock lld.

Both pools hold the same value, the descriptor's address, and ld-prime never
synthesizes `__thread_ptrs` at all. Make `__got` the sole non-lazy pointer
section, deleting `TlvPointerSection`, `NonLazyPointerSectionBase`,
`in.tlvPointers`, `Symbol::getTlvVA` and the indirect-symbol-table
special-casing, and collapsing `resolveGotVA`/`resolveTlvVA` into
`resolveNonLazyPtrVA`. One section, one index, so the collision becomes
unrepresentable. Input objects with a real `__thread_ptrs` section still pass
through unchanged.

The check can now say what is actually wrong: TLV relocations against
dynamic-lookup symbols and GOT, branch or unsigned relocations against
thread-locals are accepted; a TLV relocation against a symbol known not to be
thread-local still errors, and a direct relocation against an imported
thread-local gets its own diagnostic. Two tests asserted a diagnostic ld64 does
not raise, so they keep their inputs, move out of `invalid/`, and assert the new
behaviour.



To unsubscribe from these emails, change your notification settings at https://github.com/llvm/llvm-project/settings/notifications


More information about the All-commits mailing list