From 268dd2e5a7a8919bd26f0a59c847f8268a2437d1 Mon Sep 17 00:00:00 2001 From: Michael Munday Date: Mon, 10 Aug 2020 08:01:21 -0700 Subject: [PATCH] cmd/internal/obj: fix inline marker issue on s390x The optimization that replaces inline markers with pre-existing instructions assumes that 'Prog' values produced by the compiler are still reachable after the assembler has run. This was not true on s390x where the assembler was removing NOP instructions from the linked list of 'Prog' values. This led to broken inlining data which in turn caused an infinite loop in the runtime traceback code. Fix this by stopping the s390x assembler backend removing NOP values. It does not make any difference to the output of the assembler because NOP instructions are 0 bytes long anyway. Fixes #40473. Change-Id: I9b97c494afaae2d5ed6bca4cd428b4132b5f8133 Reviewed-on: https://go-review.googlesource.com/c/go/+/249448 Run-TryBot: Michael Munday TryBot-Result: Gobot Gobot Reviewed-by: Keith Randall --- src/cmd/internal/obj/pcln.go | 15 +++++++++++++++ src/cmd/internal/obj/s390x/objz.go | 11 ----------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/cmd/internal/obj/pcln.go b/src/cmd/internal/obj/pcln.go index 1f7ccf47ef..bffeda041d 100644 --- a/src/cmd/internal/obj/pcln.go +++ b/src/cmd/internal/obj/pcln.go @@ -278,6 +278,21 @@ func linkpcln(ctxt *Link, cursym *LSym) { funcpctab(ctxt, &pcln.Pcfile, cursym, "pctofile", pctofileline, pcln) funcpctab(ctxt, &pcln.Pcline, cursym, "pctoline", pctofileline, nil) + // Check that all the Progs used as inline markers are still reachable. + // See issue #40473. + inlMarkProgs := make(map[*Prog]struct{}, len(cursym.Func.InlMarks)) + for _, inlMark := range cursym.Func.InlMarks { + inlMarkProgs[inlMark.p] = struct{}{} + } + for p := cursym.Func.Text; p != nil; p = p.Link { + if _, ok := inlMarkProgs[p]; ok { + delete(inlMarkProgs, p) + } + } + if len(inlMarkProgs) > 0 { + ctxt.Diag("one or more instructions used as inline markers are no longer reachable") + } + pcinlineState := new(pcinlineState) funcpctab(ctxt, &pcln.Pcinline, cursym, "pctoinline", pcinlineState.pctoinline, nil) for _, inlMark := range cursym.Func.InlMarks { diff --git a/src/cmd/internal/obj/s390x/objz.go b/src/cmd/internal/obj/s390x/objz.go index b14dc810fa..ef6335d849 100644 --- a/src/cmd/internal/obj/s390x/objz.go +++ b/src/cmd/internal/obj/s390x/objz.go @@ -283,17 +283,6 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { ACMPUBNE: q = p p.Mark |= BRANCH - if p.Pcond != nil { - q := p.Pcond - for q.As == obj.ANOP { - q = q.Link - p.Pcond = q - } - } - - case obj.ANOP: - q.Link = p.Link /* q is non-nop */ - p.Link.Mark |= p.Mark default: q = p -- 2.50.0