[all-commits] [llvm/llvm-project] 4e5a44: [ELF] Fix TLS GD against non-preemptible dynamic s...

Jessica Clarke via All-commits all-commits at lists.llvm.org
Fri Jul 10 12:57:05 PDT 2026


  Branch: refs/heads/main
  Home:   https://github.com/llvm/llvm-project
  Commit: 4e5a44a332d020e668f350f65fd24019fe239c8d
      https://github.com/llvm/llvm-project/commit/4e5a44a332d020e668f350f65fd24019fe239c8d
  Author: Jessica Clarke <jrtc27 at jrtc27.com>
  Date:   2026-07-10 (Fri, 10 Jul 2026)

  Changed paths:
    M lld/ELF/Relocations.cpp
    M lld/ELF/SyntheticSections.cpp
    M lld/test/ELF/mips-tls-64-pic-local-variable.s
    M lld/test/ELF/x86-64-tls-gd-local.s

  Log Message:
  -----------
  [ELF] Fix TLS GD against non-preemptible dynamic symbols in DSOs (#207881)

Consider a DSO that uses TLS GD against a dynamic non-preemptible symbol
(e.g.  protected, or linked with -Bsymbolic). The expected meaning of
this is to always reference the DSO's own TLS segment for that symbol,
regardless of any attempts to preempt it at load time, and LLD will
indeed emit a constant offset rather than a symbolic DTPOFF relocation
for the second GOT word. However, for the first GOT word, because we
currently only treat the isLocalInExecutable case as special (where the
module index is 1), we end up creating a symbolic DTPMOD relocation,
rather than a non-symbolic (i.e. against the null symbol) one to get
this DSO's index, and so any load-time preemption will cause us to use a
different module's TLS block. As a result, not only do we have symbol
preemption when we shouldn't, but also the two halves of the TLS GD GOT
entry end up inconsistent, using the offset of the symbol in this
module's TLS block for a different module's.

Fix this by breaking down the two !isLocalInExecutable cases, emitting
the expected non-symbolic DTPMOD relocation for any non-preemptible
symbol references in a DSO. Whilst here, combine the DTPMOD and DTPOFF
code rather than have two different if statements, so it's clearer what
the three cases are and they don't get out of sync.

Note that although, for the existing code, local symbols take the exact same
code paths in postScanRelocations, they do not end up with symbolic DTPMOD
relocations in the output, despite creating them. DynamicReloc::getSymIndex has
the quirk of silently squashing the symbol index to 0 for symbolic relocations
against non-dynamic symbols, which applies to local symbols but not other
non-preemptible symbols, i.e. the case relevant in the first paragraph. This
quirky behaviour of DynamicReloc::getSymIndex is probably something that should
be retired; I can't see a good reason for it, and any case that it squashes
could be hiding similar bugs like this. I take the view that a request to
create a symbolic relocation against a symbol that won't be in the dynamic
symbol table is a strong sign that the code is confused and doing something
wrong, even if it happens to work out.



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