diff --git a/src/cmd/internal/obj/loong64/obj.go b/src/cmd/internal/obj/loong64/obj.go index dc05e18c7d..0c1f5c029d 100644 --- a/src/cmd/internal/obj/loong64/obj.go +++ b/src/cmd/internal/obj/loong64/obj.go @@ -260,6 +260,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 {