// the thread local base and the thread local variable defined by the
// referenced (thread local) symbol from the GOT.
R_ARM64_TLS_IE
+
+ // PPC64.
+
+ // R_POWER_TLS_LE is used to implement the "local exec" model for tls
+ // access. It resolves to the offset of the thread-local symbol from the
+ // thread pointer (R13) and inserts this value into the low 16 bits of an
+ // instruction word.
+ R_POWER_TLS_LE
)
type Auto struct {
{AMOVBZ, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0},
{AMOVB, C_ADDR, C_NONE, C_NONE, C_REG, 76, 12, 0},
+ {AMOVD, C_TLS_LE, C_NONE, C_NONE, C_REG, 79, 4, 0},
+
/* load constant */
{AMOVD, C_SECON, C_NONE, C_NONE, C_REG, 3, 4, REGSB},
{AMOVD, C_SACON, C_NONE, C_NONE, C_REG, 3, 4, REGSP},
}
ctxt.Instoffset = a.Offset
if a.Sym != nil { // use relocation
+ if a.Sym.Type == obj.STLSBSS {
+ return C_TLS_LE
+ }
return C_ADDR
}
return C_LEXT
//if(dlm) reloc(&p->from, p->pc, 1);
+ case 79:
+ if p.From.Offset != 0 {
+ ctxt.Diag("invalid offset against tls var %v", p)
+ }
+ o1 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), REGZERO, 0)
+ rel := obj.Addrel(ctxt.Cursym)
+ rel.Off = int32(ctxt.Pc)
+ rel.Siz = 4
+ rel.Sym = p.From.Sym
+ rel.Type = obj.R_POWER_TLS_LE
+
}
out[0] = o1
*val = ld.Symaddr(r.Sym) + r.Add - symtoc(s)
return 0
+
+ case obj.R_POWER_TLS_LE:
+ // The thread pointer points 0x7000 bytes after the start of the the
+ // thread local storage area as documented in section "3.7.2 TLS
+ // Runtime Handling" of "Power Architecture 64-Bit ELF V2 ABI
+ // Specification".
+ v := r.Sym.Value - 0x7000
+ if int64(int16(v)) != v {
+ ld.Diag("TLS offset out of range %d", v)
+ }
+ *val = (*val &^ 0xffff) | (v & 0xffff)
+ return 0
}
return -1
MOVB runtime·iscgo(SB), R31
CMP R31, $0
BEQ nocgo
-
- // $runtime.tlsg(SB) is a special linker symbol.
- // It is the offset from the start of TLS to our
- // thread-local storage for g.
- MOVD $runtime·tls_g(SB), R31
+ MOVD runtime·tls_g(SB), R31
ADD R13, R31
- // The actual TLS base is 0x7000 below R13
- SUB $0x7000, R31
-
- // Store g in TLS
MOVD g, 0(R31)
nocgo:
//
// NOTE: _cgo_topofstack assumes this only clobbers g (R30), and R31.
TEXT runtime·load_g(SB),NOSPLIT|NOFRAME,$0-0
- MOVD $runtime·tls_g(SB), R31
- // R13 is the C ABI TLS base pointer + 0x7000
+ MOVD runtime·tls_g(SB), R31
ADD R13, R31
- SUB $0x7000, R31
-
MOVD 0(R31), g
RET