For #59670.
Change-Id: Ie784ba4dd2701e4f455e1abde4a6bfebee4b1387
Reviewed-on: https://go-review.googlesource.com/c/go/+/485496
Reviewed-by: David Chase <drchase@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Austin Clements <austin@google.com>
Auto-Submit: Austin Clements <austin@google.com>
import (
"bytes"
- "cmd/internal/objabi"
"encoding/binary"
"internal/abi"
)
Args uint32
Locals uint32
FuncID abi.FuncID
- FuncFlag objabi.FuncFlag
+ FuncFlag abi.FuncFlag
StartLine int32
File []CUFileIndex
InlTree []InlTreeNode
func (*FuncInfo) ReadFuncID(b []byte) abi.FuncID { return abi.FuncID(b[8]) }
-func (*FuncInfo) ReadFuncFlag(b []byte) objabi.FuncFlag { return objabi.FuncFlag(b[9]) }
+func (*FuncInfo) ReadFuncFlag(b []byte) abi.FuncFlag { return abi.FuncFlag(b[9]) }
func (*FuncInfo) ReadStartLine(b []byte) int32 { return int32(binary.LittleEndian.Uint32(b[12:])) }
"cmd/internal/obj"
"cmd/internal/objabi"
"cmd/internal/sys"
+ "internal/abi"
"internal/buildcfg"
"log"
)
if p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP && p.Spadj == 0 {
f := c.cursym.Func()
- if f.FuncFlag&objabi.FuncFlag_SPWRITE == 0 {
- c.cursym.Func().FuncFlag |= objabi.FuncFlag_SPWRITE
+ if f.FuncFlag&abi.FuncFlagSPWrite == 0 {
+ c.cursym.Func().FuncFlag |= abi.FuncFlagSPWrite
if ctxt.Debugvlog || !ctxt.IsAsm {
ctxt.Logf("auto-SPWRITE: %s %v\n", c.cursym.Name, p)
if !ctxt.IsAsm {
"cmd/internal/objabi"
"cmd/internal/src"
"cmd/internal/sys"
+ "internal/abi"
"internal/buildcfg"
"log"
"math"
if p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP && p.Spadj == 0 {
f := c.cursym.Func()
- if f.FuncFlag&objabi.FuncFlag_SPWRITE == 0 {
- c.cursym.Func().FuncFlag |= objabi.FuncFlag_SPWRITE
+ if f.FuncFlag&abi.FuncFlagSPWrite == 0 {
+ c.cursym.Func().FuncFlag |= abi.FuncFlagSPWrite
if ctxt.Debugvlog || !ctxt.IsAsm {
ctxt.Logf("auto-SPWRITE: %s %v\n", c.cursym.Name, p)
if !ctxt.IsAsm {
Locals int32
Align int32
FuncID abi.FuncID
- FuncFlag objabi.FuncFlag
+ FuncFlag abi.FuncFlag
StartLine int32
Text *Prog
Autot map[*LSym]struct{}
// TextAttrString formats the symbol attributes for printing in as part of a TEXT prog.
func (s *LSym) TextAttrString() string {
attr := s.Attribute.String()
- if s.Func().FuncFlag&objabi.FuncFlag_TOPFRAME != 0 {
+ if s.Func().FuncFlag&abi.FuncFlagTopFrame != 0 {
if attr != "" {
attr += "|"
}
"cmd/internal/obj"
"cmd/internal/objabi"
"cmd/internal/sys"
+ "internal/abi"
"log"
"math"
)
if p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP && p.Spadj == 0 {
f := c.cursym.Func()
- if f.FuncFlag&objabi.FuncFlag_SPWRITE == 0 {
- c.cursym.Func().FuncFlag |= objabi.FuncFlag_SPWRITE
+ if f.FuncFlag&abi.FuncFlagSPWrite == 0 {
+ c.cursym.Func().FuncFlag |= abi.FuncFlagSPWrite
if ctxt.Debugvlog || !ctxt.IsAsm {
ctxt.Logf("auto-SPWRITE: %s %v\n", c.cursym.Name, p)
if !ctxt.IsAsm {
"cmd/internal/sys"
"encoding/binary"
"fmt"
+ "internal/abi"
"log"
"math"
)
if p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP && p.Spadj == 0 {
f := c.cursym.Func()
- if f.FuncFlag&objabi.FuncFlag_SPWRITE == 0 {
- c.cursym.Func().FuncFlag |= objabi.FuncFlag_SPWRITE
+ if f.FuncFlag&abi.FuncFlagSPWrite == 0 {
+ c.cursym.Func().FuncFlag |= abi.FuncFlagSPWrite
if ctxt.Debugvlog || !ctxt.IsAsm {
ctxt.Logf("auto-SPWRITE: %s %v\n", c.cursym.Name, p)
if !ctxt.IsAsm {
"cmd/internal/sys"
"encoding/binary"
"fmt"
+ "internal/abi"
"io"
"log"
"os"
if s.NoSplit() {
fmt.Fprintf(ctxt.Bso, "nosplit ")
}
- if s.Func() != nil && s.Func().FuncFlag&objabi.FuncFlag_TOPFRAME != 0 {
+ if s.Func() != nil && s.Func().FuncFlag&abi.FuncFlagTopFrame != 0 {
fmt.Fprintf(ctxt.Bso, "topframe ")
}
- if s.Func() != nil && s.Func().FuncFlag&objabi.FuncFlag_ASM != 0 {
+ if s.Func() != nil && s.Func().FuncFlag&abi.FuncFlagAsm != 0 {
fmt.Fprintf(ctxt.Bso, "asm ")
}
fmt.Fprintf(ctxt.Bso, "size=%d", s.Size)
"cmd/internal/objabi"
"cmd/internal/src"
"fmt"
+ "internal/abi"
"strings"
)
ctxt.dwarfSym(s)
}
-func (ctxt *Link) toFuncFlag(flag int) objabi.FuncFlag {
- var out objabi.FuncFlag
+func (ctxt *Link) toFuncFlag(flag int) abi.FuncFlag {
+ var out abi.FuncFlag
if flag&TOPFRAME != 0 {
- out |= objabi.FuncFlag_TOPFRAME
+ out |= abi.FuncFlagTopFrame
}
if ctxt.IsAsm {
- out |= objabi.FuncFlag_ASM
+ out |= abi.FuncFlagAsm
}
return out
}
"cmd/internal/objabi"
"cmd/internal/src"
"cmd/internal/sys"
+ "internal/abi"
"log"
)
if p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP && p.Spadj == 0 && p.As != ACMPU {
f := c.cursym.Func()
- if f.FuncFlag&objabi.FuncFlag_SPWRITE == 0 {
- c.cursym.Func().FuncFlag |= objabi.FuncFlag_SPWRITE
+ if f.FuncFlag&abi.FuncFlagSPWrite == 0 {
+ c.cursym.Func().FuncFlag |= abi.FuncFlagSPWrite
if ctxt.Debugvlog || !ctxt.IsAsm {
ctxt.Logf("auto-SPWRITE: %s %v\n", c.cursym.Name, p)
if !ctxt.IsAsm {
"cmd/internal/objabi"
"cmd/internal/sys"
"fmt"
+ "internal/abi"
"log"
"math/bits"
)
if p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP && p.Spadj == 0 {
f := cursym.Func()
- if f.FuncFlag&objabi.FuncFlag_SPWRITE == 0 {
- f.FuncFlag |= objabi.FuncFlag_SPWRITE
+ if f.FuncFlag&abi.FuncFlagSPWrite == 0 {
+ f.FuncFlag |= abi.FuncFlagSPWrite
if ctxt.Debugvlog || !ctxt.IsAsm {
ctxt.Logf("auto-SPWRITE: %s %v\n", cursym.Name, p)
if !ctxt.IsAsm {
"cmd/internal/obj"
"cmd/internal/objabi"
"cmd/internal/sys"
+ "internal/abi"
"log"
"math"
)
if p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP && p.Spadj == 0 {
f := c.cursym.Func()
- if f.FuncFlag&objabi.FuncFlag_SPWRITE == 0 {
- c.cursym.Func().FuncFlag |= objabi.FuncFlag_SPWRITE
+ if f.FuncFlag&abi.FuncFlagSPWrite == 0 {
+ c.cursym.Func().FuncFlag |= abi.FuncFlagSPWrite
if ctxt.Debugvlog || !ctxt.IsAsm {
ctxt.Logf("auto-SPWRITE: %s\n", c.cursym.Name)
if !ctxt.IsAsm {
"cmd/internal/objabi"
"cmd/internal/src"
"cmd/internal/sys"
+ "internal/abi"
"log"
"math"
"path"
default:
if p.To.Type == obj.TYPE_REG && p.To.Reg == REG_SP && p.As != ACMPL && p.As != ACMPQ {
f := cursym.Func()
- if f.FuncFlag&objabi.FuncFlag_SPWRITE == 0 {
- f.FuncFlag |= objabi.FuncFlag_SPWRITE
+ if f.FuncFlag&abi.FuncFlagSPWrite == 0 {
+ f.FuncFlag |= abi.FuncFlagSPWrite
if ctxt.Debugvlog || !ctxt.IsAsm {
ctxt.Logf("auto-SPWRITE: %s %v\n", cursym.Name, p)
if !ctxt.IsAsm {
"strings"
)
-// A FuncFlag records bits about a function, passed to the runtime.
-type FuncFlag uint8
-
-// Note: This list must match the list in runtime/symtab.go.
-const (
- FuncFlag_TOPFRAME = 1 << iota
- FuncFlag_SPWRITE
- FuncFlag_ASM
-)
-
var funcIDs = map[string]abi.FuncID{
"abort": abi.FuncID_abort,
"asmcgocall": abi.FuncID_asmcgocall,
off = sb.SetUint8(ctxt.Arch, off, uint8(funcID))
// flag uint8
- var flag objabi.FuncFlag
+ var flag abi.FuncFlag
if fi.Valid() {
flag = fi.FuncFlag()
}
return (*goobj.FuncInfo)(nil).ReadFuncID(fi.data)
}
-func (fi *FuncInfo) FuncFlag() objabi.FuncFlag {
+func (fi *FuncInfo) FuncFlag() abi.FuncFlag {
return (*goobj.FuncInfo)(nil).ReadFuncFlag(fi.data)
}
// is an entry point, meaning that unwinders should stop when they hit
// this function.
func (fi *FuncInfo) TopFrame() bool {
- return (fi.FuncFlag() & objabi.FuncFlag_TOPFRAME) != 0
+ return (fi.FuncFlag() & abi.FuncFlagTopFrame) != 0
}
type InlTreeNode struct {
package abi
+// A FuncFlag records bits about a function, passed to the runtime.
+type FuncFlag uint8
+
+const (
+ // FuncFlagTopFrame indicates a function that appears at the top of its stack.
+ // The traceback routine stop at such a function and consider that a
+ // successful, complete traversal of the stack.
+ // Examples of TopFrame functions include goexit, which appears
+ // at the top of a user goroutine stack, and mstart, which appears
+ // at the top of a system goroutine stack.
+ FuncFlagTopFrame FuncFlag = 1 << iota
+
+ // FuncFlagSPWrite indicates a function that writes an arbitrary value to SP
+ // (any write other than adding or subtracting a constant amount).
+ // The traceback routines cannot encode such changes into the
+ // pcsp tables, so the function traceback cannot safely unwind past
+ // SPWrite functions. Stopping at an SPWrite function is considered
+ // to be an incomplete unwinding of the stack. In certain contexts
+ // (in particular garbage collector stack scans) that is a fatal error.
+ FuncFlagSPWrite
+
+ // FuncFlagAsm indicates that a function was implemented in assembly.
+ FuncFlagAsm
+)
+
// A FuncID identifies particular functions that need to be treated
// specially by the runtime.
// Note that in some situations involving plugins, there may be multiple
// functions (except at calls).
return false, 0
}
- if fd := funcdata(f, _FUNCDATA_LocalsPointerMaps); fd == nil || f.flag&funcFlag_ASM != 0 {
+ if fd := funcdata(f, _FUNCDATA_LocalsPointerMaps); fd == nil || f.flag&abi.FuncFlagAsm != 0 {
// This is assembly code. Don't assume it's well-formed.
// TODO: Empirically we still need the fd == nil check. Why?
//
if !f.valid() {
throw("preempt at unknown pc")
}
- if f.flag&funcFlag_SPWRITE != 0 {
+ if f.flag&abi.FuncFlagSPWrite != 0 {
println("runtime: unexpected SPWRITE function", funcname(f), "in async preempt")
throw("preempt SPWRITE")
}
cuOffset uint32 // runtime.cutab offset of this function's CU
startLine int32 // line number of start of function (func keyword/TEXT directive)
funcID abi.FuncID // set for certain special runtime functions
- flag funcFlag
+ flag abi.FuncFlag
_ [1]byte // pad
nfuncdata uint8 // must be last, must end on a uint32-aligned boundary
_PCDATA_RestartAtEntry = -5
)
-// A FuncFlag holds bits about a function.
-// This list must match the list in cmd/internal/objabi/funcid.go.
-type funcFlag uint8
-
-const (
- // TOPFRAME indicates a function that appears at the top of its stack.
- // The traceback routine stop at such a function and consider that a
- // successful, complete traversal of the stack.
- // Examples of TOPFRAME functions include goexit, which appears
- // at the top of a user goroutine stack, and mstart, which appears
- // at the top of a system goroutine stack.
- funcFlag_TOPFRAME funcFlag = 1 << iota
-
- // SPWRITE indicates a function that writes an arbitrary value to SP
- // (any write other than adding or subtracting a constant amount).
- // The traceback routines cannot encode such changes into the
- // pcsp tables, so the function traceback cannot safely unwind past
- // SPWRITE functions. Stopping at an SPWRITE function is considered
- // to be an incomplete unwinding of the stack. In certain contexts
- // (in particular garbage collector stack scans) that is a fatal error.
- funcFlag_SPWRITE
-
- // ASM indicates that a function was implemented in assembly.
- funcFlag_ASM
-)
-
// pcHeader holds data used by the pclntab lookups.
type pcHeader struct {
magic uint32 // 0xFFFFFFF1
// but it carefully arranges that during the transition BOTH stacks
// have cgocallback frame valid for unwinding through.
// So we don't need to exclude it with the other SP-writing functions.
- flag &^= funcFlag_SPWRITE
+ flag &^= abi.FuncFlagSPWrite
}
if isSyscall {
// Some Syscall functions write to SP, but they do so only after
// saving the entry PC/SP using entersyscall.
// Since we are using the entry PC/SP, the later SP write doesn't matter.
- flag &^= funcFlag_SPWRITE
+ flag &^= abi.FuncFlagSPWrite
}
// Found an actual function.
// systemstack doesn't have an SP delta (the CALL
// instruction opens the frame), therefore no way
// to check.
- flag &^= funcFlag_SPWRITE
+ flag &^= abi.FuncFlagSPWrite
break
}
gp = gp.m.curg
u.g.set(gp)
frame.sp = gp.sched.sp
u.cgoCtxt = len(gp.cgoCtxt) - 1
- flag &^= funcFlag_SPWRITE
+ flag &^= abi.FuncFlagSPWrite
}
}
frame.fp = frame.sp + uintptr(funcspdelta(f, frame.pc, &u.cache))
}
// Derive link register.
- if flag&funcFlag_TOPFRAME != 0 {
+ if flag&abi.FuncFlagTopFrame != 0 {
// This function marks the top of the stack. Stop the traceback.
frame.lr = 0
- } else if flag&funcFlag_SPWRITE != 0 {
+ } else if flag&abi.FuncFlagSPWrite != 0 {
// The function we are in does a write to SP that we don't know
// how to encode in the spdelta table. Examples include context
// switch routines like runtime.gogo but also any code that switches