]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/x86: mark 2-instruction TLS access nonpreemptible
authorCherry Zhang <cherryyz@google.com>
Wed, 13 Nov 2019 20:05:17 +0000 (15:05 -0500)
committerCherry Zhang <cherryyz@google.com>
Fri, 15 Nov 2019 02:31:58 +0000 (02:31 +0000)
The 2-instruction TLS access sequence
MOVQ TLS, BX
MOVQ 0(BX)(TLS*1), BX
is not async preemptible, as if it is preempted and resumed on a
different thread, the TLS address may become invalid.

May fix #35349. (This is a rare failure and I haven't been able
to reproduce it.)

Change-Id: Ie1a366fd0d7d73627dc62ee2de01c0aa09365f2b
Reviewed-on: https://go-review.googlesource.com/c/go/+/206903
Run-TryBot: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Austin Clements <austin@google.com>
src/cmd/internal/obj/x86/asm6.go

index 3a33bc3c3cc83655f98a836739770eff0d294909..cfeb179a863992c461982c3006d3f092e26ce8cf 100644 (file)
@@ -1984,6 +1984,22 @@ func span6(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) {
                        fmt.Printf(" rel %#.4x/%d %s%+d\n", uint32(r.Off), r.Siz, r.Sym.Name, r.Add)
                }
        }
+
+       // Mark nonpreemptible instruction sequences.
+       // The 2-instruction TLS access sequence
+       //      MOVQ TLS, BX
+       //      MOVQ 0(BX)(TLS*1), BX
+       // is not async preemptible, as if it is preempted and resumed on
+       // a different thread, the TLS address may become invalid.
+       if !CanUse1InsnTLS(ctxt) {
+               useTLS := func(p *obj.Prog) bool {
+                       // Only need to mark the second instruction, which has
+                       // REG_TLS as Index. (It is okay to interrupt and restart
+                       // the first instruction.)
+                       return p.From.Index == REG_TLS
+               }
+               obj.MarkUnsafePoints(ctxt, s.Func.Text, newprog, useTLS)
+       }
 }
 
 func instinit(ctxt *obj.Link) {