diff options
| author | Josh Bleecher Snyder <josharian@gmail.com> | 2017-04-11 15:15:04 -0700 |
|---|---|---|
| committer | Josh Bleecher Snyder <josharian@gmail.com> | 2017-04-12 21:53:39 +0000 |
| commit | ce3ee7cdae9059a2cfb1a801a34712f413afb211 (patch) | |
| tree | ec23161c4ba9d7a5fe95af90813569e2c983525a /src/cmd/internal | |
| parent | 4eb48a336e5a7ac519611cf8360909e0ac37f018 (diff) | |
| download | go-ce3ee7cdae9059a2cfb1a801a34712f413afb211.tar.xz | |
cmd/internal/obj: stop storing Text flags in From3
Prior to this CL, flags such as NOSPLIT
on ATEXT Progs were stored in From3.Offset.
Some but not all of those flags were also
duplicated into From.Sym.Attribute.
This CL migrates all of those flags into
From.Sym.Attribute and stops creating a From3.
A side-effect of this is that printing an
ATEXT Prog can no longer simply dump From3.Offset.
That's kind of good, since the raw flag value
wasn't very informative anyway, but it did
necessitate a bunch of updates to the cmd/asm tests.
The reason I'm doing this work now is that
avoiding storing flags in both From.Sym and From3.Offset
simplifies some other changes to fix the data
race first described in CL 40254.
This CL almost passes toolstash-check -all.
The only changes are in cases where the assembler
has decided that a function's flags may be altered,
e.g. to make a function with no calls in it NOSPLIT.
Prior to this CL, that information was not printed.
Sample before:
"".Ctz64 t=1 size=63 args=0x10 locals=0x0
0x0000 00000 (/Users/josh/go/tip/src/runtime/internal/sys/intrinsics.go:35) TEXT "".Ctz64(SB), $0-16
0x0000 00000 (/Users/josh/go/tip/src/runtime/internal/sys/intrinsics.go:35) FUNCDATA $0, gclocals·f207267fbf96a0178e8758c6e3e0ce28(SB)
Sample after:
"".Ctz64 t=1 nosplit size=63 args=0x10 locals=0x0
0x0000 00000 (/Users/josh/go/tip/src/runtime/internal/sys/intrinsics.go:35) TEXT "".Ctz64(SB), NOSPLIT, $0-16
0x0000 00000 (/Users/josh/go/tip/src/runtime/internal/sys/intrinsics.go:35) FUNCDATA $0, gclocals·f207267fbf96a0178e8758c6e3e0ce28(SB)
Observe the additional "nosplit" in the first line
and the additional "NOSPLIT" in the second line.
Updates #15756
Change-Id: I5c59bd8f3bdc7c780361f801d94a261f0aef3d13
Reviewed-on: https://go-review.googlesource.com/40495
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src/cmd/internal')
| -rw-r--r-- | src/cmd/internal/obj/arm/obj5.go | 8 | ||||
| -rw-r--r-- | src/cmd/internal/obj/arm64/obj7.go | 6 | ||||
| -rw-r--r-- | src/cmd/internal/obj/link.go | 53 | ||||
| -rw-r--r-- | src/cmd/internal/obj/mips/obj0.go | 8 | ||||
| -rw-r--r-- | src/cmd/internal/obj/plist.go | 18 | ||||
| -rw-r--r-- | src/cmd/internal/obj/ppc64/obj9.go | 16 | ||||
| -rw-r--r-- | src/cmd/internal/obj/s390x/objz.go | 16 | ||||
| -rw-r--r-- | src/cmd/internal/obj/util.go | 16 | ||||
| -rw-r--r-- | src/cmd/internal/obj/x86/obj6.go | 16 |
9 files changed, 99 insertions, 58 deletions
diff --git a/src/cmd/internal/obj/arm/obj5.go b/src/cmd/internal/obj/arm/obj5.go index cec7c212d4..fb63712918 100644 --- a/src/cmd/internal/obj/arm/obj5.go +++ b/src/cmd/internal/obj/arm/obj5.go @@ -357,7 +357,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { } } - if p.From3.Offset&obj.NOSPLIT == 0 { + if !p.From.Sym.NoSplit() { p = c.stacksplit(p, autosize) // emit split check } @@ -373,7 +373,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { p.To.Reg = REGSP p.Spadj = autosize - if cursym.Text.From3.Offset&obj.WRAPPER != 0 { + if cursym.Text.From.Sym.Wrapper() { // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame // // MOVW g_panic(g), R1 @@ -534,7 +534,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { } case ADIV, ADIVU, AMOD, AMODU: - if cursym.Text.From3.Offset&obj.NOSPLIT != 0 { + if cursym.Text.From.Sym.NoSplit() { ctxt.Diag("cannot divide in NOSPLIT function") } const debugdivmod = false @@ -842,7 +842,7 @@ func (c *ctxt5) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { switch { case c.cursym.CFunc(): morestack = "runtime.morestackc" - case c.cursym.Text.From3.Offset&obj.NEEDCTXT == 0: + case !c.cursym.Text.From.Sym.NeedCtxt(): morestack = "runtime.morestack_noctxt" } call.To.Sym = c.ctxt.Lookup(morestack, 0) diff --git a/src/cmd/internal/obj/arm64/obj7.go b/src/cmd/internal/obj/arm64/obj7.go index 5c56701363..1c8a40f9d6 100644 --- a/src/cmd/internal/obj/arm64/obj7.go +++ b/src/cmd/internal/obj/arm64/obj7.go @@ -204,7 +204,7 @@ func (c *ctxt7) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { switch { case c.cursym.CFunc(): morestack = "runtime.morestackc" - case c.cursym.Text.From3.Offset&obj.NEEDCTXT == 0: + case !c.cursym.Text.From.Sym.NeedCtxt(): morestack = "runtime.morestack_noctxt" } call.To.Sym = c.ctxt.Lookup(morestack, 0) @@ -552,7 +552,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { c.cursym.Text.Mark |= LEAF } - if !(p.From3.Offset&obj.NOSPLIT != 0) { + if !p.From.Sym.NoSplit() { p = c.stacksplit(p, c.autosize) // emit split check } @@ -614,7 +614,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { q1.Spadj = aoffset } - if c.cursym.Text.From3.Offset&obj.WRAPPER != 0 { + if c.cursym.Text.From.Sym.Wrapper() { // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame // // MOV g_panic(g), R1 diff --git a/src/cmd/internal/obj/link.go b/src/cmd/internal/obj/link.go index d5d96f792e..fc0305344f 100644 --- a/src/cmd/internal/obj/link.go +++ b/src/cmd/internal/obj/link.go @@ -261,14 +261,6 @@ func (p *Prog) From3Type() AddrType { return p.From3.Type } -// From3Offset returns From3.Offset, or 0 when From3 is nil. -func (p *Prog) From3Offset() int64 { - if p.From3 == nil { - return 0 - } - return p.From3.Offset -} - // An As denotes an assembler opcode. // There are some portable opcodes, declared here in package obj, // that are common to all architectures. @@ -347,6 +339,9 @@ const ( AttrCFunc AttrNoSplit AttrLeaf + AttrWrapper + AttrNeedCtxt + AttrNoFrame AttrSeenGlobl AttrOnList @@ -379,6 +374,9 @@ func (a Attribute) SeenGlobl() bool { return a&AttrSeenGlobl != 0 } func (a Attribute) OnList() bool { return a&AttrOnList != 0 } func (a Attribute) ReflectMethod() bool { return a&AttrReflectMethod != 0 } func (a Attribute) Local() bool { return a&AttrLocal != 0 } +func (a Attribute) Wrapper() bool { return a&AttrWrapper != 0 } +func (a Attribute) NeedCtxt() bool { return a&AttrNeedCtxt != 0 } +func (a Attribute) NoFrame() bool { return a&AttrNoFrame != 0 } func (a *Attribute) Set(flag Attribute, value bool) { if value { @@ -388,6 +386,45 @@ func (a *Attribute) Set(flag Attribute, value bool) { } } +var textAttrStrings = [...]struct { + bit Attribute + s string +}{ + {bit: AttrDuplicateOK, s: "DUPOK"}, + {bit: AttrMakeTypelink, s: ""}, + {bit: AttrCFunc, s: "CFUNC"}, + {bit: AttrNoSplit, s: "NOSPLIT"}, + {bit: AttrLeaf, s: "LEAF"}, + {bit: AttrSeenGlobl, s: ""}, + {bit: AttrOnList, s: ""}, + {bit: AttrReflectMethod, s: "REFLECTMETHOD"}, + {bit: AttrLocal, s: "LOCAL"}, + {bit: AttrWrapper, s: "WRAPPER"}, + {bit: AttrNeedCtxt, s: "NEEDCTXT"}, + {bit: AttrNoFrame, s: "NOFRAME"}, +} + +// TextAttrString formats a for printing in as part of a TEXT prog. +func (a Attribute) TextAttrString() string { + var s string + for _, x := range textAttrStrings { + if a&x.bit != 0 { + if x.s != "" { + s += x.s + "|" + } + a &^= x.bit + } + } + if a != 0 { + s += fmt.Sprintf("UnknownAttribute(%d)|", a) + } + // Chop off trailing |, if present. + if len(s) > 0 { + s = s[:len(s)-1] + } + return s +} + // The compiler needs LSym to satisfy fmt.Stringer, because it stores // an LSym in ssa.ExternSymbol. func (s *LSym) String() string { diff --git a/src/cmd/internal/obj/mips/obj0.go b/src/cmd/internal/obj/mips/obj0.go index bef1b4d551..6ea156e32c 100644 --- a/src/cmd/internal/obj/mips/obj0.go +++ b/src/cmd/internal/obj/mips/obj0.go @@ -286,7 +286,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { p.To.Offset = int64(autosize) - ctxt.FixedFrameSize() - if p.From3.Offset&obj.NOSPLIT == 0 { + if !p.From.Sym.NoSplit() { p = c.stacksplit(p, autosize) // emit split check } @@ -316,7 +316,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { q.To.Reg = REGSP q.Spadj = +autosize } else if c.cursym.Text.Mark&LEAF == 0 { - if c.cursym.Text.From3.Offset&obj.NOSPLIT != 0 { + if c.cursym.Text.From.Sym.NoSplit() { if ctxt.Debugvlog { ctxt.Logf("save suppressed in: %s\n", c.cursym.Name) } @@ -330,7 +330,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { break } - if c.cursym.Text.From3.Offset&obj.WRAPPER != 0 { + if c.cursym.Text.From.Sym.Wrapper() { // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame // // MOV g_panic(g), R1 @@ -759,7 +759,7 @@ func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { p.To.Type = obj.TYPE_BRANCH if c.cursym.CFunc() { p.To.Sym = c.ctxt.Lookup("runtime.morestackc", 0) - } else if c.cursym.Text.From3.Offset&obj.NEEDCTXT == 0 { + } else if !c.cursym.Text.From.Sym.NeedCtxt() { p.To.Sym = c.ctxt.Lookup("runtime.morestack_noctxt", 0) } else { p.To.Sym = c.ctxt.Lookup("runtime.morestack", 0) diff --git a/src/cmd/internal/obj/plist.go b/src/cmd/internal/obj/plist.go index 6614f7d74e..b2acd0f29d 100644 --- a/src/cmd/internal/obj/plist.go +++ b/src/cmd/internal/obj/plist.go @@ -112,7 +112,7 @@ func Flushplist(ctxt *Link, plist *Plist, newprog ProgAlloc) { ctxt.Text = append(ctxt.Text, text...) } -func (ctxt *Link) InitTextSym(p *Prog) { +func (ctxt *Link) InitTextSym(p *Prog, flag int) { if p.As != ATEXT { ctxt.Diag("InitTextSym non-ATEXT: %v", p) } @@ -132,16 +132,12 @@ func (ctxt *Link) InitTextSym(p *Prog) { ctxt.Diag("symbol %s listed multiple times", s.Name) } s.Set(AttrOnList, true) - flag := int(p.From3Offset()) - if flag&DUPOK != 0 { - s.Set(AttrDuplicateOK, true) - } - if flag&NOSPLIT != 0 { - s.Set(AttrNoSplit, true) - } - if flag&REFLECTMETHOD != 0 { - s.Set(AttrReflectMethod, true) - } + s.Set(AttrDuplicateOK, flag&DUPOK != 0) + s.Set(AttrNoSplit, flag&NOSPLIT != 0) + s.Set(AttrReflectMethod, flag&REFLECTMETHOD != 0) + s.Set(AttrWrapper, flag&WRAPPER != 0) + s.Set(AttrNeedCtxt, flag&NEEDCTXT != 0) + s.Set(AttrNoFrame, flag&NOFRAME != 0) s.Type = STEXT s.Text = p } diff --git a/src/cmd/internal/obj/ppc64/obj9.go b/src/cmd/internal/obj/ppc64/obj9.go index fb08b13fde..3e36ed16a7 100644 --- a/src/cmd/internal/obj/ppc64/obj9.go +++ b/src/cmd/internal/obj/ppc64/obj9.go @@ -240,13 +240,13 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { textstksiz := p.To.Offset if textstksiz == -8 { // Compatibility hack. - p.From3.Offset |= obj.NOFRAME + p.From.Sym.Set(obj.AttrNoFrame, true) textstksiz = 0 } if textstksiz%8 != 0 { c.ctxt.Diag("frame size %d not a multiple of 8", textstksiz) } - if p.From3.Offset&obj.NOFRAME != 0 { + if p.From.Sym.NoFrame() { if textstksiz != 0 { c.ctxt.Diag("NOFRAME functions must have a frame size of 0, not %d", textstksiz) } @@ -439,10 +439,10 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { if p.Mark&LEAF != 0 && autosize == 0 { // A leaf function with no locals has no frame. - p.From3.Offset |= obj.NOFRAME + p.From.Sym.Set(obj.AttrNoFrame, true) } - if p.From3.Offset&obj.NOFRAME == 0 { + if !p.From.Sym.NoFrame() { // If there is a stack frame at all, it includes // space to save the LR. autosize += int32(c.ctxt.FixedFrameSize()) @@ -451,7 +451,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { if p.Mark&LEAF != 0 && autosize < obj.StackSmall { // A leaf function with a small stack can be marked // NOSPLIT, avoiding a stack check. - p.From3.Offset |= obj.NOSPLIT + p.From.Sym.Set(obj.AttrNoSplit, true) } p.To.Offset = int64(autosize) @@ -492,7 +492,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { rel.Type = obj.R_ADDRPOWER_PCREL } - if c.cursym.Text.From3.Offset&obj.NOSPLIT == 0 { + if !c.cursym.Text.From.Sym.NoSplit() { q = c.stacksplit(q, autosize) // emit split check } @@ -572,7 +572,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { q.To.Offset = 24 } - if c.cursym.Text.From3.Offset&obj.WRAPPER != 0 { + if c.cursym.Text.From.Sym.Wrapper() { // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame // // MOVD g_panic(g), R3 @@ -950,7 +950,7 @@ func (c *ctxt9) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { var morestacksym *obj.LSym if c.cursym.CFunc() { morestacksym = c.ctxt.Lookup("runtime.morestackc", 0) - } else if c.cursym.Text.From3.Offset&obj.NEEDCTXT == 0 { + } else if !c.cursym.Text.From.Sym.NeedCtxt() { morestacksym = c.ctxt.Lookup("runtime.morestack_noctxt", 0) } else { morestacksym = c.ctxt.Lookup("runtime.morestack", 0) diff --git a/src/cmd/internal/obj/s390x/objz.go b/src/cmd/internal/obj/s390x/objz.go index 8b86dbb404..99d9609e4f 100644 --- a/src/cmd/internal/obj/s390x/objz.go +++ b/src/cmd/internal/obj/s390x/objz.go @@ -204,13 +204,13 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { textstksiz := p.To.Offset if textstksiz == -8 { // Compatibility hack. - p.From3.Offset |= obj.NOFRAME + p.From.Sym.Set(obj.AttrNoFrame, true) textstksiz = 0 } if textstksiz%8 != 0 { c.ctxt.Diag("frame size %d not a multiple of 8", textstksiz) } - if p.From3.Offset&obj.NOFRAME != 0 { + if p.From.Sym.NoFrame() { if textstksiz != 0 { c.ctxt.Diag("NOFRAME functions must have a frame size of 0, not %d", textstksiz) } @@ -293,10 +293,10 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { if p.Mark&LEAF != 0 && autosize == 0 { // A leaf function with no locals has no frame. - p.From3.Offset |= obj.NOFRAME + p.From.Sym.Set(obj.AttrNoFrame, true) } - if p.From3.Offset&obj.NOFRAME == 0 { + if !p.From.Sym.NoFrame() { // If there is a stack frame at all, it includes // space to save the LR. autosize += int32(c.ctxt.FixedFrameSize()) @@ -305,14 +305,14 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { if p.Mark&LEAF != 0 && autosize < obj.StackSmall { // A leaf function with a small stack can be marked // NOSPLIT, avoiding a stack check. - p.From3.Offset |= obj.NOSPLIT + p.From.Sym.Set(obj.AttrNoSplit, true) } p.To.Offset = int64(autosize) q := p - if p.From3.Offset&obj.NOSPLIT == 0 { + if !p.From.Sym.NoSplit() { p, pPreempt = c.stacksplitPre(p, autosize) // emit pre part of split check pPre = p wasSplit = true //need post part of split @@ -352,7 +352,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { break } - if c.cursym.Text.From3.Offset&obj.WRAPPER != 0 { + if c.cursym.Text.From.Sym.Wrapper() { // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame // // MOVD g_panic(g), R3 @@ -682,7 +682,7 @@ func (c *ctxtz) stacksplitPost(p *obj.Prog, pPre *obj.Prog, pPreempt *obj.Prog, p.To.Type = obj.TYPE_BRANCH if c.cursym.CFunc() { p.To.Sym = c.ctxt.Lookup("runtime.morestackc", 0) - } else if c.cursym.Text.From3.Offset&obj.NEEDCTXT == 0 { + } else if !c.cursym.Text.From.Sym.NeedCtxt() { p.To.Sym = c.ctxt.Lookup("runtime.morestack_noctxt", 0) } else { p.To.Sym = c.ctxt.Lookup("runtime.morestack", 0) diff --git a/src/cmd/internal/obj/util.go b/src/cmd/internal/obj/util.go index 97a3fe95bc..e800ea6efb 100644 --- a/src/cmd/internal/obj/util.go +++ b/src/cmd/internal/obj/util.go @@ -143,16 +143,24 @@ func (p *Prog) String() string { sep = ", " } if p.From3Type() != TYPE_NONE { - if p.From3.Type == TYPE_CONST && p.As == ATEXT { - // Special case - omit $. - fmt.Fprintf(&buf, "%s%d", sep, p.From3.Offset) - } else if quadOpAmd64 { + if quadOpAmd64 { fmt.Fprintf(&buf, "%s%v", sep, Rconv(int(p.From3.Reg))) } else { fmt.Fprintf(&buf, "%s%v", sep, Dconv(p, p.From3)) } sep = ", " } + if p.As == ATEXT { + // If there are attributes, print them. Otherwise, skip the comma. + // In short, print one of these two: + // TEXT foo(SB), DUPOK|NOSPLIT, $0 + // TEXT foo(SB), $0 + s := p.From.Sym.Attribute.TextAttrString() + if s != "" { + fmt.Fprintf(&buf, "%s%s", sep, s) + sep = ", " + } + } if p.To.Type != TYPE_NONE { fmt.Fprintf(&buf, "%s%v", sep, Dconv(p, &p.To)) } diff --git a/src/cmd/internal/obj/x86/obj6.go b/src/cmd/internal/obj/x86/obj6.go index fc39efeaa8..c783bc0315 100644 --- a/src/cmd/internal/obj/x86/obj6.go +++ b/src/cmd/internal/obj/x86/obj6.go @@ -609,8 +609,8 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { var bpsize int if ctxt.Arch.Family == sys.AMD64 && ctxt.Framepointer_enabled && - p.From3.Offset&obj.NOFRAME == 0 && // (1) below - !(autoffset == 0 && p.From3.Offset&obj.NOSPLIT != 0) && // (2) below + !p.From.Sym.NoFrame() && // (1) below + !(autoffset == 0 && p.From.Sym.NoSplit()) && // (2) below !(autoffset == 0 && !hasCall) { // (3) below // Make room to save a base pointer. // There are 2 cases we must avoid: @@ -637,7 +637,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { } // TODO(rsc): Remove 'ctxt.Arch.Family == sys.AMD64 &&'. - if ctxt.Arch.Family == sys.AMD64 && autoffset < obj.StackSmall && p.From3Offset()&obj.NOSPLIT == 0 { + if ctxt.Arch.Family == sys.AMD64 && autoffset < obj.StackSmall && !p.From.Sym.NoSplit() { leaf := true LeafSearch: for q := p; q != nil; q = q.Link { @@ -659,16 +659,16 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { } if leaf { - p.From3.Offset |= obj.NOSPLIT + p.From.Sym.Set(obj.AttrNoSplit, true) } } - if p.From3Offset()&obj.NOSPLIT == 0 || p.From3Offset()&obj.WRAPPER != 0 { + if !p.From.Sym.NoSplit() || p.From.Sym.Wrapper() { p = obj.Appendp(p, newprog) p = load_g_cx(ctxt, p, newprog) // load g into CX } - if cursym.Text.From3Offset()&obj.NOSPLIT == 0 { + if !cursym.Text.From.Sym.NoSplit() { p = stacksplit(ctxt, cursym, p, newprog, autoffset, int32(textarg)) // emit split check } @@ -709,7 +709,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { p.To.Reg = REG_BP } - if cursym.Text.From3Offset()&obj.WRAPPER != 0 { + if cursym.Text.From.Sym.Wrapper() { // if g._panic != nil && g._panic.argp == FP { // g._panic.argp = bottom-of-frame // } @@ -1150,7 +1150,7 @@ func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, newprog obj.ProgA switch { case cursym.CFunc(): morestack = "runtime.morestackc" - case cursym.Text.From3Offset()&obj.NEEDCTXT == 0: + case !cursym.Text.From.Sym.NeedCtxt(): morestack = "runtime.morestack_noctxt" } call.To.Sym = ctxt.Lookup(morestack, 0) |
