aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/link/internal/loader/loader.go
diff options
context:
space:
mode:
authorThan McIntosh <thanm@google.com>2020-04-08 11:56:43 -0400
committerThan McIntosh <thanm@google.com>2020-04-10 12:33:04 +0000
commit30b0c819d13692cc63852f4bfbf5979bffc13acc (patch)
tree24189c5a994c4bb7e19d010bf56e43190769408b /src/cmd/link/internal/loader/loader.go
parent37cc5cd76941f2b42f8b1403dde362439c8a9e69 (diff)
downloadgo-30b0c819d13692cc63852f4bfbf5979bffc13acc.tar.gz
go-30b0c819d13692cc63852f4bfbf5979bffc13acc.zip
[dev.link] cmd/link/internal/loader: expand methods for FuncInfo
Expand the methods for the FuncInfo helper, to support reading the contents of an object file FuncInfo aux symbol using the new style (that is to say, incrementally and without allocating slices to hold the various bits). Change-Id: I953d72c4a53f98c840e6b25b08fd33dc4a833dd5 Reviewed-on: https://go-review.googlesource.com/c/go/+/227585 Reviewed-by: Cherry Zhang <cherryyz@google.com>
Diffstat (limited to 'src/cmd/link/internal/loader/loader.go')
-rw-r--r--src/cmd/link/internal/loader/loader.go130
1 files changed, 125 insertions, 5 deletions
diff --git a/src/cmd/link/internal/loader/loader.go b/src/cmd/link/internal/loader/loader.go
index cd5971c2e1..390eb1af24 100644
--- a/src/cmd/link/internal/loader/loader.go
+++ b/src/cmd/link/internal/loader/loader.go
@@ -1529,13 +1529,18 @@ func (x RelocByOff) Less(i, j int) bool { return x[i].Off < x[j].Off }
// FuncInfo provides hooks to access goobj2.FuncInfo in the objects.
type FuncInfo struct {
- l *Loader
- r *oReader
- data []byte
+ l *Loader
+ r *oReader
+ data []byte
+ lengths goobj2.FuncInfoLengths
}
func (fi *FuncInfo) Valid() bool { return fi.r != nil }
+func (fi *FuncInfo) Args() int {
+ return int((*goobj2.FuncInfo)(nil).ReadArgs(fi.data))
+}
+
func (fi *FuncInfo) Locals() int {
return int((*goobj2.FuncInfo)(nil).ReadLocals(fi.data))
}
@@ -1545,7 +1550,122 @@ func (fi *FuncInfo) Pcsp() []byte {
return fi.r.BytesAt(fi.r.PcdataBase()+pcsp, int(end-pcsp))
}
-// TODO: more accessors.
+func (fi *FuncInfo) Pcfile() []byte {
+ pcf, end := (*goobj2.FuncInfo)(nil).ReadPcfile(fi.data)
+ return fi.r.BytesAt(fi.r.PcdataBase()+pcf, int(end-pcf))
+}
+
+func (fi *FuncInfo) Pcline() []byte {
+ pcln, end := (*goobj2.FuncInfo)(nil).ReadPcline(fi.data)
+ return fi.r.BytesAt(fi.r.PcdataBase()+pcln, int(end-pcln))
+}
+
+// Preload has to be called prior to invoking the various methods
+// below related to pcdata, funcdataoff, files, and inltree nodes.
+func (fi *FuncInfo) Preload() {
+ fi.lengths = (*goobj2.FuncInfo)(nil).ReadFuncInfoLengths(fi.data)
+}
+
+func (fi *FuncInfo) Pcinline() []byte {
+ if !fi.lengths.Initialized {
+ panic("need to call Preload first")
+ }
+ pcinl, end := (*goobj2.FuncInfo)(nil).ReadPcinline(fi.data, fi.lengths.PcdataOff)
+ return fi.r.BytesAt(fi.r.PcdataBase()+pcinl, int(end-pcinl))
+}
+
+func (fi *FuncInfo) NumPcdata() uint32 {
+ if !fi.lengths.Initialized {
+ panic("need to call Preload first")
+ }
+ return fi.lengths.NumPcdata
+}
+
+func (fi *FuncInfo) Pcdata(k int) []byte {
+ if !fi.lengths.Initialized {
+ panic("need to call Preload first")
+ }
+ pcdat, end := (*goobj2.FuncInfo)(nil).ReadPcdata(fi.data, fi.lengths.PcdataOff, uint32(k))
+ return fi.r.BytesAt(fi.r.PcdataBase()+pcdat, int(end-pcdat))
+}
+
+func (fi *FuncInfo) NumFuncdataoff() uint32 {
+ if !fi.lengths.Initialized {
+ panic("need to call Preload first")
+ }
+ return fi.lengths.NumFuncdataoff
+}
+
+func (fi *FuncInfo) Funcdataoff(k int) int64 {
+ if !fi.lengths.Initialized {
+ panic("need to call Preload first")
+ }
+ return (*goobj2.FuncInfo)(nil).ReadFuncdataoff(fi.data, fi.lengths.FuncdataoffOff, uint32(k))
+}
+
+func (fi *FuncInfo) Funcdata(fnsym Sym, syms []Sym) []Sym {
+ if !fi.lengths.Initialized {
+ panic("need to call Preload first")
+ }
+ if int(fi.lengths.NumFuncdataoff) > cap(syms) {
+ syms = make([]Sym, 0, fi.lengths.NumFuncdataoff)
+ } else {
+ syms = syms[:0]
+ }
+ r, li := fi.l.toLocal(fnsym)
+ auxs := r.Auxs2(li)
+ for j := range auxs {
+ a := &auxs[j]
+ if a.Type() == goobj2.AuxFuncdata {
+ syms = append(syms, fi.l.resolve(fi.r, a.Sym()))
+ }
+ }
+ return syms
+}
+
+func (fi *FuncInfo) NumFile() uint32 {
+ if !fi.lengths.Initialized {
+ panic("need to call Preload first")
+ }
+ return fi.lengths.NumFile
+}
+
+func (fi *FuncInfo) File(k int) Sym {
+ if !fi.lengths.Initialized {
+ panic("need to call Preload first")
+ }
+ sr := (*goobj2.FuncInfo)(nil).ReadFile(fi.data, fi.lengths.FileOff, uint32(k))
+ return fi.l.resolve(fi.r, sr)
+}
+
+type InlTreeNode struct {
+ Parent int32
+ File Sym
+ Line int32
+ Func Sym
+ ParentPC int32
+}
+
+func (fi *FuncInfo) NumInlTree() uint32 {
+ if !fi.lengths.Initialized {
+ panic("need to call Preload first")
+ }
+ return fi.lengths.NumInlTree
+}
+
+func (fi *FuncInfo) InlTree(k int) InlTreeNode {
+ if !fi.lengths.Initialized {
+ panic("need to call Preload first")
+ }
+ node := (*goobj2.FuncInfo)(nil).ReadInlTree(fi.data, fi.lengths.InlTreeOff, uint32(k))
+ return InlTreeNode{
+ Parent: node.Parent,
+ File: fi.l.resolve(fi.r, node.File),
+ Line: node.Line,
+ Func: fi.l.resolve(fi.r, node.Func),
+ ParentPC: node.ParentPC,
+ }
+}
func (l *Loader) FuncInfo(i Sym) FuncInfo {
var r *oReader
@@ -1566,7 +1686,7 @@ func (l *Loader) FuncInfo(i Sym) FuncInfo {
a := &auxs[j]
if a.Type() == goobj2.AuxFuncInfo {
b := r.Data(int(a.Sym().SymIdx))
- return FuncInfo{l, r, b}
+ return FuncInfo{l, r, b, goobj2.FuncInfoLengths{}}
}
}
return FuncInfo{}