mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.link] cmd/internal/obj, cmd/link: add InlTree in new object files
Add InlTree to the FuncInfo aux symbol in new object files. In the linker, change InlinedCall.Func from a Symbol to a string, as we only use its Name. (There was a use of Func.File, but that use is not correct anyway.) So we don't need to create a Symbol if not necessary. Change-Id: I38ce568ae0934cd9cb6d0b30599f1c8d75444fc9 Reviewed-on: https://go-review.googlesource.com/c/go/+/200098 Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Than McIntosh <thanm@google.com>
This commit is contained in:
parent
dab05a0484
commit
6ba3ae9ca5
8 changed files with 91 additions and 9 deletions
|
|
@ -154,6 +154,7 @@ func (r *objReader) readNew() {
|
|||
PCData: make([]Data, len(info.Pcdata)-1), // -1 as we appended one above
|
||||
FuncData: make([]FuncData, len(info.Funcdataoff)),
|
||||
File: make([]string, len(info.File)),
|
||||
InlTree: make([]InlinedCall, len(info.InlTree)),
|
||||
}
|
||||
sym.Func = f
|
||||
for k := range f.PCData {
|
||||
|
|
@ -167,5 +168,15 @@ func (r *objReader) readNew() {
|
|||
symID := resolveSymRef(info.File[k])
|
||||
f.File[k] = symID.Name
|
||||
}
|
||||
for k := range f.InlTree {
|
||||
inl := &info.InlTree[k]
|
||||
f.InlTree[k] = InlinedCall{
|
||||
Parent: int64(inl.Parent),
|
||||
File: resolveSymRef(inl.File).Name,
|
||||
Line: int64(inl.Line),
|
||||
Func: resolveSymRef(inl.Func),
|
||||
ParentPC: int64(inl.ParentPC),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ type FuncInfo struct {
|
|||
Funcdataoff []uint32
|
||||
File []SymRef // TODO: just use string?
|
||||
|
||||
// TODO: InlTree
|
||||
InlTree []InlTreeNode
|
||||
}
|
||||
|
||||
func (a *FuncInfo) Write(w *bytes.Buffer) {
|
||||
|
|
@ -61,8 +61,10 @@ func (a *FuncInfo) Write(w *bytes.Buffer) {
|
|||
writeUint32(f.PkgIdx)
|
||||
writeUint32(f.SymIdx)
|
||||
}
|
||||
|
||||
// TODO: InlTree
|
||||
writeUint32(uint32(len(a.InlTree)))
|
||||
for i := range a.InlTree {
|
||||
a.InlTree[i].Write(w)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *FuncInfo) Read(b []byte) {
|
||||
|
|
@ -98,6 +100,48 @@ func (a *FuncInfo) Read(b []byte) {
|
|||
for i := range a.File {
|
||||
a.File[i] = SymRef{readUint32(), readUint32()}
|
||||
}
|
||||
|
||||
// TODO: InlTree
|
||||
inltreelen := readUint32()
|
||||
a.InlTree = make([]InlTreeNode, inltreelen)
|
||||
for i := range a.InlTree {
|
||||
b = a.InlTree[i].Read(b)
|
||||
}
|
||||
}
|
||||
|
||||
// InlTreeNode is the serialized form of FileInfo.InlTree.
|
||||
type InlTreeNode struct {
|
||||
Parent int32
|
||||
File SymRef
|
||||
Line int32
|
||||
Func SymRef
|
||||
ParentPC int32
|
||||
}
|
||||
|
||||
func (inl *InlTreeNode) Write(w *bytes.Buffer) {
|
||||
var b [4]byte
|
||||
writeUint32 := func(x uint32) {
|
||||
binary.LittleEndian.PutUint32(b[:], x)
|
||||
w.Write(b[:])
|
||||
}
|
||||
writeUint32(uint32(inl.Parent))
|
||||
writeUint32(inl.File.PkgIdx)
|
||||
writeUint32(inl.File.SymIdx)
|
||||
writeUint32(uint32(inl.Line))
|
||||
writeUint32(inl.Func.PkgIdx)
|
||||
writeUint32(inl.Func.SymIdx)
|
||||
writeUint32(uint32(inl.ParentPC))
|
||||
}
|
||||
|
||||
// Read an InlTreeNode from b, return the remaining bytes.
|
||||
func (inl *InlTreeNode) Read(b []byte) []byte {
|
||||
readUint32 := func() uint32 {
|
||||
x := binary.LittleEndian.Uint32(b)
|
||||
b = b[4:]
|
||||
return x
|
||||
}
|
||||
inl.Parent = int32(readUint32())
|
||||
inl.File = SymRef{readUint32(), readUint32()}
|
||||
inl.Line = int32(readUint32())
|
||||
inl.Func = SymRef{readUint32(), readUint32()}
|
||||
inl.ParentPC = int32(readUint32())
|
||||
return b
|
||||
}
|
||||
|
|
|
|||
|
|
@ -395,6 +395,18 @@ func genFuncInfoSyms(ctxt *Link) {
|
|||
fsym := ctxt.Lookup(f)
|
||||
o.File[i] = makeSymRef(fsym)
|
||||
}
|
||||
o.InlTree = make([]goobj2.InlTreeNode, len(pc.InlTree.nodes))
|
||||
for i, inl := range pc.InlTree.nodes {
|
||||
f, l := linkgetlineFromPos(ctxt, inl.Pos)
|
||||
fsym := ctxt.Lookup(f)
|
||||
o.InlTree[i] = goobj2.InlTreeNode{
|
||||
Parent: int32(inl.Parent),
|
||||
File: makeSymRef(fsym),
|
||||
Line: l,
|
||||
Func: makeSymRef(inl.Func),
|
||||
ParentPC: inl.ParentPC,
|
||||
}
|
||||
}
|
||||
|
||||
o.Write(&b)
|
||||
isym := &LSym{
|
||||
|
|
|
|||
|
|
@ -277,6 +277,10 @@ func (ctxt *Link) traverseSyms(flag traverseFlag, fn func(*LSym)) {
|
|||
if call.Func != nil {
|
||||
fn(call.Func)
|
||||
}
|
||||
f, _ := linkgetlineFromPos(ctxt, call.Pos)
|
||||
if fsym := ctxt.Lookup(f); fsym != nil {
|
||||
fn(fsym)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -294,10 +294,10 @@ func (ctxt *Link) pclntab() {
|
|||
// appears in the Pcfile table. In that case, this assigns
|
||||
// the outer file a number.
|
||||
numberfile(ctxt, call.File)
|
||||
nameoff := nameToOffset(call.Func.Name)
|
||||
nameoff := nameToOffset(call.Func)
|
||||
|
||||
inlTreeSym.SetUint16(ctxt.Arch, int64(i*20+0), uint16(call.Parent))
|
||||
inlTreeSym.SetUint8(ctxt.Arch, int64(i*20+2), uint8(objabi.GetFuncID(call.Func.Name, call.Func.File)))
|
||||
inlTreeSym.SetUint8(ctxt.Arch, int64(i*20+2), uint8(objabi.GetFuncID(call.Func, "")))
|
||||
// byte 3 is unused
|
||||
inlTreeSym.SetUint32(ctxt.Arch, int64(i*20+4), uint32(call.File.Value))
|
||||
inlTreeSym.SetUint32(ctxt.Arch, int64(i*20+8), uint32(call.Line))
|
||||
|
|
|
|||
|
|
@ -369,7 +369,7 @@ overwrite:
|
|||
pc.InlTree[i].Parent = r.readInt32()
|
||||
pc.InlTree[i].File = r.readSymIndex()
|
||||
pc.InlTree[i].Line = r.readInt32()
|
||||
pc.InlTree[i].Func = r.readSymIndex()
|
||||
pc.InlTree[i].Func = r.readSymIndex().Name
|
||||
pc.InlTree[i].ParentPC = r.readInt32()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -699,6 +699,7 @@ func loadObjFull(l *Loader, r *oReader) {
|
|||
pc.Pcdata = make([]sym.Pcdata, len(info.Pcdata)-1) // -1 as we appended one above
|
||||
pc.Funcdataoff = make([]int64, len(info.Funcdataoff))
|
||||
pc.File = make([]*sym.Symbol, len(info.File))
|
||||
pc.InlTree = make([]sym.InlinedCall, len(info.InlTree))
|
||||
pc.Pcsp.P = r.BytesAt(pcdataBase+info.Pcsp, int(info.Pcfile-info.Pcsp))
|
||||
pc.Pcfile.P = r.BytesAt(pcdataBase+info.Pcfile, int(info.Pcline-info.Pcfile))
|
||||
pc.Pcline.P = r.BytesAt(pcdataBase+info.Pcline, int(info.Pcinline-info.Pcline))
|
||||
|
|
@ -712,6 +713,16 @@ func loadObjFull(l *Loader, r *oReader) {
|
|||
for k := range pc.File {
|
||||
pc.File[k] = resolveSymRef(info.File[k])
|
||||
}
|
||||
for k := range pc.InlTree {
|
||||
inl := &info.InlTree[k]
|
||||
pc.InlTree[k] = sym.InlinedCall{
|
||||
Parent: inl.Parent,
|
||||
File: resolveSymRef(inl.File),
|
||||
Line: inl.Line,
|
||||
Func: l.SymName(l.Resolve(r, inl.Func)),
|
||||
ParentPC: inl.ParentPC,
|
||||
}
|
||||
}
|
||||
|
||||
if !dupok {
|
||||
if s.Attr.OnList() {
|
||||
|
|
|
|||
|
|
@ -534,7 +534,7 @@ type InlinedCall struct {
|
|||
Parent int32 // index of parent in InlTree
|
||||
File *Symbol // file of the inlined call
|
||||
Line int32 // line number of the inlined call
|
||||
Func *Symbol // function that was inlined
|
||||
Func string // name of the function that was inlined
|
||||
ParentPC int32 // PC of the instruction just before the inlined body (offset from function start)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue