cmd/internal/obj/mips,s390x,riscv: save LR after decrementing SP

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>
This commit is contained in:
Cherry Mui 2022-06-22 16:28:41 -04:00 committed by David Chase
parent d6481d5b96
commit 3562977b6f
4 changed files with 41 additions and 4 deletions

View 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

View 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 {

View 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() {

View 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