]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/mips,s390x,riscv: save LR after decrementing SP
authorCherry Mui <cherryyz@google.com>
Wed, 22 Jun 2022 20:28:41 +0000 (16:28 -0400)
committerDavid Chase <drchase@google.com>
Wed, 29 Jun 2022 16:36:06 +0000 (16:36 +0000)
Following CL 412474, for the rest of the LR architectures. On
MIPS(32/64), S390X, and RISCV, there is no single instruction that
saves the LR and decrements the SP, so we need to insert an
instruction to save the LR after decrementing the SP.

On ARM(32) and PPC64 we already use a single instruction to save
the LR and decrement the SP.

Updates #53374.

Change-Id: I5a2e211026d95edb0e0f7d084ddb784f8077b86d
Reviewed-on: https://go-review.googlesource.com/c/go/+/413428
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>

src/cmd/asm/internal/asm/testdata/mips64.s
src/cmd/internal/obj/mips/obj0.go
src/cmd/internal/obj/riscv/obj.go
src/cmd/internal/obj/s390x/objz.go

index 99044d89f7be331b44df28456c5ebc90442a217e..8f628e26c9a563c8c3e8886544da6120c17af6c4 100644 (file)
@@ -21,9 +21,9 @@ label0:
        BEQ     R1, 2(PC)
        JMP     label0+0        // JMP 3        // 1000fffd
        BEQ     R1, 2(PC)
-       JAL     1(PC)           // CALL 1(PC)   // 0c00000e
+       JAL     1(PC)           // CALL 1(PC)   // 0c00000f
        BEQ     R1, 2(PC)
-       JAL     label0+0        // CALL 3       // 0c000006
+       JAL     label0+0        // CALL 3       // 0c000007
 
 //     LBRA addr
 //     {
@@ -32,11 +32,11 @@ label0:
        BEQ     R1, 2(PC)
        JMP     0(R1)           // JMP (R1)     // 00200008
        BEQ     R1, 2(PC)
-       JMP     foo+0(SB)       // JMP foo(SB)  // 08000018
+       JMP     foo+0(SB)       // JMP foo(SB)  // 08000019
        BEQ     R1, 2(PC)
        JAL     0(R1)           // CALL (R1)    // 0020f809
        BEQ     R1, 2(PC)
-       JAL     foo+0(SB)       // CALL foo(SB) // 0c000020
+       JAL     foo+0(SB)       // CALL foo(SB) // 0c000021
 
 //
 // BEQ/BNE
index 2a2c8ecb75cee94b47aa89ebefad0e29c21a4f31..9241dfd6316d078d1a2c25f8ae3b8ce33d30f64f 100644 (file)
@@ -343,6 +343,20 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                                q.Spadj = +autosize
 
                                q = c.ctxt.EndUnsafePoint(q, c.newprog, -1)
+
+                               // On Linux, in a cgo binary we may get a SIGSETXID signal early on
+                               // before the signal stack is set, as glibc doesn't allow us to block
+                               // SIGSETXID. So a signal may land on the current stack and clobber
+                               // the content below the SP. We store the LR again after the SP is
+                               // decremented.
+                               q = obj.Appendp(q, newprog)
+                               q.As = mov
+                               q.Pos = p.Pos
+                               q.From.Type = obj.TYPE_REG
+                               q.From.Reg = REGLINK
+                               q.To.Type = obj.TYPE_MEM
+                               q.To.Offset = 0
+                               q.To.Reg = REGSP
                        }
 
                        if c.cursym.Func().Text.From.Sym.Wrapper() && c.cursym.Func().Text.Mark&LEAF == 0 {
index b30958cb38550e9850f5d4259765bcbbadfce238..34aa923f4abd33ce5fc8ce3953c314b3e36f301a 100644 (file)
@@ -410,6 +410,16 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                prologue.Spadj = int32(stacksize)
 
                prologue = ctxt.EndUnsafePoint(prologue, newprog, -1)
+
+               // On Linux, in a cgo binary we may get a SIGSETXID signal early on
+               // before the signal stack is set, as glibc doesn't allow us to block
+               // SIGSETXID. So a signal may land on the current stack and clobber
+               // the content below the SP. We store the LR again after the SP is
+               // decremented.
+               prologue = obj.Appendp(prologue, newprog)
+               prologue.As = AMOV
+               prologue.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_LR}
+               prologue.To = obj.Addr{Type: obj.TYPE_MEM, Reg: REG_SP, Offset: 0}
        }
 
        if cursym.Func().Text.From.Sym.Wrapper() {
index fed770375920eeef1f8fe2667a66ac855627e938..4e8475624df489d4f3c491d58fe33be79cf1b96d 100644 (file)
@@ -358,6 +358,19 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                                q.Spadj = autosize
 
                                q = c.ctxt.EndUnsafePoint(q, c.newprog, -1)
+
+                               // On Linux, in a cgo binary we may get a SIGSETXID signal early on
+                               // before the signal stack is set, as glibc doesn't allow us to block
+                               // SIGSETXID. So a signal may land on the current stack and clobber
+                               // the content below the SP. We store the LR again after the SP is
+                               // decremented.
+                               q = obj.Appendp(q, c.newprog)
+                               q.As = AMOVD
+                               q.From.Type = obj.TYPE_REG
+                               q.From.Reg = REG_LR
+                               q.To.Type = obj.TYPE_MEM
+                               q.To.Reg = REGSP
+                               q.To.Offset = 0
                        } else if c.cursym.Func().Text.Mark&LEAF == 0 {
                                // A very few functions that do not return to their caller
                                // (e.g. gogo) are not identified as leaves but still have