Skip to content

Commit 3562977

Browse files
cherrymuidr2chase
authored andcommitted
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 <[email protected]> Reviewed-by: Austin Clements <[email protected]> Run-TryBot: Cherry Mui <[email protected]>
1 parent d6481d5 commit 3562977

File tree

4 files changed

+41
-4
lines changed

4 files changed

+41
-4
lines changed

src/cmd/asm/internal/asm/testdata/mips64.s

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ label0:
2121
BEQ R1, 2(PC)
2222
JMP label0+0 // JMP 3 // 1000fffd
2323
BEQ R1, 2(PC)
24-
JAL 1(PC) // CALL 1(PC) // 0c00000e
24+
JAL 1(PC) // CALL 1(PC) // 0c00000f
2525
BEQ R1, 2(PC)
26-
JAL label0+0 // CALL 3 // 0c000006
26+
JAL label0+0 // CALL 3 // 0c000007
2727

2828
// LBRA addr
2929
// {
@@ -32,11 +32,11 @@ label0:
3232
BEQ R1, 2(PC)
3333
JMP 0(R1) // JMP (R1) // 00200008
3434
BEQ R1, 2(PC)
35-
JMP foo+0(SB) // JMP foo(SB) // 08000018
35+
JMP foo+0(SB) // JMP foo(SB) // 08000019
3636
BEQ R1, 2(PC)
3737
JAL 0(R1) // CALL (R1) // 0020f809
3838
BEQ R1, 2(PC)
39-
JAL foo+0(SB) // CALL foo(SB) // 0c000020
39+
JAL foo+0(SB) // CALL foo(SB) // 0c000021
4040

4141
//
4242
// BEQ/BNE

src/cmd/internal/obj/mips/obj0.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,20 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
343343
q.Spadj = +autosize
344344

345345
q = c.ctxt.EndUnsafePoint(q, c.newprog, -1)
346+
347+
// On Linux, in a cgo binary we may get a SIGSETXID signal early on
348+
// before the signal stack is set, as glibc doesn't allow us to block
349+
// SIGSETXID. So a signal may land on the current stack and clobber
350+
// the content below the SP. We store the LR again after the SP is
351+
// decremented.
352+
q = obj.Appendp(q, newprog)
353+
q.As = mov
354+
q.Pos = p.Pos
355+
q.From.Type = obj.TYPE_REG
356+
q.From.Reg = REGLINK
357+
q.To.Type = obj.TYPE_MEM
358+
q.To.Offset = 0
359+
q.To.Reg = REGSP
346360
}
347361

348362
if c.cursym.Func().Text.From.Sym.Wrapper() && c.cursym.Func().Text.Mark&LEAF == 0 {

src/cmd/internal/obj/riscv/obj.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,16 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
410410
prologue.Spadj = int32(stacksize)
411411

412412
prologue = ctxt.EndUnsafePoint(prologue, newprog, -1)
413+
414+
// On Linux, in a cgo binary we may get a SIGSETXID signal early on
415+
// before the signal stack is set, as glibc doesn't allow us to block
416+
// SIGSETXID. So a signal may land on the current stack and clobber
417+
// the content below the SP. We store the LR again after the SP is
418+
// decremented.
419+
prologue = obj.Appendp(prologue, newprog)
420+
prologue.As = AMOV
421+
prologue.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_LR}
422+
prologue.To = obj.Addr{Type: obj.TYPE_MEM, Reg: REG_SP, Offset: 0}
413423
}
414424

415425
if cursym.Func().Text.From.Sym.Wrapper() {

src/cmd/internal/obj/s390x/objz.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,19 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
358358
q.Spadj = autosize
359359

360360
q = c.ctxt.EndUnsafePoint(q, c.newprog, -1)
361+
362+
// On Linux, in a cgo binary we may get a SIGSETXID signal early on
363+
// before the signal stack is set, as glibc doesn't allow us to block
364+
// SIGSETXID. So a signal may land on the current stack and clobber
365+
// the content below the SP. We store the LR again after the SP is
366+
// decremented.
367+
q = obj.Appendp(q, c.newprog)
368+
q.As = AMOVD
369+
q.From.Type = obj.TYPE_REG
370+
q.From.Reg = REG_LR
371+
q.To.Type = obj.TYPE_MEM
372+
q.To.Reg = REGSP
373+
q.To.Offset = 0
361374
} else if c.cursym.Func().Text.Mark&LEAF == 0 {
362375
// A very few functions that do not return to their caller
363376
// (e.g. gogo) are not identified as leaves but still have

0 commit comments

Comments
 (0)