From: Cherry Zhang Date: Tue, 25 Feb 2020 20:14:31 +0000 (-0500) Subject: [dev.link] cmd/internal/goobj2, cmd/link: add accessors for field of FuncInfo X-Git-Tag: go1.15beta1~679^2~117 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=e00da38b81897d29857a6ce3eae01729da813fba;p=gostls13.git [dev.link] cmd/internal/goobj2, cmd/link: add accessors for field of FuncInfo Add accessors for fields of FuncInfo, so we don't have to read the whole FuncInfo. TODO: explore/experiment with an alternative idea -- splitting FuncInfo to separate Aux symbols. Change-Id: Ie4bc2613fd76d08fc63fd86956802920da63dd2f Reviewed-on: https://go-review.googlesource.com/c/go/+/220979 Run-TryBot: Cherry Zhang Reviewed-by: Than McIntosh --- diff --git a/src/cmd/internal/goobj2/funcinfo.go b/src/cmd/internal/goobj2/funcinfo.go index d8cfd3d02d..053d7adc15 100644 --- a/src/cmd/internal/goobj2/funcinfo.go +++ b/src/cmd/internal/goobj2/funcinfo.go @@ -100,6 +100,16 @@ func (a *FuncInfo) Read(b []byte) { } } +// Accessors reading only some fields. +// TODO: more accessors. + +func (*FuncInfo) ReadLocals(b []byte) uint32 { return binary.LittleEndian.Uint32(b[4:]) } + +// return start and end offsets. +func (*FuncInfo) ReadPcsp(b []byte) (uint32, uint32) { + return binary.LittleEndian.Uint32(b[8:]), binary.LittleEndian.Uint32(b[12:]) +} + // InlTreeNode is the serialized form of FileInfo.InlTree. type InlTreeNode struct { Parent int32 diff --git a/src/cmd/link/internal/loader/loader.go b/src/cmd/link/internal/loader/loader.go index 1ff123efbb..51d210d9f5 100644 --- a/src/cmd/link/internal/loader/loader.go +++ b/src/cmd/link/internal/loader/loader.go @@ -1527,6 +1527,43 @@ func (x RelocByOff) Len() int { return len(x) } func (x RelocByOff) Swap(i, j int) { x[i], x[j] = x[j], x[i] } 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 +} + +func (fi *FuncInfo) Valid() bool { return fi.r != nil } + +func (fi *FuncInfo) Locals() int { + return int((*goobj2.FuncInfo)(nil).ReadLocals(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)) +} + +// TODO: more accessors. + +func (l *Loader) FuncInfo(i Sym) FuncInfo { + if l.IsExternal(i) { + return FuncInfo{} + } + r, li := l.toLocal(i) + n := r.NAux(li) + for j := 0; j < n; j++ { + a := goobj2.Aux{} + a.Read(r.Reader, r.AuxOff(li, j)) + if a.Type == goobj2.AuxFuncInfo { + b := r.Data(int(a.Sym.SymIdx)) + return FuncInfo{l, r, b} + } + } + return FuncInfo{} +} + // Preload a package: add autolibs, add defined package symbols to the symbol table. // Does not add non-package symbols yet, which will be done in LoadNonpkgSyms. // Does not read symbol data.