cmd/link/ld,cmd/internal/obj,runtime: make the Android TLS offset dynamic

We're going to need a different TLS offset for Android Q, so the static
offsets used for 386 and amd64 are no longer viable on Android.

Introduce runtime·tls_g and use that for indexing into TLS storage. As
an added benefit, we can then merge the TLS setup code for all android
GOARCHs.

While we're at it, remove a bunch of android special cases no longer
needed.

Updates #29674
Updates #29249 (perhaps fixes it)

Change-Id: I77c7385aec7de8f1f6a4da7c9c79999157e39572
Reviewed-on: https://go-review.googlesource.com/c/go/+/169817
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
Elias Naur 2019-03-28 13:11:53 +01:00
parent 2cc347382f
commit 1d10b17589
14 changed files with 102 additions and 275 deletions

View file

@ -41,13 +41,8 @@ import (
func CanUse1InsnTLS(ctxt *obj.Link) bool {
if isAndroid {
// For android, we use a disgusting hack that assumes
// the thread-local storage slot for g is allocated
// using pthread_key_create with a fixed offset
// (see src/runtime/cgo/gcc_android_amd64.c).
// This makes access to the TLS storage (for g) doable
// with 1 instruction.
return true
// Android uses a global variable for the tls offset.
return false
}
if ctxt.Arch.Family == sys.I386 {
@ -162,6 +157,18 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
}
}
// Android uses a tls offset determined at runtime. Rewrite
// MOVQ TLS, BX
// to
// MOVQ runtime.tls_g(SB), BX
if isAndroid && (p.As == AMOVQ || p.As == AMOVL) && p.From.Type == obj.TYPE_REG && p.From.Reg == REG_TLS && p.To.Type == obj.TYPE_REG && REG_AX <= p.To.Reg && p.To.Reg <= REG_R15 {
p.From.Type = obj.TYPE_MEM
p.From.Name = obj.NAME_EXTERN
p.From.Reg = REG_NONE
p.From.Sym = ctxt.Lookup("runtime.tls_g")
p.From.Index = REG_NONE
}
// TODO: Remove.
if ctxt.Headtype == objabi.Hwindows && ctxt.Arch.Family == sys.AMD64 || ctxt.Headtype == objabi.Hplan9 {
if p.From.Scale == 1 && p.From.Index == REG_TLS {
@ -1007,6 +1014,7 @@ func load_g_cx(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) *obj.Prog {
progedit(ctxt, p, newprog)
for p.Link != next {
p = p.Link
progedit(ctxt, p, newprog)
}
if p.From.Index == REG_TLS {