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: Cherry Zhang <cherryyz@google.com>
diff --git a/src/cmd/internal/obj/arm/obj5.go b/src/cmd/internal/obj/arm/obj5.go
index 59f044e..f7d0f17 100644
--- a/src/cmd/internal/obj/arm/obj5.go
+++ b/src/cmd/internal/obj/arm/obj5.go
@@ -259,9 +259,20 @@
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 @@
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 @@
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
}
}