]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj: fix tail call in non-zero frame leaf function on MIPS and S390X
authorCherry Mui <cherryyz@google.com>
Mon, 13 Dec 2021 15:24:07 +0000 (10:24 -0500)
committerCherry Mui <cherryyz@google.com>
Mon, 13 Dec 2021 22:42:08 +0000 (22:42 +0000)
A "RET f(SB)" wasn't assembled correctly in a leaf function with
non-zero frame size. Follows CL 371034, for MIPS(32/64)(be/le)
and S390X. Other architectures seem to do it right. Add a test.

Change-Id: I41349a7ae9862b924f3a3de2bcb55b782061ce21
Reviewed-on: https://go-review.googlesource.com/c/go/+/371214
Trust: Cherry Mui <cherryyz@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
Reviewed-by: David Chase <drchase@google.com>
src/cmd/internal/obj/mips/obj0.go
src/cmd/internal/obj/s390x/objz.go
test/retjmp.dir/a.s
test/retjmp.dir/main.go

index 9e2ccc1929774e4fcbe974ac8ca0d77f26ebc1c6..b96a28a94423b8ff9cd8875e95daba89cf890d64 100644 (file)
@@ -466,9 +466,15 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                                q = c.newprog()
                                q.As = AJMP
                                q.Pos = p.Pos
-                               q.To.Type = obj.TYPE_MEM
-                               q.To.Offset = 0
-                               q.To.Reg = REGLINK
+                               if retSym != nil { // retjmp
+                                       q.To.Type = obj.TYPE_BRANCH
+                                       q.To.Name = obj.NAME_EXTERN
+                                       q.To.Sym = retSym
+                               } else {
+                                       q.To.Type = obj.TYPE_MEM
+                                       q.To.Reg = REGLINK
+                                       q.To.Offset = 0
+                               }
                                q.Mark |= BRANCH
                                q.Spadj = +autosize
 
index de40ff05aff52acecc5f93b2f8fcf7383a688dc2..aebbf8dbc55f1a02a2fd9155f6802bcc16b6b34c 100644 (file)
@@ -488,8 +488,13 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                                q = obj.Appendp(p, c.newprog)
                                q.As = ABR
                                q.From = obj.Addr{}
-                               q.To.Type = obj.TYPE_REG
-                               q.To.Reg = REG_LR
+                               if retTarget == nil {
+                                       q.To.Type = obj.TYPE_REG
+                                       q.To.Reg = REG_LR
+                               } else {
+                                       q.To.Type = obj.TYPE_BRANCH
+                                       q.To.Sym = retTarget
+                               }
                                q.Mark |= BRANCH
                                q.Spadj = autosize
                                break
index c67a06638f90be9d182770f2738326d7c02c835c..101b3428fc2d6c794b2119fffe709e58a74c910b 100644 (file)
@@ -10,3 +10,7 @@ TEXT  ·f(SB), 4, $8-0
 TEXT   ·leaf(SB), 4, $0-0
        RET     ·f3(SB)
        JMP     ·unreachable(SB)
+
+TEXT   ·leaf2(SB), 4, $32-0 // nonzero frame size
+       RET     ·f4(SB)
+       JMP     ·unreachable(SB)
index cb4bd018bf8c021090187d2e9b58fe3de954f4f1..0bed5a61b7ac623be289e969c8f17f7b7b9b44c5 100644 (file)
@@ -6,8 +6,9 @@ package main
 
 func f()
 func leaf()
+func leaf2()
 
-var f1called, f2called, f3called bool
+var f1called, f2called, f3called, f4called bool
 
 func main() {
        f()
@@ -21,11 +22,16 @@ func main() {
        if !f3called {
                panic("f3 not called")
        }
+       leaf2()
+       if !f4called {
+               panic("f4 not called")
+       }
 }
 
 func f1() { f1called = true }
 func f2() { f2called = true }
 func f3() { f3called = true }
+func f4() { f4called = true }
 
 func unreachable() {
        panic("unreachable function called")