From 99e37e98b474f27a29ccc89d781f211869b53fa2 Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Wed, 24 Jan 2018 17:17:38 -0500 Subject: [PATCH] cmd/internal/obj/arm: support NOFRAME This adds support on arm for the NOFRAME symbol attribute used by ppc64 and s390x in preference to using a frame size of -4. This is modeled on ppc64's implementation of NOFRAME. This passes toolstash -cmp. Change-Id: I0d15e81770e54222ae329ce4496da0601673677f Reviewed-on: https://go-review.googlesource.com/92039 Run-TryBot: Austin Clements TryBot-Result: Gobot Gobot Reviewed-by: Cherry Zhang --- src/cmd/internal/obj/arm/obj5.go | 37 +++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/src/cmd/internal/obj/arm/obj5.go b/src/cmd/internal/obj/arm/obj5.go index 59f044ec9d..f7d0f17168 100644 --- a/src/cmd/internal/obj/arm/obj5.go +++ b/src/cmd/internal/obj/arm/obj5.go @@ -259,9 +259,20 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { p := c.cursym.Func.Text autoffset := int32(p.To.Offset) - if autoffset < 0 { + if autoffset == -4 { + // Historical way to mark NOFRAME. + p.From.Sym.Set(obj.AttrNoFrame, true) autoffset = 0 } + if autoffset < 0 || autoffset%4 != 0 { + c.ctxt.Diag("frame size %d not 0 or a positive multiple of 4", autoffset) + } + if p.From.Sym.NoFrame() { + if autoffset != 0 { + c.ctxt.Diag("NOFRAME functions must have a frame size of 0, not %d", autoffset) + } + } + cursym.Func.Locals = autoffset cursym.Func.Args = p.To.Val.(int32) @@ -335,15 +346,22 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { o := p.As switch o { case obj.ATEXT: - autosize = int32(p.To.Offset + 4) - if autosize <= 4 { - if cursym.Func.Text.Mark&LEAF != 0 { - p.To.Offset = -4 - autosize = 0 - } + autosize = int32(autoffset) + + if p.Mark&LEAF != 0 && autosize == 0 { + // A leaf function with no locals has no frame. + p.From.Sym.Set(obj.AttrNoFrame, true) + } + + if !p.From.Sym.NoFrame() { + // If there is a stack frame at all, it includes + // space to save the LR. + autosize += 4 } if autosize == 0 && cursym.Func.Text.Mark&LEAF == 0 { + // A very few functions that do not return to their caller + // are not identified as leaves but still have no frame. if ctxt.Debugvlog { ctxt.Logf("save suppressed in: %s\n", cursym.Name) } @@ -351,9 +369,12 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { cursym.Func.Text.Mark |= LEAF } + // FP offsets need an updated p.To.Offset. + p.To.Offset = int64(autosize) - 4 + if cursym.Func.Text.Mark&LEAF != 0 { cursym.Set(obj.AttrLeaf, true) - if autosize == 0 { + if p.From.Sym.NoFrame() { break } } -- 2.50.0