This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug target/84010] [sparc64] Bad TLS code generation


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84010

--- Comment #1 from James Clarke <jrtc27 at jrtc27 dot com> ---
Elaborating slightly for those unfamiliar with SPARC TLS relocations:

Initial exec sequences normally look something like:

  sethi %tie_hi22(foo), %r1
  or    %r1, %tie_lo10(foo), %r1
  ldx   [%l7+%r1], %r2, %tie_ldx(foo)
  add   %g7, %r2, %r2, %tie_add(foo)

(if %l7 is the PIC base register), so %r1 ends up being a 32-bit GOT offset
(where the GOT is storing the offset of the thread-local variable from the
thread pointer, %g7). Note that %tie_ldx(foo) and %tie_add(foo) are not actual
arguments for the instructions, but get converted into R_SPARC_TLS_IE_LDX/ADD
relocations so the linker can identify the instructions in the sequence.

However, a local exec sequence looks something like:

  sethi %tle_hix22(foo), %r1
  xor   %r1, %tle_lox10(foo), %r1
  add   %g7, %r1, %r1

and so %r1 is a signed 32-bit value. The linker can relax the initial exec
sequence into the local exec sequence if it knows that foo is defined in the
executable, and so gcc cannot assume that %r1 in the first case is a 32-bit
quantity.

There are similar problems for other TLS models which can be relaxed, but even
worse than this, local dynamic uses a sethi/xor for the offset from the
defining module's block to load a signed 32-bit value, but since it's marked as
SI I assume a spill/reload will truncate the top 32 bits and thus lose any sign
extension if it's negative, breaking it even with linker relaxation disabled.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]