mirror of
https://github.com/golang/go
synced 2024-09-29 07:14:29 -06:00
internal/abi, runtime, cmd: merge PCDATA_* and FUNCDATA_* consts into internal/abi
We also rename the constants related to unsafe-points: currently, they follow the same naming scheme as the PCDATA table indexes, but are not PCDATA table indexes. For #59670. Change-Id: I06529fecfae535be5fe7d9ac56c886b9106c74fd Reviewed-on: https://go-review.googlesource.com/c/go/+/485497 Run-TryBot: Austin Clements <austin@google.com> Reviewed-by: David Chase <drchase@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Auto-Submit: Austin Clements <austin@google.com> Reviewed-by: Cherry Mui <cherryyz@google.com>
This commit is contained in:
parent
2668a190ba
commit
7843ca83e7
@ -6,6 +6,7 @@ package asm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"internal/abi"
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/scanner"
|
||||
@ -16,7 +17,6 @@ import (
|
||||
"cmd/internal/obj"
|
||||
"cmd/internal/obj/ppc64"
|
||||
"cmd/internal/obj/x86"
|
||||
"cmd/internal/objabi"
|
||||
"cmd/internal/sys"
|
||||
)
|
||||
|
||||
@ -169,7 +169,7 @@ func (p *Parser) asmText(operands [][]lex.Token) {
|
||||
frameSize = -frameSize
|
||||
}
|
||||
op = op[1:]
|
||||
argSize := int64(objabi.ArgsSizeUnknown)
|
||||
argSize := int64(abi.ArgsSizeUnknown)
|
||||
if len(op) > 0 {
|
||||
// There is an argument size. It must be a minus sign followed by a non-negative integer literal.
|
||||
if len(op) != 2 || op[0].ScanToken != '-' || op[1].ScanToken != scanner.Int {
|
||||
|
@ -6,6 +6,7 @@ package liveness
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"internal/abi"
|
||||
|
||||
"cmd/compile/internal/base"
|
||||
"cmd/compile/internal/bitvec"
|
||||
@ -13,7 +14,6 @@ import (
|
||||
"cmd/compile/internal/objw"
|
||||
"cmd/compile/internal/ssa"
|
||||
"cmd/internal/obj"
|
||||
"cmd/internal/objabi"
|
||||
)
|
||||
|
||||
// Argument liveness tracking.
|
||||
@ -221,7 +221,7 @@ func ArgLiveness(fn *ir.Func, f *ssa.Func, pp *objw.Progs) (blockIdx, valueIdx m
|
||||
//lv.print()
|
||||
|
||||
p := pp.Prog(obj.AFUNCDATA)
|
||||
p.From.SetConst(objabi.FUNCDATA_ArgLiveInfo)
|
||||
p.From.SetConst(abi.FUNCDATA_ArgLiveInfo)
|
||||
p.To.Type = obj.TYPE_MEM
|
||||
p.To.Name = obj.NAME_EXTERN
|
||||
p.To.Sym = lsym
|
||||
|
@ -31,8 +31,9 @@ import (
|
||||
"cmd/compile/internal/types"
|
||||
"cmd/internal/notsha256"
|
||||
"cmd/internal/obj"
|
||||
"cmd/internal/objabi"
|
||||
"cmd/internal/src"
|
||||
|
||||
rtabi "internal/abi"
|
||||
)
|
||||
|
||||
// OpVarDef is an annotation for the liveness analysis, marking a place
|
||||
@ -1361,20 +1362,20 @@ func Compute(curfn *ir.Func, f *ssa.Func, stkptrsize int64, pp *objw.Progs) (Map
|
||||
fninfo.GCArgs, fninfo.GCLocals = lv.emit()
|
||||
|
||||
p := pp.Prog(obj.AFUNCDATA)
|
||||
p.From.SetConst(objabi.FUNCDATA_ArgsPointerMaps)
|
||||
p.From.SetConst(rtabi.FUNCDATA_ArgsPointerMaps)
|
||||
p.To.Type = obj.TYPE_MEM
|
||||
p.To.Name = obj.NAME_EXTERN
|
||||
p.To.Sym = fninfo.GCArgs
|
||||
|
||||
p = pp.Prog(obj.AFUNCDATA)
|
||||
p.From.SetConst(objabi.FUNCDATA_LocalsPointerMaps)
|
||||
p.From.SetConst(rtabi.FUNCDATA_LocalsPointerMaps)
|
||||
p.To.Type = obj.TYPE_MEM
|
||||
p.To.Name = obj.NAME_EXTERN
|
||||
p.To.Sym = fninfo.GCLocals
|
||||
|
||||
if x := lv.emitStackObjects(); x != nil {
|
||||
p := pp.Prog(obj.AFUNCDATA)
|
||||
p.From.SetConst(objabi.FUNCDATA_StackObjects)
|
||||
p.From.SetConst(rtabi.FUNCDATA_StackObjects)
|
||||
p.To.Type = obj.TYPE_MEM
|
||||
p.To.Name = obj.NAME_EXTERN
|
||||
p.To.Sym = x
|
||||
|
@ -34,8 +34,8 @@ import (
|
||||
"cmd/compile/internal/base"
|
||||
"cmd/compile/internal/ir"
|
||||
"cmd/internal/obj"
|
||||
"cmd/internal/objabi"
|
||||
"cmd/internal/src"
|
||||
"internal/abi"
|
||||
)
|
||||
|
||||
var sharedProgArray = new([10000]obj.Prog) // *T instead of T to work around issue 19839
|
||||
@ -144,18 +144,18 @@ func (pp *Progs) Prog(as obj.As) *obj.Prog {
|
||||
idx := pp.NextLive.StackMapIndex
|
||||
pp.PrevLive.StackMapIndex = idx
|
||||
p := pp.Prog(obj.APCDATA)
|
||||
p.From.SetConst(objabi.PCDATA_StackMapIndex)
|
||||
p.From.SetConst(abi.PCDATA_StackMapIndex)
|
||||
p.To.SetConst(int64(idx))
|
||||
}
|
||||
if pp.NextLive.IsUnsafePoint != pp.PrevLive.IsUnsafePoint {
|
||||
// Emit unsafe-point marker.
|
||||
pp.PrevLive.IsUnsafePoint = pp.NextLive.IsUnsafePoint
|
||||
p := pp.Prog(obj.APCDATA)
|
||||
p.From.SetConst(objabi.PCDATA_UnsafePoint)
|
||||
p.From.SetConst(abi.PCDATA_UnsafePoint)
|
||||
if pp.NextLive.IsUnsafePoint {
|
||||
p.To.SetConst(objabi.PCDATA_UnsafePointUnsafe)
|
||||
p.To.SetConst(abi.UnsafePointUnsafe)
|
||||
} else {
|
||||
p.To.SetConst(objabi.PCDATA_UnsafePointSafe)
|
||||
p.To.SetConst(abi.UnsafePointSafe)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,9 +27,10 @@ import (
|
||||
"cmd/compile/internal/typecheck"
|
||||
"cmd/compile/internal/types"
|
||||
"cmd/internal/obj"
|
||||
"cmd/internal/objabi"
|
||||
"cmd/internal/src"
|
||||
"cmd/internal/sys"
|
||||
|
||||
rtabi "internal/abi"
|
||||
)
|
||||
|
||||
var ssaConfig *ssa.Config
|
||||
@ -6726,7 +6727,7 @@ func emitArgInfo(e *ssafn, f *ssa.Func, pp *objw.Progs) {
|
||||
|
||||
// Emit a funcdata pointing at the arg info data.
|
||||
p := pp.Prog(obj.AFUNCDATA)
|
||||
p.From.SetConst(objabi.FUNCDATA_ArgInfo)
|
||||
p.From.SetConst(rtabi.FUNCDATA_ArgInfo)
|
||||
p.To.Type = obj.TYPE_MEM
|
||||
p.To.Name = obj.NAME_EXTERN
|
||||
p.To.Sym = x
|
||||
@ -6893,7 +6894,7 @@ func emitWrappedFuncInfo(e *ssafn, pp *objw.Progs) {
|
||||
|
||||
// Emit a funcdata pointing at the wrap info data.
|
||||
p := pp.Prog(obj.AFUNCDATA)
|
||||
p.From.SetConst(objabi.FUNCDATA_WrapInfo)
|
||||
p.From.SetConst(rtabi.FUNCDATA_WrapInfo)
|
||||
p.To.Type = obj.TYPE_MEM
|
||||
p.To.Name = obj.NAME_EXTERN
|
||||
p.To.Sym = x
|
||||
@ -6915,7 +6916,7 @@ func genssa(f *ssa.Func, pp *objw.Progs) {
|
||||
// This function uses open-coded defers -- write out the funcdata
|
||||
// info that we computed at the end of genssa.
|
||||
p := pp.Prog(obj.AFUNCDATA)
|
||||
p.From.SetConst(objabi.FUNCDATA_OpenCodedDeferInfo)
|
||||
p.From.SetConst(rtabi.FUNCDATA_OpenCodedDeferInfo)
|
||||
p.To.Type = obj.TYPE_MEM
|
||||
p.To.Name = obj.NAME_EXTERN
|
||||
p.To.Sym = openDeferInfo
|
||||
@ -6987,7 +6988,7 @@ func genssa(f *ssa.Func, pp *objw.Progs) {
|
||||
if idx, ok := argLiveBlockMap[b.ID]; ok && idx != argLiveIdx {
|
||||
argLiveIdx = idx
|
||||
p := s.pp.Prog(obj.APCDATA)
|
||||
p.From.SetConst(objabi.PCDATA_ArgLiveIndex)
|
||||
p.From.SetConst(rtabi.PCDATA_ArgLiveIndex)
|
||||
p.To.SetConst(int64(idx))
|
||||
}
|
||||
|
||||
@ -7051,7 +7052,7 @@ func genssa(f *ssa.Func, pp *objw.Progs) {
|
||||
if idx, ok := argLiveValueMap[v.ID]; ok && idx != argLiveIdx {
|
||||
argLiveIdx = idx
|
||||
p := s.pp.Prog(obj.APCDATA)
|
||||
p.From.SetConst(objabi.PCDATA_ArgLiveIndex)
|
||||
p.From.SetConst(rtabi.PCDATA_ArgLiveIndex)
|
||||
p.To.SetConst(int64(idx))
|
||||
}
|
||||
|
||||
|
2
src/cmd/dist/buildtool.go
vendored
2
src/cmd/dist/buildtool.go
vendored
@ -307,7 +307,7 @@ func bootstrapFixImports(srcFile string) string {
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(line, `import "`) || strings.HasPrefix(line, `import . "`) ||
|
||||
inBlock && (strings.HasPrefix(line, "\t\"") || strings.HasPrefix(line, "\t. \"") || strings.HasPrefix(line, "\texec \"")) {
|
||||
inBlock && (strings.HasPrefix(line, "\t\"") || strings.HasPrefix(line, "\t. \"") || strings.HasPrefix(line, "\texec \"") || strings.HasPrefix(line, "\trtabi \"")) {
|
||||
line = strings.Replace(line, `"cmd/`, `"bootstrap/cmd/`, -1)
|
||||
for _, dir := range bootstrapDirs {
|
||||
if strings.HasPrefix(dir, "cmd/") {
|
||||
|
@ -58,12 +58,12 @@ func Flushplist(ctxt *Link, plist *Plist, newprog ProgAlloc, myimportpath string
|
||||
}
|
||||
switch p.To.Sym.Name {
|
||||
case "go_args_stackmap":
|
||||
if p.From.Type != TYPE_CONST || p.From.Offset != objabi.FUNCDATA_ArgsPointerMaps {
|
||||
if p.From.Type != TYPE_CONST || p.From.Offset != abi.FUNCDATA_ArgsPointerMaps {
|
||||
ctxt.Diag("%s: FUNCDATA use of go_args_stackmap(SB) without FUNCDATA_ArgsPointerMaps", p.Pos)
|
||||
}
|
||||
p.To.Sym = ctxt.LookupDerived(curtext, curtext.Name+".args_stackmap")
|
||||
case "no_pointers_stackmap":
|
||||
if p.From.Type != TYPE_CONST || p.From.Offset != objabi.FUNCDATA_LocalsPointerMaps {
|
||||
if p.From.Type != TYPE_CONST || p.From.Offset != abi.FUNCDATA_LocalsPointerMaps {
|
||||
ctxt.Diag("%s: FUNCDATA use of no_pointers_stackmap(SB) without FUNCDATA_LocalsPointerMaps", p.Pos)
|
||||
}
|
||||
// funcdata for functions with no local variables in frame.
|
||||
@ -110,10 +110,10 @@ func Flushplist(ctxt *Link, plist *Plist, newprog ProgAlloc, myimportpath string
|
||||
foundArgMap, foundArgInfo := false, false
|
||||
for p := s.Func().Text; p != nil; p = p.Link {
|
||||
if p.As == AFUNCDATA && p.From.Type == TYPE_CONST {
|
||||
if p.From.Offset == objabi.FUNCDATA_ArgsPointerMaps {
|
||||
if p.From.Offset == abi.FUNCDATA_ArgsPointerMaps {
|
||||
foundArgMap = true
|
||||
}
|
||||
if p.From.Offset == objabi.FUNCDATA_ArgInfo {
|
||||
if p.From.Offset == abi.FUNCDATA_ArgInfo {
|
||||
foundArgInfo = true
|
||||
}
|
||||
if foundArgMap && foundArgInfo {
|
||||
@ -125,7 +125,7 @@ func Flushplist(ctxt *Link, plist *Plist, newprog ProgAlloc, myimportpath string
|
||||
p := Appendp(s.Func().Text, newprog)
|
||||
p.As = AFUNCDATA
|
||||
p.From.Type = TYPE_CONST
|
||||
p.From.Offset = objabi.FUNCDATA_ArgsPointerMaps
|
||||
p.From.Offset = abi.FUNCDATA_ArgsPointerMaps
|
||||
p.To.Type = TYPE_MEM
|
||||
p.To.Name = NAME_EXTERN
|
||||
p.To.Sym = ctxt.LookupDerived(s, s.Name+".args_stackmap")
|
||||
@ -134,7 +134,7 @@ func Flushplist(ctxt *Link, plist *Plist, newprog ProgAlloc, myimportpath string
|
||||
p := Appendp(s.Func().Text, newprog)
|
||||
p.As = AFUNCDATA
|
||||
p.From.Type = TYPE_CONST
|
||||
p.From.Offset = objabi.FUNCDATA_ArgInfo
|
||||
p.From.Offset = abi.FUNCDATA_ArgInfo
|
||||
p.To.Type = TYPE_MEM
|
||||
p.To.Name = NAME_EXTERN
|
||||
p.To.Sym = ctxt.LookupDerived(s, fmt.Sprintf("%s.arginfo%d", s.Name, s.ABI()))
|
||||
@ -261,7 +261,7 @@ func (ctxt *Link) EmitEntryStackMap(s *LSym, p *Prog, newprog ProgAlloc) *Prog {
|
||||
pcdata.Pos = s.Func().Text.Pos
|
||||
pcdata.As = APCDATA
|
||||
pcdata.From.Type = TYPE_CONST
|
||||
pcdata.From.Offset = objabi.PCDATA_StackMapIndex
|
||||
pcdata.From.Offset = abi.PCDATA_StackMapIndex
|
||||
pcdata.To.Type = TYPE_CONST
|
||||
pcdata.To.Offset = -1 // pcdata starts at -1 at function entry
|
||||
|
||||
@ -274,7 +274,7 @@ func (ctxt *Link) EmitEntryUnsafePoint(s *LSym, p *Prog, newprog ProgAlloc) *Pro
|
||||
pcdata.Pos = s.Func().Text.Pos
|
||||
pcdata.As = APCDATA
|
||||
pcdata.From.Type = TYPE_CONST
|
||||
pcdata.From.Offset = objabi.PCDATA_UnsafePoint
|
||||
pcdata.From.Offset = abi.PCDATA_UnsafePoint
|
||||
pcdata.To.Type = TYPE_CONST
|
||||
pcdata.To.Offset = -1
|
||||
|
||||
@ -289,9 +289,9 @@ func (ctxt *Link) StartUnsafePoint(p *Prog, newprog ProgAlloc) *Prog {
|
||||
pcdata := Appendp(p, newprog)
|
||||
pcdata.As = APCDATA
|
||||
pcdata.From.Type = TYPE_CONST
|
||||
pcdata.From.Offset = objabi.PCDATA_UnsafePoint
|
||||
pcdata.From.Offset = abi.PCDATA_UnsafePoint
|
||||
pcdata.To.Type = TYPE_CONST
|
||||
pcdata.To.Offset = objabi.PCDATA_UnsafePointUnsafe
|
||||
pcdata.To.Offset = abi.UnsafePointUnsafe
|
||||
|
||||
return pcdata
|
||||
}
|
||||
@ -304,7 +304,7 @@ func (ctxt *Link) EndUnsafePoint(p *Prog, newprog ProgAlloc, oldval int64) *Prog
|
||||
pcdata := Appendp(p, newprog)
|
||||
pcdata.As = APCDATA
|
||||
pcdata.From.Type = TYPE_CONST
|
||||
pcdata.From.Offset = objabi.PCDATA_UnsafePoint
|
||||
pcdata.From.Offset = abi.PCDATA_UnsafePoint
|
||||
pcdata.To.Type = TYPE_CONST
|
||||
pcdata.To.Offset = oldval
|
||||
|
||||
@ -330,11 +330,11 @@ func MarkUnsafePoints(ctxt *Link, p0 *Prog, newprog ProgAlloc, isUnsafePoint, is
|
||||
prevPcdata := int64(-1) // entry PC data value
|
||||
prevRestart := int64(0)
|
||||
for p := prev.Link; p != nil; p, prev = p.Link, p {
|
||||
if p.As == APCDATA && p.From.Offset == objabi.PCDATA_UnsafePoint {
|
||||
if p.As == APCDATA && p.From.Offset == abi.PCDATA_UnsafePoint {
|
||||
prevPcdata = p.To.Offset
|
||||
continue
|
||||
}
|
||||
if prevPcdata == objabi.PCDATA_UnsafePointUnsafe {
|
||||
if prevPcdata == abi.UnsafePointUnsafe {
|
||||
continue // already unsafe
|
||||
}
|
||||
if isUnsafePoint(p) {
|
||||
@ -353,15 +353,15 @@ func MarkUnsafePoints(ctxt *Link, p0 *Prog, newprog ProgAlloc, isUnsafePoint, is
|
||||
continue
|
||||
}
|
||||
if isRestartable(p) {
|
||||
val := int64(objabi.PCDATA_Restart1)
|
||||
val := int64(abi.UnsafePointRestart1)
|
||||
if val == prevRestart {
|
||||
val = objabi.PCDATA_Restart2
|
||||
val = abi.UnsafePointRestart2
|
||||
}
|
||||
prevRestart = val
|
||||
q := Appendp(prev, newprog)
|
||||
q.As = APCDATA
|
||||
q.From.Type = TYPE_CONST
|
||||
q.From.Offset = objabi.PCDATA_UnsafePoint
|
||||
q.From.Offset = abi.PCDATA_UnsafePoint
|
||||
q.To.Type = TYPE_CONST
|
||||
q.To.Offset = val
|
||||
q.Pc = p.Pc
|
||||
@ -378,7 +378,7 @@ func MarkUnsafePoints(ctxt *Link, p0 *Prog, newprog ProgAlloc, isUnsafePoint, is
|
||||
p = Appendp(p, newprog)
|
||||
p.As = APCDATA
|
||||
p.From.Type = TYPE_CONST
|
||||
p.From.Offset = objabi.PCDATA_UnsafePoint
|
||||
p.From.Offset = abi.PCDATA_UnsafePoint
|
||||
p.To.Type = TYPE_CONST
|
||||
p.To.Offset = prevPcdata
|
||||
p.Pc = p.Link.Pc
|
||||
|
@ -6,9 +6,9 @@ package obj
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"cmd/internal/objabi"
|
||||
"cmd/internal/src"
|
||||
"fmt"
|
||||
"internal/abi"
|
||||
"internal/buildcfg"
|
||||
"io"
|
||||
"strings"
|
||||
@ -313,7 +313,7 @@ func writeDconv(w io.Writer, p *Prog, a *Addr, abiDetail bool) {
|
||||
}
|
||||
|
||||
case TYPE_TEXTSIZE:
|
||||
if a.Val.(int32) == objabi.ArgsSizeUnknown {
|
||||
if a.Val.(int32) == abi.ArgsSizeUnknown {
|
||||
fmt.Fprintf(w, "$%d", a.Offset)
|
||||
} else {
|
||||
fmt.Fprintf(w, "$%d-%d", a.Offset, a.Val.(int32))
|
||||
|
@ -1,51 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package objabi
|
||||
|
||||
// This file defines the IDs for PCDATA and FUNCDATA instructions
|
||||
// in Go binaries.
|
||||
//
|
||||
// These must agree with ../../../runtime/funcdata.h and
|
||||
// ../../../runtime/symtab.go.
|
||||
|
||||
const (
|
||||
PCDATA_UnsafePoint = 0
|
||||
PCDATA_StackMapIndex = 1
|
||||
PCDATA_InlTreeIndex = 2
|
||||
PCDATA_ArgLiveIndex = 3
|
||||
|
||||
FUNCDATA_ArgsPointerMaps = 0
|
||||
FUNCDATA_LocalsPointerMaps = 1
|
||||
FUNCDATA_StackObjects = 2
|
||||
FUNCDATA_InlTree = 3
|
||||
FUNCDATA_OpenCodedDeferInfo = 4
|
||||
FUNCDATA_ArgInfo = 5
|
||||
FUNCDATA_ArgLiveInfo = 6
|
||||
FUNCDATA_WrapInfo = 7
|
||||
|
||||
// ArgsSizeUnknown is set in Func.argsize to mark all functions
|
||||
// whose argument size is unknown (C vararg functions, and
|
||||
// assembly code without an explicit specification).
|
||||
// This value is generated by the compiler, assembler, or linker.
|
||||
ArgsSizeUnknown = -0x80000000
|
||||
)
|
||||
|
||||
// Special PCDATA values.
|
||||
const (
|
||||
// PCDATA_UnsafePoint values.
|
||||
PCDATA_UnsafePointSafe = -1 // Safe for async preemption
|
||||
PCDATA_UnsafePointUnsafe = -2 // Unsafe for async preemption
|
||||
|
||||
// PCDATA_Restart1(2) apply on a sequence of instructions, within
|
||||
// which if an async preemption happens, we should back off the PC
|
||||
// to the start of the sequence when resuming.
|
||||
// We need two so we can distinguish the start/end of the sequence
|
||||
// in case that two sequences are next to each other.
|
||||
PCDATA_Restart1 = -3
|
||||
PCDATA_Restart2 = -4
|
||||
|
||||
// Like PCDATA_Restart1, but back to function entry if async preempted.
|
||||
PCDATA_RestartAtEntry = -5
|
||||
)
|
@ -528,8 +528,8 @@ func numPCData(ldr *loader.Loader, s loader.Sym, fi loader.FuncInfo) uint32 {
|
||||
}
|
||||
numPCData := uint32(ldr.NumPcdata(s))
|
||||
if fi.NumInlTree() > 0 {
|
||||
if numPCData < objabi.PCDATA_InlTreeIndex+1 {
|
||||
numPCData = objabi.PCDATA_InlTreeIndex + 1
|
||||
if numPCData < abi.PCDATA_InlTreeIndex+1 {
|
||||
numPCData = abi.PCDATA_InlTreeIndex + 1
|
||||
}
|
||||
}
|
||||
return numPCData
|
||||
@ -566,10 +566,10 @@ func funcData(ldr *loader.Loader, s loader.Sym, fi loader.FuncInfo, inlSym loade
|
||||
if fi.Valid() {
|
||||
fdSyms = ldr.Funcdata(s, fdSyms)
|
||||
if fi.NumInlTree() > 0 {
|
||||
if len(fdSyms) < objabi.FUNCDATA_InlTree+1 {
|
||||
fdSyms = append(fdSyms, make([]loader.Sym, objabi.FUNCDATA_InlTree+1-len(fdSyms))...)
|
||||
if len(fdSyms) < abi.FUNCDATA_InlTree+1 {
|
||||
fdSyms = append(fdSyms, make([]loader.Sym, abi.FUNCDATA_InlTree+1-len(fdSyms))...)
|
||||
}
|
||||
fdSyms[objabi.FUNCDATA_InlTree] = inlSym
|
||||
fdSyms[abi.FUNCDATA_InlTree] = inlSym
|
||||
}
|
||||
}
|
||||
return fdSyms
|
||||
@ -597,8 +597,8 @@ func (state pclntab) calculateFunctabSize(ctxt *Link, funcs []loader.Sym) (int64
|
||||
fi.Preload()
|
||||
numFuncData := ldr.NumFuncdata(s)
|
||||
if fi.NumInlTree() > 0 {
|
||||
if numFuncData < objabi.FUNCDATA_InlTree+1 {
|
||||
numFuncData = objabi.FUNCDATA_InlTree + 1
|
||||
if numFuncData < abi.FUNCDATA_InlTree+1 {
|
||||
numFuncData = abi.FUNCDATA_InlTree + 1
|
||||
}
|
||||
}
|
||||
size += int64(numPCData(ldr, s, fi) * 4)
|
||||
@ -724,7 +724,7 @@ func writeFuncs(ctxt *Link, sb *loader.SymbolBuilder, funcs []loader.Sym, inlSym
|
||||
sb.SetUint32(ctxt.Arch, off+int64(j*4), uint32(ldr.SymValue(pcSym)))
|
||||
}
|
||||
if fi.NumInlTree() > 0 {
|
||||
sb.SetUint32(ctxt.Arch, off+objabi.PCDATA_InlTreeIndex*4, uint32(ldr.SymValue(pcinline)))
|
||||
sb.SetUint32(ctxt.Arch, off+abi.PCDATA_InlTreeIndex*4, uint32(ldr.SymValue(pcinline)))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,3 +62,45 @@ const (
|
||||
FuncID_systemstack_switch
|
||||
FuncIDWrapper // any autogenerated code (hash/eq algorithms, method wrappers, etc.)
|
||||
)
|
||||
|
||||
// ArgsSizeUnknown is set in Func.argsize to mark all functions
|
||||
// whose argument size is unknown (C vararg functions, and
|
||||
// assembly code without an explicit specification).
|
||||
// This value is generated by the compiler, assembler, or linker.
|
||||
const ArgsSizeUnknown = -0x80000000
|
||||
|
||||
// IDs for PCDATA and FUNCDATA tables in Go binaries.
|
||||
//
|
||||
// These must agree with ../../../runtime/funcdata.h.
|
||||
const (
|
||||
PCDATA_UnsafePoint = 0
|
||||
PCDATA_StackMapIndex = 1
|
||||
PCDATA_InlTreeIndex = 2
|
||||
PCDATA_ArgLiveIndex = 3
|
||||
|
||||
FUNCDATA_ArgsPointerMaps = 0
|
||||
FUNCDATA_LocalsPointerMaps = 1
|
||||
FUNCDATA_StackObjects = 2
|
||||
FUNCDATA_InlTree = 3
|
||||
FUNCDATA_OpenCodedDeferInfo = 4
|
||||
FUNCDATA_ArgInfo = 5
|
||||
FUNCDATA_ArgLiveInfo = 6
|
||||
FUNCDATA_WrapInfo = 7
|
||||
)
|
||||
|
||||
// Special values for the PCDATA_UnsafePoint table.
|
||||
const (
|
||||
UnsafePointSafe = -1 // Safe for async preemption
|
||||
UnsafePointUnsafe = -2 // Unsafe for async preemption
|
||||
|
||||
// UnsafePointRestart1(2) apply on a sequence of instructions, within
|
||||
// which if an async preemption happens, we should back off the PC
|
||||
// to the start of the sequence when resuming.
|
||||
// We need two so we can distinguish the start/end of the sequence
|
||||
// in case that two sequences are next to each other.
|
||||
UnsafePointRestart1 = -3
|
||||
UnsafePointRestart2 = -4
|
||||
|
||||
// Like UnsafePointRestart1, but back to function entry if async preempted.
|
||||
UnsafePointRestartAtEntry = -5
|
||||
)
|
||||
|
@ -6,7 +6,10 @@
|
||||
|
||||
package runtime
|
||||
|
||||
import "unsafe"
|
||||
import (
|
||||
"internal/abi"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
debugCallSystemStack = "executing on Go runtime stack"
|
||||
@ -80,8 +83,8 @@ func debugCallCheck(pc uintptr) string {
|
||||
if pc != f.entry() {
|
||||
pc--
|
||||
}
|
||||
up := pcdatavalue(f, _PCDATA_UnsafePoint, pc, nil)
|
||||
if up != _PCDATA_UnsafePointSafe {
|
||||
up := pcdatavalue(f, abi.PCDATA_UnsafePoint, pc, nil)
|
||||
if up != abi.UnsafePointSafe {
|
||||
// Not at a safe point.
|
||||
ret = debugCallUnsafePoint
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
// in Go binaries. It is included by assembly sources, so it must
|
||||
// be written using #defines.
|
||||
//
|
||||
// These must agree with symtab.go and ../cmd/internal/objabi/funcdata.go.
|
||||
// These must agree with internal/abi/symtab.go.
|
||||
|
||||
#define PCDATA_UnsafePoint 0
|
||||
#define PCDATA_StackMapIndex 1
|
||||
|
@ -12,6 +12,7 @@
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"internal/abi"
|
||||
"internal/goarch"
|
||||
"unsafe"
|
||||
)
|
||||
@ -257,7 +258,7 @@ func dumpframe(s *stkframe, child *childInfo) {
|
||||
pcdata := int32(-1) // Use the entry map at function entry
|
||||
if pc != f.entry() {
|
||||
pc--
|
||||
pcdata = pcdatavalue(f, _PCDATA_StackMapIndex, pc, nil)
|
||||
pcdata = pcdatavalue(f, abi.PCDATA_StackMapIndex, pc, nil)
|
||||
}
|
||||
if pcdata == -1 {
|
||||
// We do not have a valid pcdata value but there might be a
|
||||
@ -265,7 +266,7 @@ func dumpframe(s *stkframe, child *childInfo) {
|
||||
// at the function prologue, assume so and hope for the best.
|
||||
pcdata = 0
|
||||
}
|
||||
stkmap := (*stackmap)(funcdata(f, _FUNCDATA_LocalsPointerMaps))
|
||||
stkmap := (*stackmap)(funcdata(f, abi.FUNCDATA_LocalsPointerMaps))
|
||||
|
||||
var bv bitvector
|
||||
if stkmap != nil && stkmap.n > 0 {
|
||||
@ -326,7 +327,7 @@ func dumpframe(s *stkframe, child *childInfo) {
|
||||
child.arglen = s.argBytes()
|
||||
child.sp = (*uint8)(unsafe.Pointer(s.sp))
|
||||
child.depth++
|
||||
stkmap = (*stackmap)(funcdata(f, _FUNCDATA_ArgsPointerMaps))
|
||||
stkmap = (*stackmap)(funcdata(f, abi.FUNCDATA_ArgsPointerMaps))
|
||||
if stkmap != nil {
|
||||
child.args = stackmapdata(stkmap, pcdata)
|
||||
} else {
|
||||
|
@ -654,7 +654,7 @@ func addOneOpenDeferFrame(gp *g, pc uintptr, sp unsafe.Pointer) {
|
||||
continue
|
||||
}
|
||||
f := frame.fn
|
||||
fd := funcdata(f, _FUNCDATA_OpenCodedDeferInfo)
|
||||
fd := funcdata(f, abi.FUNCDATA_OpenCodedDeferInfo)
|
||||
if fd == nil {
|
||||
continue
|
||||
}
|
||||
|
@ -396,14 +396,14 @@ func isAsyncSafePoint(gp *g, pc, sp, lr uintptr) (bool, uintptr) {
|
||||
// use the LR for unwinding, which will be bad.
|
||||
return false, 0
|
||||
}
|
||||
up, startpc := pcdatavalue2(f, _PCDATA_UnsafePoint, pc)
|
||||
if up == _PCDATA_UnsafePointUnsafe {
|
||||
up, startpc := pcdatavalue2(f, abi.PCDATA_UnsafePoint, pc)
|
||||
if up == abi.UnsafePointUnsafe {
|
||||
// Unsafe-point marked by compiler. This includes
|
||||
// atomic sequences (e.g., write barrier) and nosplit
|
||||
// functions (except at calls).
|
||||
return false, 0
|
||||
}
|
||||
if fd := funcdata(f, _FUNCDATA_LocalsPointerMaps); fd == nil || f.flag&abi.FuncFlagAsm != 0 {
|
||||
if fd := funcdata(f, abi.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?
|
||||
//
|
||||
@ -432,14 +432,14 @@ func isAsyncSafePoint(gp *g, pc, sp, lr uintptr) (bool, uintptr) {
|
||||
return false, 0
|
||||
}
|
||||
switch up {
|
||||
case _PCDATA_Restart1, _PCDATA_Restart2:
|
||||
case abi.UnsafePointRestart1, abi.UnsafePointRestart2:
|
||||
// Restartable instruction sequence. Back off PC to
|
||||
// the start PC.
|
||||
if startpc == 0 || startpc > pc || pc-startpc > 20 {
|
||||
throw("bad restart PC")
|
||||
}
|
||||
return true, startpc
|
||||
case _PCDATA_RestartAtEntry:
|
||||
case abi.UnsafePointRestartAtEntry:
|
||||
// Restart from the function entry at resumption.
|
||||
return true, f.entry()
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ type reflectMethodValue struct {
|
||||
|
||||
// argBytes returns the argument frame size for a call to frame.fn.
|
||||
func (frame *stkframe) argBytes() uintptr {
|
||||
if frame.fn.args != _ArgsSizeUnknown {
|
||||
if frame.fn.args != abi.ArgsSizeUnknown {
|
||||
return uintptr(frame.fn.args)
|
||||
}
|
||||
// This is an uncommon and complicated case. Fall back to fully
|
||||
@ -93,7 +93,7 @@ func (frame *stkframe) argBytes() uintptr {
|
||||
// function stack object, which the caller must synthesize.
|
||||
func (frame *stkframe) argMapInternal() (argMap bitvector, hasReflectStackObj bool) {
|
||||
f := frame.fn
|
||||
if f.args != _ArgsSizeUnknown {
|
||||
if f.args != abi.ArgsSizeUnknown {
|
||||
argMap.n = f.args / goarch.PtrSize
|
||||
return
|
||||
}
|
||||
@ -169,7 +169,7 @@ func (frame *stkframe) getStackMap(cache *pcvalueCache, debug bool) (locals, arg
|
||||
// the first instruction of the function changes the
|
||||
// stack map.
|
||||
targetpc--
|
||||
pcdata = pcdatavalue(f, _PCDATA_StackMapIndex, targetpc, cache)
|
||||
pcdata = pcdatavalue(f, abi.PCDATA_StackMapIndex, targetpc, cache)
|
||||
}
|
||||
if pcdata == -1 {
|
||||
// We do not have a valid pcdata value but there might be a
|
||||
@ -189,7 +189,7 @@ func (frame *stkframe) getStackMap(cache *pcvalueCache, debug bool) (locals, arg
|
||||
}
|
||||
if size > minsize {
|
||||
stackid := pcdata
|
||||
stkmap := (*stackmap)(funcdata(f, _FUNCDATA_LocalsPointerMaps))
|
||||
stkmap := (*stackmap)(funcdata(f, abi.FUNCDATA_LocalsPointerMaps))
|
||||
if stkmap == nil || stkmap.n <= 0 {
|
||||
print("runtime: frame ", funcname(f), " untyped locals ", hex(frame.varp-size), "+", hex(size), "\n")
|
||||
throw("missing stackmap")
|
||||
@ -216,7 +216,7 @@ func (frame *stkframe) getStackMap(cache *pcvalueCache, debug bool) (locals, arg
|
||||
if args.n > 0 && args.bytedata == nil {
|
||||
// Non-empty argument frame, but not a special map.
|
||||
// Fetch the argument map at pcdata.
|
||||
stackmap := (*stackmap)(funcdata(f, _FUNCDATA_ArgsPointerMaps))
|
||||
stackmap := (*stackmap)(funcdata(f, abi.FUNCDATA_ArgsPointerMaps))
|
||||
if stackmap == nil || stackmap.n <= 0 {
|
||||
print("runtime: frame ", funcname(f), " untyped args ", hex(frame.argp), "+", hex(args.n*goarch.PtrSize), "\n")
|
||||
throw("missing stackmap")
|
||||
@ -242,7 +242,7 @@ func (frame *stkframe) getStackMap(cache *pcvalueCache, debug bool) (locals, arg
|
||||
// This offset matches the assembly code on amd64 and arm64.
|
||||
objs = methodValueCallFrameObjs[:]
|
||||
} else {
|
||||
p := funcdata(f, _FUNCDATA_StackObjects)
|
||||
p := funcdata(f, abi.FUNCDATA_StackObjects)
|
||||
if p != nil {
|
||||
n := *(*uintptr)(p)
|
||||
p = add(p, goarch.PtrSize)
|
||||
|
@ -296,45 +296,6 @@ func (f *_func) funcInfo() funcInfo {
|
||||
return funcInfo{f, mod}
|
||||
}
|
||||
|
||||
// PCDATA and FUNCDATA table indexes.
|
||||
//
|
||||
// See funcdata.h and ../cmd/internal/objabi/funcdata.go.
|
||||
const (
|
||||
_PCDATA_UnsafePoint = 0
|
||||
_PCDATA_StackMapIndex = 1
|
||||
_PCDATA_InlTreeIndex = 2
|
||||
_PCDATA_ArgLiveIndex = 3
|
||||
|
||||
_FUNCDATA_ArgsPointerMaps = 0
|
||||
_FUNCDATA_LocalsPointerMaps = 1
|
||||
_FUNCDATA_StackObjects = 2
|
||||
_FUNCDATA_InlTree = 3
|
||||
_FUNCDATA_OpenCodedDeferInfo = 4
|
||||
_FUNCDATA_ArgInfo = 5
|
||||
_FUNCDATA_ArgLiveInfo = 6
|
||||
_FUNCDATA_WrapInfo = 7
|
||||
|
||||
_ArgsSizeUnknown = -0x80000000
|
||||
)
|
||||
|
||||
const (
|
||||
// PCDATA_UnsafePoint values.
|
||||
_PCDATA_UnsafePointSafe = -1 // Safe for async preemption
|
||||
_PCDATA_UnsafePointUnsafe = -2 // Unsafe for async preemption
|
||||
|
||||
// _PCDATA_Restart1(2) apply on a sequence of instructions, within
|
||||
// which if an async preemption happens, we should back off the PC
|
||||
// to the start of the sequence when resume.
|
||||
// We need two so we can distinguish the start/end of the sequence
|
||||
// in case that two sequences are next to each other.
|
||||
_PCDATA_Restart1 = -3
|
||||
_PCDATA_Restart2 = -4
|
||||
|
||||
// Like _PCDATA_RestartAtEntry, but back to function entry if async
|
||||
// preempted.
|
||||
_PCDATA_RestartAtEntry = -5
|
||||
)
|
||||
|
||||
// pcHeader holds data used by the pclntab lookups.
|
||||
type pcHeader struct {
|
||||
magic uint32 // 0xFFFFFFF1
|
||||
|
@ -53,7 +53,7 @@ type inlineFrame struct {
|
||||
// only ever used for symbolic debugging. If things go really wrong, it'll just
|
||||
// fall back to the outermost frame.
|
||||
func newInlineUnwinder(f funcInfo, pc uintptr, cache *pcvalueCache) (inlineUnwinder, inlineFrame) {
|
||||
inldata := funcdata(f, _FUNCDATA_InlTree)
|
||||
inldata := funcdata(f, abi.FUNCDATA_InlTree)
|
||||
if inldata == nil {
|
||||
return inlineUnwinder{f: f}, inlineFrame{pc: pc, index: -1}
|
||||
}
|
||||
@ -67,7 +67,7 @@ func (u *inlineUnwinder) resolveInternal(pc uintptr) inlineFrame {
|
||||
pc: pc,
|
||||
// Conveniently, this returns -1 if there's an error, which is the same
|
||||
// value we use for the outermost frame.
|
||||
index: pcdatavalue1(u.f, _PCDATA_InlTreeIndex, pc, u.cache, false),
|
||||
index: pcdatavalue1(u.f, abi.PCDATA_InlTreeIndex, pc, u.cache, false),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1701,7 +1701,7 @@ func startPCforTrace(pc uintptr) uintptr {
|
||||
if !f.valid() {
|
||||
return pc // may happen for locked g in extra M since its pc is 0.
|
||||
}
|
||||
w := funcdata(f, _FUNCDATA_WrapInfo)
|
||||
w := funcdata(f, abi.FUNCDATA_WrapInfo)
|
||||
if w == nil {
|
||||
return pc // not a wrapper
|
||||
}
|
||||
|
@ -664,13 +664,13 @@ func printArgs(f funcInfo, argp unsafe.Pointer, pc uintptr) {
|
||||
maxLen = (maxDepth*3+2)*limit + 1 // max length of _FUNCDATA_ArgInfo (see the compiler side for reasoning)
|
||||
)
|
||||
|
||||
p := (*[maxLen]uint8)(funcdata(f, _FUNCDATA_ArgInfo))
|
||||
p := (*[maxLen]uint8)(funcdata(f, abi.FUNCDATA_ArgInfo))
|
||||
if p == nil {
|
||||
return
|
||||
}
|
||||
|
||||
liveInfo := funcdata(f, _FUNCDATA_ArgLiveInfo)
|
||||
liveIdx := pcdatavalue(f, _PCDATA_ArgLiveIndex, pc, nil)
|
||||
liveInfo := funcdata(f, abi.FUNCDATA_ArgLiveInfo)
|
||||
liveIdx := pcdatavalue(f, abi.PCDATA_ArgLiveIndex, pc, nil)
|
||||
startOffset := uint8(0xff) // smallest offset that needs liveness info (slots with a lower offset is always live)
|
||||
if liveInfo != nil {
|
||||
startOffset = *(*uint8)(liveInfo)
|
||||
|
Loading…
Reference in New Issue
Block a user