]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/arm: support NOFRAME
authorAustin Clements <austin@google.com>
Wed, 24 Jan 2018 22:17:38 +0000 (17:17 -0500)
committerAustin Clements <austin@google.com>
Mon, 12 Feb 2018 21:41:24 +0000 (21:41 +0000)
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>
src/cmd/internal/obj/arm/obj5.go

index 59f044ec9ddb2a8546db8f22b48c3e9e224364ad..f7d0f17168e15128877815c40ed968ae90b39701 100644 (file)
@@ -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
                                }
                        }