Commit 99e37e98 authored by Austin Clements's avatar Austin Clements

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 <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarCherry Zhang <cherryyz@google.com>
parent 8a064c60
...@@ -259,9 +259,20 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { ...@@ -259,9 +259,20 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
p := c.cursym.Func.Text p := c.cursym.Func.Text
autoffset := int32(p.To.Offset) 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 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.Locals = autoffset
cursym.Func.Args = p.To.Val.(int32) cursym.Func.Args = p.To.Val.(int32)
...@@ -335,15 +346,22 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { ...@@ -335,15 +346,22 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
o := p.As o := p.As
switch o { switch o {
case obj.ATEXT: case obj.ATEXT:
autosize = int32(p.To.Offset + 4) autosize = int32(autoffset)
if autosize <= 4 {
if cursym.Func.Text.Mark&LEAF != 0 { if p.Mark&LEAF != 0 && autosize == 0 {
p.To.Offset = -4 // A leaf function with no locals has no frame.
autosize = 0 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 { 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 { if ctxt.Debugvlog {
ctxt.Logf("save suppressed in: %s\n", cursym.Name) ctxt.Logf("save suppressed in: %s\n", cursym.Name)
} }
...@@ -351,9 +369,12 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { ...@@ -351,9 +369,12 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
cursym.Func.Text.Mark |= LEAF 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 { if cursym.Func.Text.Mark&LEAF != 0 {
cursym.Set(obj.AttrLeaf, true) cursym.Set(obj.AttrLeaf, true)
if autosize == 0 { if p.From.Sym.NoFrame() {
break break
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment