mirror of https://github.com/golang/go.git
cmd/internal/obj, cmd/link, runtime: handle TLS more like a platform linker on ppc64
On ppc64x, the thread pointer, held in R13, points 0x7000 bytes past where thread-local storage begins (presumably to maximize the amount of storage that can be accessed with a 16-bit signed displacement). The relocations used to indicate thread-local storage to the platform linker account for this, so to be able to support external linking we need to change things so the linker applies this offset instead of the runtime assembly. Change-Id: I2556c249ab2d802cae62c44b2b4c5b44787d7059 Reviewed-on: https://go-review.googlesource.com/14233 Reviewed-by: Russ Cox <rsc@golang.org> Reviewed-by: Austin Clements <austin@google.com>
This commit is contained in:
parent
a59a27564b
commit
c9b8cab16c
|
|
@ -451,6 +451,14 @@ const (
|
|||
// 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 {
|
||||
|
|
|
|||
|
|
@ -220,6 +220,7 @@ const (
|
|||
C_ANY
|
||||
C_GOK
|
||||
C_ADDR
|
||||
C_TLS_LE
|
||||
C_TEXTSIZE
|
||||
|
||||
C_NCLASS /* must be the last */
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ var cnames9 = []string{
|
|||
"ANY",
|
||||
"GOK",
|
||||
"ADDR",
|
||||
"TLS_LE",
|
||||
"TEXTSIZE",
|
||||
"NCLASS",
|
||||
}
|
||||
|
|
|
|||
|
|
@ -245,6 +245,8 @@ var optab = []Optab{
|
|||
{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},
|
||||
|
|
@ -583,6 +585,9 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int {
|
|||
}
|
||||
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
|
||||
|
|
@ -2396,6 +2401,17 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||
|
||||
//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
|
||||
|
|
|
|||
|
|
@ -408,6 +408,18 @@ func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int {
|
|||
*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
|
||||
|
|
|
|||
|
|
@ -26,16 +26,8 @@ TEXT runtime·save_g(SB),NOSPLIT|NOFRAME,$0-0
|
|||
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:
|
||||
|
|
@ -51,11 +43,8 @@ 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
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue