mirror of
https://github.com/golang/go
synced 2024-11-02 13:42:29 +00:00
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:
parent
d6481d5b96
commit
3562977b6f
4 changed files with 41 additions and 4 deletions
8
src/cmd/asm/internal/asm/testdata/mips64.s
vendored
8
src/cmd/asm/internal/asm/testdata/mips64.s
vendored
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue