mirror of
https://github.com/golang/go
synced 2024-10-06 08:00:07 +00:00
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 <cherryyz@google.com> Reviewed-by: Than McIntosh <thanm@google.com>
This commit is contained in:
parent
587b3c1192
commit
e180e2c27c
|
@ -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:]))
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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{}
|
||||
|
|
Loading…
Reference in a new issue