mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +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
6 changed files with 62 additions and 102 deletions
|
|
@ -21,10 +21,7 @@ type FuncInfo struct {
|
||||||
Locals uint32
|
Locals uint32
|
||||||
FuncID objabi.FuncID
|
FuncID objabi.FuncID
|
||||||
FuncFlag objabi.FuncFlag
|
FuncFlag objabi.FuncFlag
|
||||||
|
|
||||||
Funcdataoff []uint32
|
|
||||||
File []CUFileIndex
|
File []CUFileIndex
|
||||||
|
|
||||||
InlTree []InlTreeNode
|
InlTree []InlTreeNode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -45,10 +42,6 @@ func (a *FuncInfo) Write(w *bytes.Buffer) {
|
||||||
writeUint8(0) // pad to uint32 boundary
|
writeUint8(0) // pad to uint32 boundary
|
||||||
writeUint8(0)
|
writeUint8(0)
|
||||||
|
|
||||||
writeUint32(uint32(len(a.Funcdataoff)))
|
|
||||||
for _, x := range a.Funcdataoff {
|
|
||||||
writeUint32(x)
|
|
||||||
}
|
|
||||||
writeUint32(uint32(len(a.File)))
|
writeUint32(uint32(len(a.File)))
|
||||||
for _, f := range a.File {
|
for _, f := range a.File {
|
||||||
writeUint32(uint32(f))
|
writeUint32(uint32(f))
|
||||||
|
|
@ -65,8 +58,6 @@ func (a *FuncInfo) Write(w *bytes.Buffer) {
|
||||||
// corresponding "off" field stores the byte offset of the start of
|
// corresponding "off" field stores the byte offset of the start of
|
||||||
// the items in question.
|
// the items in question.
|
||||||
type FuncInfoLengths struct {
|
type FuncInfoLengths struct {
|
||||||
NumFuncdataoff uint32
|
|
||||||
FuncdataoffOff uint32
|
|
||||||
NumFile uint32
|
NumFile uint32
|
||||||
FileOff uint32
|
FileOff uint32
|
||||||
NumInlTree uint32
|
NumInlTree uint32
|
||||||
|
|
@ -77,13 +68,9 @@ type FuncInfoLengths struct {
|
||||||
func (*FuncInfo) ReadFuncInfoLengths(b []byte) FuncInfoLengths {
|
func (*FuncInfo) ReadFuncInfoLengths(b []byte) FuncInfoLengths {
|
||||||
var result 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.
|
// the number of bytes until we write funcdataoff to the file.
|
||||||
const numfuncdataoffOff = 12
|
const numfileOff = 12
|
||||||
result.NumFuncdataoff = binary.LittleEndian.Uint32(b[numfuncdataoffOff:])
|
|
||||||
result.FuncdataoffOff = numfuncdataoffOff + 4
|
|
||||||
|
|
||||||
numfileOff := result.FuncdataoffOff + 4*result.NumFuncdataoff
|
|
||||||
result.NumFile = binary.LittleEndian.Uint32(b[numfileOff:])
|
result.NumFile = binary.LittleEndian.Uint32(b[numfileOff:])
|
||||||
result.FileOff = numfileOff + 4
|
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) 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 {
|
func (*FuncInfo) ReadFile(b []byte, filesoff uint32, k uint32) CUFileIndex {
|
||||||
return CUFileIndex(binary.LittleEndian.Uint32(b[filesoff+4*k:]))
|
return CUFileIndex(binary.LittleEndian.Uint32(b[filesoff+4*k:]))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -836,7 +836,6 @@ type Pcln struct {
|
||||||
Pcinline *LSym
|
Pcinline *LSym
|
||||||
Pcdata []*LSym
|
Pcdata []*LSym
|
||||||
Funcdata []*LSym
|
Funcdata []*LSym
|
||||||
Funcdataoff []int64
|
|
||||||
UsedFiles map[goobj.CUFileIndex]struct{} // file indices used while generating pcfile
|
UsedFiles map[goobj.CUFileIndex]struct{} // file indices used while generating pcfile
|
||||||
InlTree InlTree // per-function inlining tree extracted from the global tree
|
InlTree InlTree // per-function inlining tree extracted from the global tree
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -671,10 +671,6 @@ func genFuncInfoSyms(ctxt *Link) {
|
||||||
FuncFlag: fn.FuncFlag,
|
FuncFlag: fn.FuncFlag,
|
||||||
}
|
}
|
||||||
pc := &fn.Pcln
|
pc := &fn.Pcln
|
||||||
o.Funcdataoff = make([]uint32, len(pc.Funcdataoff))
|
|
||||||
for i, x := range pc.Funcdataoff {
|
|
||||||
o.Funcdataoff[i] = uint32(x)
|
|
||||||
}
|
|
||||||
i := 0
|
i := 0
|
||||||
o.File = make([]goobj.CUFileIndex, len(pc.UsedFiles))
|
o.File = make([]goobj.CUFileIndex, len(pc.UsedFiles))
|
||||||
for f := range pc.UsedFiles {
|
for f := range pc.UsedFiles {
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"cmd/internal/goobj"
|
"cmd/internal/goobj"
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -280,8 +281,6 @@ func linkpcln(ctxt *Link, cursym *LSym) {
|
||||||
|
|
||||||
pcln.Pcdata = make([]*LSym, npcdata)
|
pcln.Pcdata = make([]*LSym, npcdata)
|
||||||
pcln.Funcdata = make([]*LSym, nfuncdata)
|
pcln.Funcdata = make([]*LSym, nfuncdata)
|
||||||
pcln.Funcdataoff = make([]int64, nfuncdata)
|
|
||||||
pcln.Funcdataoff = pcln.Funcdataoff[:nfuncdata]
|
|
||||||
|
|
||||||
pcln.Pcsp = funcpctab(ctxt, cursym, "pctospadj", pctospadj, nil)
|
pcln.Pcsp = funcpctab(ctxt, cursym, "pctospadj", pctospadj, nil)
|
||||||
pcln.Pcfile = funcpctab(ctxt, cursym, "pctofile", pctofileline, pcln)
|
pcln.Pcfile = funcpctab(ctxt, cursym, "pctofile", pctofileline, pcln)
|
||||||
|
|
@ -351,12 +350,10 @@ func linkpcln(ctxt *Link, cursym *LSym) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
i := int(p.From.Offset)
|
i := int(p.From.Offset)
|
||||||
pcln.Funcdataoff[i] = p.To.Offset
|
if p.To.Type != TYPE_MEM || p.To.Offset != 0 {
|
||||||
if p.To.Type != TYPE_CONST {
|
panic(fmt.Sprintf("bad funcdata: %v", p))
|
||||||
// TODO: Dedup.
|
|
||||||
//funcdata_bytes += p->to.sym->size;
|
|
||||||
pcln.Funcdata[i] = p.To.Sym
|
|
||||||
}
|
}
|
||||||
|
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.
|
// 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
|
// object. This is a helper function to make querying the FuncInfo object
|
||||||
// cleaner.
|
// 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: Preload must be called on the FuncInfo before calling.
|
||||||
// NB: fdSyms and fdOffs are used as scratch space.
|
// NB: fdSyms is used as scratch space.
|
||||||
func funcData(fi loader.FuncInfo, inlSym loader.Sym, fdSyms []loader.Sym, fdOffs []int64) ([]loader.Sym, []int64) {
|
func funcData(ldr *loader.Loader, s loader.Sym, fi loader.FuncInfo, inlSym loader.Sym, fdSyms []loader.Sym) []loader.Sym {
|
||||||
fdSyms, fdOffs = fdSyms[:0], fdOffs[:0]
|
fdSyms = fdSyms[:0]
|
||||||
if fi.Valid() {
|
if fi.Valid() {
|
||||||
numOffsets := int(fi.NumFuncdataoff())
|
fdSyms = ldr.Funcdata(s, fdSyms)
|
||||||
for i := 0; i < numOffsets; i++ {
|
|
||||||
fdOffs = append(fdOffs, fi.Funcdataoff(i))
|
|
||||||
}
|
|
||||||
fdSyms = fi.Funcdata(fdSyms)
|
|
||||||
if fi.NumInlTree() > 0 {
|
if fi.NumInlTree() > 0 {
|
||||||
if len(fdSyms) < objabi.FUNCDATA_InlTree+1 {
|
if len(fdSyms) < objabi.FUNCDATA_InlTree+1 {
|
||||||
fdSyms = append(fdSyms, make([]loader.Sym, objabi.FUNCDATA_InlTree+1-len(fdSyms))...)
|
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
|
fdSyms[objabi.FUNCDATA_InlTree] = inlSym
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return fdSyms, fdOffs
|
return fdSyms
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculateFunctabSize calculates the size of the pclntab, and the offsets in
|
// 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)
|
size += int64(state.funcSize)
|
||||||
if fi.Valid() {
|
if fi.Valid() {
|
||||||
fi.Preload()
|
fi.Preload()
|
||||||
numFuncData := int(fi.NumFuncdataoff())
|
numFuncData := ldr.NumFuncdata(s)
|
||||||
if fi.NumInlTree() > 0 {
|
if fi.NumInlTree() > 0 {
|
||||||
if numFuncData < objabi.FUNCDATA_InlTree+1 {
|
if numFuncData < objabi.FUNCDATA_InlTree+1 {
|
||||||
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.
|
// 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) {
|
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
|
ldr := ctxt.loader
|
||||||
funcdata, funcdataoff := []loader.Sym{}, []int64{}
|
funcdata := []loader.Sym{}
|
||||||
for i, s := range funcs {
|
for i, s := range funcs {
|
||||||
fi := ldr.FuncInfo(s)
|
fi := ldr.FuncInfo(s)
|
||||||
if !fi.Valid() {
|
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.
|
// funcdata, must be pointer-aligned and we're only int32-aligned.
|
||||||
// Missing funcdata will be 0 (nil pointer).
|
// 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 {
|
if len(funcdata) > 0 {
|
||||||
off := int64(startLocations[i] + state.funcSize + numPCData(ldr, s, fi)*4)
|
off := int64(startLocations[i] + state.funcSize + numPCData(ldr, s, fi)*4)
|
||||||
off = Rnd(off, int64(ctxt.Arch.PtrSize))
|
off = Rnd(off, int64(ctxt.Arch.PtrSize))
|
||||||
for j := range funcdata {
|
for j := range funcdata {
|
||||||
dataoff := off + int64(ctxt.Arch.PtrSize*j)
|
dataoff := off + int64(ctxt.Arch.PtrSize*j)
|
||||||
if funcdata[j] == 0 {
|
if funcdata[j] == 0 {
|
||||||
setUint(sb, ctxt.Arch, dataoff, uint64(funcdataoff[j]))
|
setUint(sb, ctxt.Arch, dataoff, 0)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// TODO: Does this need deduping?
|
// 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) {
|
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
|
ldr := ctxt.loader
|
||||||
deferReturnSym := ldr.Lookup("runtime.deferreturn", abiInternalVer)
|
deferReturnSym := ldr.Lookup("runtime.deferreturn", abiInternalVer)
|
||||||
funcdata, funcdataoff := []loader.Sym{}, []int64{}
|
funcdata := []loader.Sym{}
|
||||||
var pcsp, pcfile, pcline, pcinline loader.Sym
|
var pcsp, pcfile, pcline, pcinline loader.Sym
|
||||||
var pcdata []loader.Sym
|
var pcdata []loader.Sym
|
||||||
|
|
||||||
|
|
@ -839,7 +830,7 @@ func writeFuncs(ctxt *Link, sb *loader.SymbolBuilder, funcs []loader.Sym, inlSym
|
||||||
off += 1 // pad
|
off += 1 // pad
|
||||||
|
|
||||||
// nfuncdata must be the final entry.
|
// 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))))
|
off = uint32(sb.SetUint8(ctxt.Arch, int64(off), uint8(len(funcdata))))
|
||||||
|
|
||||||
// Output the pcdata.
|
// Output the pcdata.
|
||||||
|
|
|
||||||
|
|
@ -1930,12 +1930,38 @@ func (l *Loader) NumPcdata(i Sym) int {
|
||||||
return n
|
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.
|
// FuncInfo provides hooks to access goobj.FuncInfo in the objects.
|
||||||
type FuncInfo struct {
|
type FuncInfo struct {
|
||||||
l *Loader
|
l *Loader
|
||||||
r *oReader
|
r *oReader
|
||||||
data []byte
|
data []byte
|
||||||
auxs []goobj.Aux
|
|
||||||
lengths goobj.FuncInfoLengths
|
lengths goobj.FuncInfoLengths
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1963,38 +1989,6 @@ func (fi *FuncInfo) Preload() {
|
||||||
fi.lengths = (*goobj.FuncInfo)(nil).ReadFuncInfoLengths(fi.data)
|
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 {
|
func (fi *FuncInfo) NumFile() uint32 {
|
||||||
if !fi.lengths.Initialized {
|
if !fi.lengths.Initialized {
|
||||||
panic("need to call Preload first")
|
panic("need to call Preload first")
|
||||||
|
|
@ -2051,7 +2045,7 @@ func (l *Loader) FuncInfo(i Sym) FuncInfo {
|
||||||
a := &auxs[j]
|
a := &auxs[j]
|
||||||
if a.Type() == goobj.AuxFuncInfo {
|
if a.Type() == goobj.AuxFuncInfo {
|
||||||
b := r.Data(a.Sym().SymIdx)
|
b := r.Data(a.Sym().SymIdx)
|
||||||
return FuncInfo{l, r, b, auxs, goobj.FuncInfoLengths{}}
|
return FuncInfo{l, r, b, goobj.FuncInfoLengths{}}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return FuncInfo{}
|
return FuncInfo{}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue