// Create top-level function.
xfunc := makepartialcall(fn, fn.Type, sym)
fn.Func = xfunc.Func
+ fn.Func.SetWrapper(true)
fn.Right = newname(sym)
fn.Op = OCALLPART
fn.Type = xfunc.Type
import (
"bytes"
+ "cmd/internal/objabi"
"encoding/binary"
)
type FuncInfo struct {
Args uint32
Locals uint32
+ FuncID objabi.FuncID
Pcsp uint32
Pcfile uint32
writeUint32(a.Args)
writeUint32(a.Locals)
+ writeUint32(uint32(a.FuncID))
writeUint32(a.Pcsp)
writeUint32(a.Pcfile)
a.Args = readUint32()
a.Locals = readUint32()
+ a.FuncID = objabi.FuncID(readUint32())
a.Pcsp = readUint32()
a.Pcfile = readUint32()
func (*FuncInfo) ReadFuncInfoLengths(b []byte) FuncInfoLengths {
var result FuncInfoLengths
- const numpcdataOff = 24
+ const numpcdataOff = 28
result.NumPcdata = binary.LittleEndian.Uint32(b[numpcdataOff:])
result.PcdataOff = numpcdataOff + 4
func (*FuncInfo) ReadLocals(b []byte) uint32 { return binary.LittleEndian.Uint32(b[4:]) }
+func (*FuncInfo) ReadFuncID(b []byte) uint32 { return binary.LittleEndian.Uint32(b[8:]) }
+
// return start and end offsets.
func (*FuncInfo) ReadPcsp(b []byte) (uint32, uint32) {
- return binary.LittleEndian.Uint32(b[8:]), binary.LittleEndian.Uint32(b[12:])
+ return binary.LittleEndian.Uint32(b[12:]), binary.LittleEndian.Uint32(b[16:])
}
// return start and end offsets.
func (*FuncInfo) ReadPcfile(b []byte) (uint32, uint32) {
- return binary.LittleEndian.Uint32(b[12:]), binary.LittleEndian.Uint32(b[16:])
+ return binary.LittleEndian.Uint32(b[16:]), binary.LittleEndian.Uint32(b[20:])
}
// return start and end offsets.
func (*FuncInfo) ReadPcline(b []byte) (uint32, uint32) {
- return binary.LittleEndian.Uint32(b[16:]), binary.LittleEndian.Uint32(b[20:])
+ return binary.LittleEndian.Uint32(b[20:]), binary.LittleEndian.Uint32(b[24:])
}
// return start and end offsets.
func (*FuncInfo) ReadPcinline(b []byte, pcdataoffset uint32) (uint32, uint32) {
- return binary.LittleEndian.Uint32(b[20:]), binary.LittleEndian.Uint32(b[pcdataoffset:])
+ return binary.LittleEndian.Uint32(b[24:]), binary.LittleEndian.Uint32(b[pcdataoffset:])
}
// return start and end offsets.
// New object file format.
//
// Header struct {
-// Magic [...]byte // "\x00go115ld"
+// Magic [...]byte // "\x00go116ld"
// Fingerprint [8]byte
// Flags uint32
// Offsets [...]uint32 // byte offset of each block below
Offsets [NBlk]uint32
}
-const Magic = "\x00go115ld"
+const Magic = "\x00go116ld"
func (h *Header) Write(w *Writer) {
w.RawString(h.Magic)
Args int32
Locals int32
Align int32
+ FuncID objabi.FuncID
Text *Prog
Autot map[*LSym]struct{}
Pcln Pcln
}
fmt.Fprintf(ctxt.Bso, "size=%d", s.Size)
if s.Type == objabi.STEXT {
- fmt.Fprintf(ctxt.Bso, " args=%#x locals=%#x", uint64(s.Func.Args), uint64(s.Func.Locals))
+ fmt.Fprintf(ctxt.Bso, " args=%#x locals=%#x funcid=%#x", uint64(s.Func.Args), uint64(s.Func.Locals), uint64(s.Func.FuncID))
if s.Leaf() {
fmt.Fprintf(ctxt.Bso, " leaf")
}
o := goobj2.FuncInfo{
Args: uint32(s.Func.Args),
Locals: uint32(s.Func.Locals),
+ FuncID: objabi.FuncID(s.Func.FuncID),
}
pc := &s.Func.Pcln
o.Pcsp = pcdataoff
if s.OnList() {
ctxt.Diag("symbol %s listed multiple times", s.Name)
}
+ name := strings.Replace(s.Name, "\"\"", ctxt.Pkgpath, -1)
+ s.Func.FuncID = objabi.GetFuncID(name, flag&WRAPPER != 0)
s.Set(AttrOnList, true)
s.Set(AttrDuplicateOK, flag&DUPOK != 0)
s.Set(AttrNoSplit, flag&NOSPLIT != 0)
package objabi
-import (
- "strconv"
- "strings"
-)
-
// 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
// Get the function ID for the named function in the named file.
// The function should be package-qualified.
-func GetFuncID(name, file string) FuncID {
+func GetFuncID(name string, isWrapper bool) FuncID {
+ if isWrapper {
+ return FuncID_wrapper
+ }
switch name {
case "runtime.main":
return FuncID_runtime_main
// Don't show in the call stack (used when invoking defer functions)
return FuncID_wrapper
}
- if file == "<autogenerated>" {
- return FuncID_wrapper
- }
- if strings.HasPrefix(name, "runtime.call") {
- if _, err := strconv.Atoi(name[12:]); err == nil {
- // runtime.callXX reflect call wrappers.
- return FuncID_wrapper
- }
- }
- if strings.HasSuffix(name, "-fm") {
- return FuncID_wrapper
- }
return FuncID_normal
}
}
inlTreeSym.SetUint16(arch, int64(i*20+0), uint16(call.Parent))
- inlTreeSym.SetUint8(arch, int64(i*20+2), uint8(objabi.GetFuncID(ldr.SymName(call.Func), "")))
+ inlFunc := ldr.FuncInfo(call.Func)
+
+ var funcID objabi.FuncID
+ if inlFunc.Valid() {
+ funcID = inlFunc.FuncID()
+ }
+ inlTreeSym.SetUint8(arch, int64(i*20+2), uint8(funcID))
+
// byte 3 is unused
inlTreeSym.SetUint32(arch, int64(i*20+4), uint32(val))
inlTreeSym.SetUint32(arch, int64(i*20+8), uint32(call.Line))
off = int32(ftab.SetUint32(ctxt.Arch, int64(off), uint32(len(pcdata))))
// funcID uint8
- var file string
- if fi.Valid() && fi.NumFile() > 0 {
- filesymname := ldr.SymName(fi.File(0))
- file = filesymname[len(src.FileSymPrefix):]
+ var funcID objabi.FuncID
+ if fi.Valid() {
+ funcID = fi.FuncID()
}
- funcID := objabi.GetFuncID(ldr.SymName(s), file)
-
off = int32(ftab.SetUint8(ctxt.Arch, int64(off), uint8(funcID)))
// unused
return int((*goobj2.FuncInfo)(nil).ReadLocals(fi.data))
}
+func (fi *FuncInfo) FuncID() objabi.FuncID {
+ return objabi.FuncID((*goobj2.FuncInfo)(nil).ReadFuncID(fi.data))
+}
+
func (fi *FuncInfo) Pcsp() []byte {
pcsp, end := (*goobj2.FuncInfo)(nil).ReadPcsp(fi.data)
return fi.r.BytesAt(fi.r.PcdataBase()+pcsp, int(end-pcsp))