From: Cherry Mui Date: Tue, 28 Sep 2021 21:07:01 +0000 (-0400) Subject: cmd/internal/goobj, cmd/link: remove funcdataoff X-Git-Tag: go1.18beta1~1134 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=e180e2c27c3c3f06a4df6352386efedc15a1e38c;p=gostls13.git cmd/internal/goobj, cmd/link: remove funcdataoff FUNCDATA is always a symbol reference with 0 offset. Assert the offset is 0 and remove funcdataoff. Change-Id: I326815365c9db5aeef6b869df5d78a9957bc16a6 Reviewed-on: https://go-review.googlesource.com/c/go/+/352894 Trust: Cherry Mui Reviewed-by: Than McIntosh --- diff --git a/src/cmd/internal/goobj/funcinfo.go b/src/cmd/internal/goobj/funcinfo.go index 6e7970fb74..59cb957fa7 100644 --- a/src/cmd/internal/goobj/funcinfo.go +++ b/src/cmd/internal/goobj/funcinfo.go @@ -21,11 +21,8 @@ type FuncInfo struct { Locals uint32 FuncID objabi.FuncID FuncFlag objabi.FuncFlag - - Funcdataoff []uint32 - File []CUFileIndex - - InlTree []InlTreeNode + File []CUFileIndex + InlTree []InlTreeNode } func (a *FuncInfo) Write(w *bytes.Buffer) { @@ -45,10 +42,6 @@ func (a *FuncInfo) Write(w *bytes.Buffer) { writeUint8(0) // pad to uint32 boundary writeUint8(0) - writeUint32(uint32(len(a.Funcdataoff))) - for _, x := range a.Funcdataoff { - writeUint32(x) - } writeUint32(uint32(len(a.File))) for _, f := range a.File { writeUint32(uint32(f)) @@ -65,25 +58,19 @@ func (a *FuncInfo) Write(w *bytes.Buffer) { // corresponding "off" field stores the byte offset of the start of // the items in question. type FuncInfoLengths struct { - NumFuncdataoff uint32 - FuncdataoffOff uint32 - NumFile uint32 - FileOff uint32 - NumInlTree uint32 - InlTreeOff uint32 - Initialized bool + NumFile uint32 + FileOff uint32 + NumInlTree uint32 + InlTreeOff uint32 + Initialized bool } func (*FuncInfo) ReadFuncInfoLengths(b []byte) FuncInfoLengths { var result FuncInfoLengths - // Offset to the number of funcdataoff values. This value is determined by counting + // Offset to the number of the file table. This value is determined by counting // the number of bytes until we write funcdataoff to the file. - const numfuncdataoffOff = 12 - result.NumFuncdataoff = binary.LittleEndian.Uint32(b[numfuncdataoffOff:]) - result.FuncdataoffOff = numfuncdataoffOff + 4 - - numfileOff := result.FuncdataoffOff + 4*result.NumFuncdataoff + const numfileOff = 12 result.NumFile = binary.LittleEndian.Uint32(b[numfileOff:]) result.FileOff = numfileOff + 4 @@ -104,10 +91,6 @@ func (*FuncInfo) ReadFuncID(b []byte) objabi.FuncID { return objabi.FuncID(b[8]) func (*FuncInfo) ReadFuncFlag(b []byte) objabi.FuncFlag { return objabi.FuncFlag(b[9]) } -func (*FuncInfo) ReadFuncdataoff(b []byte, funcdataofffoff uint32, k uint32) int64 { - return int64(binary.LittleEndian.Uint32(b[funcdataofffoff+4*k:])) -} - func (*FuncInfo) ReadFile(b []byte, filesoff uint32, k uint32) CUFileIndex { return CUFileIndex(binary.LittleEndian.Uint32(b[filesoff+4*k:])) } diff --git a/src/cmd/internal/obj/link.go b/src/cmd/internal/obj/link.go index 82ff5994d1..abb37416cc 100644 --- a/src/cmd/internal/obj/link.go +++ b/src/cmd/internal/obj/link.go @@ -830,15 +830,14 @@ func (*LSym) CanBeAnSSAAux() {} type Pcln struct { // Aux symbols for pcln - Pcsp *LSym - Pcfile *LSym - Pcline *LSym - Pcinline *LSym - Pcdata []*LSym - Funcdata []*LSym - Funcdataoff []int64 - UsedFiles map[goobj.CUFileIndex]struct{} // file indices used while generating pcfile - InlTree InlTree // per-function inlining tree extracted from the global tree + Pcsp *LSym + Pcfile *LSym + Pcline *LSym + Pcinline *LSym + Pcdata []*LSym + Funcdata []*LSym + UsedFiles map[goobj.CUFileIndex]struct{} // file indices used while generating pcfile + InlTree InlTree // per-function inlining tree extracted from the global tree } type Reloc struct { diff --git a/src/cmd/internal/obj/objfile.go b/src/cmd/internal/obj/objfile.go index bed32198d7..3d8d69f069 100644 --- a/src/cmd/internal/obj/objfile.go +++ b/src/cmd/internal/obj/objfile.go @@ -671,10 +671,6 @@ func genFuncInfoSyms(ctxt *Link) { FuncFlag: fn.FuncFlag, } pc := &fn.Pcln - o.Funcdataoff = make([]uint32, len(pc.Funcdataoff)) - for i, x := range pc.Funcdataoff { - o.Funcdataoff[i] = uint32(x) - } i := 0 o.File = make([]goobj.CUFileIndex, len(pc.UsedFiles)) for f := range pc.UsedFiles { diff --git a/src/cmd/internal/obj/pcln.go b/src/cmd/internal/obj/pcln.go index 42c4a2a9d9..49b425b124 100644 --- a/src/cmd/internal/obj/pcln.go +++ b/src/cmd/internal/obj/pcln.go @@ -8,6 +8,7 @@ import ( "cmd/internal/goobj" "cmd/internal/objabi" "encoding/binary" + "fmt" "log" ) @@ -280,8 +281,6 @@ func linkpcln(ctxt *Link, cursym *LSym) { pcln.Pcdata = make([]*LSym, npcdata) pcln.Funcdata = make([]*LSym, nfuncdata) - pcln.Funcdataoff = make([]int64, nfuncdata) - pcln.Funcdataoff = pcln.Funcdataoff[:nfuncdata] pcln.Pcsp = funcpctab(ctxt, cursym, "pctospadj", pctospadj, nil) pcln.Pcfile = funcpctab(ctxt, cursym, "pctofile", pctofileline, pcln) @@ -351,12 +350,10 @@ func linkpcln(ctxt *Link, cursym *LSym) { continue } i := int(p.From.Offset) - pcln.Funcdataoff[i] = p.To.Offset - if p.To.Type != TYPE_CONST { - // TODO: Dedup. - //funcdata_bytes += p->to.sym->size; - pcln.Funcdata[i] = p.To.Sym + if p.To.Type != TYPE_MEM || p.To.Offset != 0 { + panic(fmt.Sprintf("bad funcdata: %v", p)) } + pcln.Funcdata[i] = p.To.Sym } } } diff --git a/src/cmd/link/internal/ld/pcln.go b/src/cmd/link/internal/ld/pcln.go index c8cd7bf09e..f319c10b5b 100644 --- a/src/cmd/link/internal/ld/pcln.go +++ b/src/cmd/link/internal/ld/pcln.go @@ -623,33 +623,24 @@ func (state *pclntab) generateFunctab(ctxt *Link, funcs []loader.Sym, inlSyms ma } // funcData returns the funcdata and offsets for the FuncInfo. -// The funcdata and offsets are written into runtime.functab after each func +// The funcdata are written into runtime.functab after each func // object. This is a helper function to make querying the FuncInfo object // cleaner. // -// Note, the majority of fdOffsets are 0, meaning there is no offset between -// the compiler's generated symbol, and what the runtime needs. They are -// plumbed through for no loss of generality. -// // NB: Preload must be called on the FuncInfo before calling. -// NB: fdSyms and fdOffs are used as scratch space. -func funcData(fi loader.FuncInfo, inlSym loader.Sym, fdSyms []loader.Sym, fdOffs []int64) ([]loader.Sym, []int64) { - fdSyms, fdOffs = fdSyms[:0], fdOffs[:0] +// NB: fdSyms is used as scratch space. +func funcData(ldr *loader.Loader, s loader.Sym, fi loader.FuncInfo, inlSym loader.Sym, fdSyms []loader.Sym) []loader.Sym { + fdSyms = fdSyms[:0] if fi.Valid() { - numOffsets := int(fi.NumFuncdataoff()) - for i := 0; i < numOffsets; i++ { - fdOffs = append(fdOffs, fi.Funcdataoff(i)) - } - fdSyms = fi.Funcdata(fdSyms) + 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))...) - fdOffs = append(fdOffs, make([]int64, objabi.FUNCDATA_InlTree+1-len(fdOffs))...) } fdSyms[objabi.FUNCDATA_InlTree] = inlSym } } - return fdSyms, fdOffs + return fdSyms } // calculateFunctabSize calculates the size of the pclntab, and the offsets in @@ -673,7 +664,7 @@ func (state pclntab) calculateFunctabSize(ctxt *Link, funcs []loader.Sym) (int64 size += int64(state.funcSize) if fi.Valid() { fi.Preload() - numFuncData := int(fi.NumFuncdataoff()) + numFuncData := ldr.NumFuncdata(s) if fi.NumInlTree() > 0 { if numFuncData < objabi.FUNCDATA_InlTree+1 { numFuncData = objabi.FUNCDATA_InlTree + 1 @@ -738,7 +729,7 @@ func writePCToFunc(ctxt *Link, sb *loader.SymbolBuilder, funcs []loader.Sym, sta // generateFunctab. func (state *pclntab) writeFuncData(ctxt *Link, sb *loader.SymbolBuilder, funcs []loader.Sym, inlSyms map[loader.Sym]loader.Sym, startLocations []uint32, setAddr pclnSetAddr, setUint pclnSetUint) { ldr := ctxt.loader - funcdata, funcdataoff := []loader.Sym{}, []int64{} + funcdata := []loader.Sym{} for i, s := range funcs { fi := ldr.FuncInfo(s) if !fi.Valid() { @@ -748,18 +739,18 @@ func (state *pclntab) writeFuncData(ctxt *Link, sb *loader.SymbolBuilder, funcs // funcdata, must be pointer-aligned and we're only int32-aligned. // Missing funcdata will be 0 (nil pointer). - funcdata, funcdataoff := funcData(fi, inlSyms[s], funcdata, funcdataoff) + funcdata = funcData(ldr, s, fi, inlSyms[s], funcdata) if len(funcdata) > 0 { off := int64(startLocations[i] + state.funcSize + numPCData(ldr, s, fi)*4) off = Rnd(off, int64(ctxt.Arch.PtrSize)) for j := range funcdata { dataoff := off + int64(ctxt.Arch.PtrSize*j) if funcdata[j] == 0 { - setUint(sb, ctxt.Arch, dataoff, uint64(funcdataoff[j])) + setUint(sb, ctxt.Arch, dataoff, 0) continue } // TODO: Does this need deduping? - setAddr(sb, ctxt.Arch, dataoff, funcdata[j], funcdataoff[j]) + setAddr(sb, ctxt.Arch, dataoff, funcdata[j], 0) } } } @@ -769,7 +760,7 @@ func (state *pclntab) writeFuncData(ctxt *Link, sb *loader.SymbolBuilder, funcs func writeFuncs(ctxt *Link, sb *loader.SymbolBuilder, funcs []loader.Sym, inlSyms map[loader.Sym]loader.Sym, startLocations, cuOffsets []uint32, nameOffsets map[loader.Sym]uint32) { ldr := ctxt.loader deferReturnSym := ldr.Lookup("runtime.deferreturn", abiInternalVer) - funcdata, funcdataoff := []loader.Sym{}, []int64{} + funcdata := []loader.Sym{} var pcsp, pcfile, pcline, pcinline loader.Sym var pcdata []loader.Sym @@ -839,7 +830,7 @@ func writeFuncs(ctxt *Link, sb *loader.SymbolBuilder, funcs []loader.Sym, inlSym off += 1 // pad // nfuncdata must be the final entry. - funcdata, funcdataoff = funcData(fi, 0, funcdata, funcdataoff) + funcdata = funcData(ldr, s, fi, 0, funcdata) off = uint32(sb.SetUint8(ctxt.Arch, int64(off), uint8(len(funcdata)))) // Output the pcdata. diff --git a/src/cmd/link/internal/loader/loader.go b/src/cmd/link/internal/loader/loader.go index ec145da26d..9b7888e940 100644 --- a/src/cmd/link/internal/loader/loader.go +++ b/src/cmd/link/internal/loader/loader.go @@ -1930,12 +1930,38 @@ func (l *Loader) NumPcdata(i Sym) int { return n } +// Returns all funcdata symbols of symbol i. +// tmp is a scratch space. +func (l *Loader) Funcdata(i Sym, tmp []Sym) []Sym { + fd := tmp[:0] + r, auxs := l.auxs(i) + for j := range auxs { + a := &auxs[j] + if a.Type() == goobj.AuxFuncdata { + fd = append(fd, l.resolve(r, a.Sym())) + } + } + return fd +} + +// Returns the number of funcdata for symbol i. +func (l *Loader) NumFuncdata(i Sym) int { + n := 0 + _, auxs := l.auxs(i) + for j := range auxs { + a := &auxs[j] + if a.Type() == goobj.AuxFuncdata { + n++ + } + } + return n +} + // FuncInfo provides hooks to access goobj.FuncInfo in the objects. type FuncInfo struct { l *Loader r *oReader data []byte - auxs []goobj.Aux lengths goobj.FuncInfoLengths } @@ -1963,38 +1989,6 @@ func (fi *FuncInfo) Preload() { fi.lengths = (*goobj.FuncInfo)(nil).ReadFuncInfoLengths(fi.data) } -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 (*goobj.FuncInfo)(nil).ReadFuncdataoff(fi.data, fi.lengths.FuncdataoffOff, uint32(k)) -} - -func (fi *FuncInfo) Funcdata(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] - } - for j := range fi.auxs { - a := &fi.auxs[j] - if a.Type() == goobj.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") @@ -2051,7 +2045,7 @@ func (l *Loader) FuncInfo(i Sym) FuncInfo { a := &auxs[j] if a.Type() == goobj.AuxFuncInfo { b := r.Data(a.Sym().SymIdx) - return FuncInfo{l, r, b, auxs, goobj.FuncInfoLengths{}} + return FuncInfo{l, r, b, goobj.FuncInfoLengths{}} } } return FuncInfo{}