mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.link] cmd/{compile,link}: remove pcdata tables from pclntab_old
Move the pctables out of pclntab_old. Creates a new generator symbol, runtime.pctab, which holds all the deduplicated pctables. Also, tightens up some of the types in runtime. Darwin, cmd/compile statistics: alloc/op Pclntab_GC 26.4MB ± 0% 13.8MB ± 0% allocs/op Pclntab_GC 89.9k ± 0% 86.4k ± 0% liveB Pclntab_GC 25.5M ± 0% 24.2M ± 0% No significant change in binary size. Change-Id: I1560fd4421f8a210f8d4b508fbc54e1780e338f9 Reviewed-on: https://go-review.googlesource.com/c/go/+/248332 Run-TryBot: Jeremy Faller <jeremy@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
parent
5387cdcb24
commit
26407b2212
8 changed files with 136 additions and 72 deletions
|
|
@ -1925,6 +1925,7 @@ func (state *dodataState) allocateDataSections(ctxt *Link) {
|
||||||
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.funcnametab", 0), sect)
|
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.funcnametab", 0), sect)
|
||||||
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.cutab", 0), sect)
|
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.cutab", 0), sect)
|
||||||
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.filetab", 0), sect)
|
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.filetab", 0), sect)
|
||||||
|
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.pctab", 0), sect)
|
||||||
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.pclntab_old", 0), sect)
|
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.pclntab_old", 0), sect)
|
||||||
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.epclntab", 0), sect)
|
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.epclntab", 0), sect)
|
||||||
if ctxt.HeadType == objabi.Haix {
|
if ctxt.HeadType == objabi.Haix {
|
||||||
|
|
@ -2511,6 +2512,7 @@ func (ctxt *Link) address() []*sym.Segment {
|
||||||
ctxt.defineInternal("runtime.funcnametab", sym.SRODATA)
|
ctxt.defineInternal("runtime.funcnametab", sym.SRODATA)
|
||||||
ctxt.defineInternal("runtime.cutab", sym.SRODATA)
|
ctxt.defineInternal("runtime.cutab", sym.SRODATA)
|
||||||
ctxt.defineInternal("runtime.filetab", sym.SRODATA)
|
ctxt.defineInternal("runtime.filetab", sym.SRODATA)
|
||||||
|
ctxt.defineInternal("runtime.pctab", sym.SRODATA)
|
||||||
ctxt.defineInternal("runtime.pclntab_old", sym.SRODATA)
|
ctxt.defineInternal("runtime.pclntab_old", sym.SRODATA)
|
||||||
ctxt.xdefine("runtime.epclntab", sym.SRODATA, int64(pclntab.Vaddr+pclntab.Length))
|
ctxt.xdefine("runtime.epclntab", sym.SRODATA, int64(pclntab.Vaddr+pclntab.Length))
|
||||||
ctxt.xdefine("runtime.noptrdata", sym.SNOPTRDATA, int64(noptr.Vaddr))
|
ctxt.xdefine("runtime.noptrdata", sym.SNOPTRDATA, int64(noptr.Vaddr))
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ type pclntab struct {
|
||||||
findfunctab loader.Sym
|
findfunctab loader.Sym
|
||||||
cutab loader.Sym
|
cutab loader.Sym
|
||||||
filetab loader.Sym
|
filetab loader.Sym
|
||||||
|
pctab loader.Sym
|
||||||
|
|
||||||
// The number of functions + number of TEXT sections - 1. This is such an
|
// The number of functions + number of TEXT sections - 1. This is such an
|
||||||
// unexpected value because platforms that have more than one TEXT section
|
// unexpected value because platforms that have more than one TEXT section
|
||||||
|
|
@ -273,10 +274,11 @@ func (state *pclntab) generatePCHeader(ctxt *Link) {
|
||||||
off = writeSymOffset(off, state.funcnametab)
|
off = writeSymOffset(off, state.funcnametab)
|
||||||
off = writeSymOffset(off, state.cutab)
|
off = writeSymOffset(off, state.cutab)
|
||||||
off = writeSymOffset(off, state.filetab)
|
off = writeSymOffset(off, state.filetab)
|
||||||
|
off = writeSymOffset(off, state.pctab)
|
||||||
off = writeSymOffset(off, state.pclntab)
|
off = writeSymOffset(off, state.pclntab)
|
||||||
}
|
}
|
||||||
|
|
||||||
size := int64(8 + 6*ctxt.Arch.PtrSize)
|
size := int64(8 + 7*ctxt.Arch.PtrSize)
|
||||||
state.pcheader = state.addGeneratedSym(ctxt, "runtime.pcheader", size, writeHeader)
|
state.pcheader = state.addGeneratedSym(ctxt, "runtime.pcheader", size, writeHeader)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -463,6 +465,68 @@ func (state *pclntab) generateFilenameTabs(ctxt *Link, compUnits []*sym.Compilat
|
||||||
return cuOffsets
|
return cuOffsets
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// generatePctab creates the runtime.pctab variable, holding all the
|
||||||
|
// deduplicated pcdata.
|
||||||
|
func (state *pclntab) generatePctab(ctxt *Link, container loader.Bitmap) {
|
||||||
|
ldr := ctxt.loader
|
||||||
|
|
||||||
|
// Pctab offsets of 0 are considered invalid in the runtime. We respect
|
||||||
|
// that by just padding a single byte at the beginning of runtime.pctab,
|
||||||
|
// that way no real offsets can be zero.
|
||||||
|
size := int64(1)
|
||||||
|
|
||||||
|
// Walk the functions, finding offset to store each pcdata.
|
||||||
|
seen := make(map[loader.Sym]struct{})
|
||||||
|
saveOffset := func(pcSym loader.Sym) {
|
||||||
|
if _, ok := seen[pcSym]; !ok {
|
||||||
|
datSize := ldr.SymSize(pcSym)
|
||||||
|
if datSize != 0 {
|
||||||
|
ldr.SetSymValue(pcSym, size)
|
||||||
|
} else {
|
||||||
|
// Invalid PC data, record as zero.
|
||||||
|
ldr.SetSymValue(pcSym, 0)
|
||||||
|
}
|
||||||
|
size += datSize
|
||||||
|
seen[pcSym] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, s := range ctxt.Textp {
|
||||||
|
if !emitPcln(ctxt, s, container) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fi := ldr.FuncInfo(s)
|
||||||
|
if !fi.Valid() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fi.Preload()
|
||||||
|
|
||||||
|
pcSyms := []loader.Sym{fi.Pcsp(), fi.Pcfile(), fi.Pcline()}
|
||||||
|
for _, pcSym := range pcSyms {
|
||||||
|
saveOffset(pcSym)
|
||||||
|
}
|
||||||
|
for _, pcSym := range fi.Pcdata() {
|
||||||
|
saveOffset(pcSym)
|
||||||
|
}
|
||||||
|
if fi.NumInlTree() > 0 {
|
||||||
|
saveOffset(fi.Pcinline())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: There is no reason we need a generator for this variable, and it
|
||||||
|
// could be moved to a carrier symbol. However, carrier symbols containing
|
||||||
|
// carrier symbols don't work yet (as of Aug 2020). Once this is fixed,
|
||||||
|
// runtime.pctab could just be a carrier sym.
|
||||||
|
writePctab := func(ctxt *Link, s loader.Sym) {
|
||||||
|
ldr := ctxt.loader
|
||||||
|
sb := ldr.MakeSymbolUpdater(s)
|
||||||
|
for sym := range seen {
|
||||||
|
sb.SetBytesAt(ldr.SymValue(sym), ldr.Data(sym))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
state.pctab = state.addGeneratedSym(ctxt, "runtime.pctab", size, writePctab)
|
||||||
|
}
|
||||||
|
|
||||||
// pclntab initializes the pclntab symbol with
|
// pclntab initializes the pclntab symbol with
|
||||||
// runtime function and file name information.
|
// runtime function and file name information.
|
||||||
|
|
||||||
|
|
@ -494,6 +558,9 @@ func (ctxt *Link) pclntab(container loader.Bitmap) *pclntab {
|
||||||
// runtime.filetab
|
// runtime.filetab
|
||||||
// []null terminated filename strings
|
// []null terminated filename strings
|
||||||
//
|
//
|
||||||
|
// runtime.pctab
|
||||||
|
// []byte of deduplicated pc data.
|
||||||
|
//
|
||||||
// runtime.pclntab_old
|
// runtime.pclntab_old
|
||||||
// function table, alternating PC and offset to func struct [each entry thearch.ptrsize bytes]
|
// function table, alternating PC and offset to func struct [each entry thearch.ptrsize bytes]
|
||||||
// end PC [thearch.ptrsize bytes]
|
// end PC [thearch.ptrsize bytes]
|
||||||
|
|
@ -514,6 +581,7 @@ func (ctxt *Link) pclntab(container loader.Bitmap) *pclntab {
|
||||||
state.generatePCHeader(ctxt)
|
state.generatePCHeader(ctxt)
|
||||||
state.generateFuncnametab(ctxt, container)
|
state.generateFuncnametab(ctxt, container)
|
||||||
cuOffsets := state.generateFilenameTabs(ctxt, compUnits, container)
|
cuOffsets := state.generateFilenameTabs(ctxt, compUnits, container)
|
||||||
|
state.generatePctab(ctxt, container)
|
||||||
|
|
||||||
funcdataBytes := int64(0)
|
funcdataBytes := int64(0)
|
||||||
ldr.SetCarrierSym(state.pclntab, state.carrier)
|
ldr.SetCarrierSym(state.pclntab, state.carrier)
|
||||||
|
|
@ -525,21 +593,6 @@ func (ctxt *Link) pclntab(container loader.Bitmap) *pclntab {
|
||||||
|
|
||||||
ftab.Grow(int64(state.nfunc)*2*int64(ctxt.Arch.PtrSize) + int64(ctxt.Arch.PtrSize) + 4)
|
ftab.Grow(int64(state.nfunc)*2*int64(ctxt.Arch.PtrSize) + int64(ctxt.Arch.PtrSize) + 4)
|
||||||
|
|
||||||
szHint := len(ctxt.Textp) * 2
|
|
||||||
pctaboff := make(map[string]uint32, szHint)
|
|
||||||
writepctab := func(off int32, p []byte) int32 {
|
|
||||||
start, ok := pctaboff[string(p)]
|
|
||||||
if !ok {
|
|
||||||
if len(p) > 0 {
|
|
||||||
start = uint32(len(ftab.Data()))
|
|
||||||
ftab.AddBytes(p)
|
|
||||||
}
|
|
||||||
pctaboff[string(p)] = start
|
|
||||||
}
|
|
||||||
newoff := int32(ftab.SetUint32(ctxt.Arch, int64(off), start))
|
|
||||||
return newoff
|
|
||||||
}
|
|
||||||
|
|
||||||
setAddr := (*loader.SymbolBuilder).SetAddrPlus
|
setAddr := (*loader.SymbolBuilder).SetAddrPlus
|
||||||
if ctxt.IsExe() && ctxt.IsInternal() {
|
if ctxt.IsExe() && ctxt.IsInternal() {
|
||||||
// Internal linking static executable. At this point the function
|
// Internal linking static executable. At this point the function
|
||||||
|
|
@ -555,10 +608,6 @@ func (ctxt *Link) pclntab(container loader.Bitmap) *pclntab {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pcsp := sym.Pcdata{}
|
|
||||||
pcfile := sym.Pcdata{}
|
|
||||||
pcline := sym.Pcdata{}
|
|
||||||
pcdata := []sym.Pcdata{}
|
|
||||||
funcdata := []loader.Sym{}
|
funcdata := []loader.Sym{}
|
||||||
funcdataoff := []int64{}
|
funcdataoff := []int64{}
|
||||||
|
|
||||||
|
|
@ -583,18 +632,13 @@ func (ctxt *Link) pclntab(container loader.Bitmap) *pclntab {
|
||||||
}
|
}
|
||||||
prevFunc = s
|
prevFunc = s
|
||||||
|
|
||||||
pcsp.P = pcsp.P[:0]
|
var numPCData int32
|
||||||
pcline.P = pcline.P[:0]
|
|
||||||
pcfile.P = pcfile.P[:0]
|
|
||||||
pcdata = pcdata[:0]
|
|
||||||
funcdataoff = funcdataoff[:0]
|
funcdataoff = funcdataoff[:0]
|
||||||
funcdata = funcdata[:0]
|
funcdata = funcdata[:0]
|
||||||
fi := ldr.FuncInfo(s)
|
fi := ldr.FuncInfo(s)
|
||||||
if fi.Valid() {
|
if fi.Valid() {
|
||||||
fi.Preload()
|
fi.Preload()
|
||||||
for _, dataSym := range fi.Pcdata() {
|
numPCData = int32(len(fi.Pcdata()))
|
||||||
pcdata = append(pcdata, sym.Pcdata{P: ldr.Data(dataSym)})
|
|
||||||
}
|
|
||||||
nfd := fi.NumFuncdataoff()
|
nfd := fi.NumFuncdataoff()
|
||||||
for i := uint32(0); i < nfd; i++ {
|
for i := uint32(0); i < nfd; i++ {
|
||||||
funcdataoff = append(funcdataoff, fi.Funcdataoff(int(i)))
|
funcdataoff = append(funcdataoff, fi.Funcdataoff(int(i)))
|
||||||
|
|
@ -602,15 +646,12 @@ func (ctxt *Link) pclntab(container loader.Bitmap) *pclntab {
|
||||||
funcdata = fi.Funcdata(funcdata)
|
funcdata = fi.Funcdata(funcdata)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
writeInlPCData := false
|
||||||
if fi.Valid() && fi.NumInlTree() > 0 {
|
if fi.Valid() && fi.NumInlTree() > 0 {
|
||||||
|
writeInlPCData = true
|
||||||
if len(pcdata) <= objabi.PCDATA_InlTreeIndex {
|
if numPCData <= objabi.PCDATA_InlTreeIndex {
|
||||||
// Create inlining pcdata table.
|
numPCData = objabi.PCDATA_InlTreeIndex + 1
|
||||||
newpcdata := make([]sym.Pcdata, objabi.PCDATA_InlTreeIndex+1)
|
|
||||||
copy(newpcdata, pcdata)
|
|
||||||
pcdata = newpcdata
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(funcdataoff) <= objabi.FUNCDATA_InlTree {
|
if len(funcdataoff) <= objabi.FUNCDATA_InlTree {
|
||||||
// Create inline tree funcdata.
|
// Create inline tree funcdata.
|
||||||
newfuncdata := make([]loader.Sym, objabi.FUNCDATA_InlTree+1)
|
newfuncdata := make([]loader.Sym, objabi.FUNCDATA_InlTree+1)
|
||||||
|
|
@ -635,7 +676,7 @@ func (ctxt *Link) pclntab(container loader.Bitmap) *pclntab {
|
||||||
// fixed size of struct, checked below
|
// fixed size of struct, checked below
|
||||||
off := funcstart
|
off := funcstart
|
||||||
|
|
||||||
end := funcstart + int32(ctxt.Arch.PtrSize) + 3*4 + 6*4 + int32(len(pcdata))*4 + int32(len(funcdata))*int32(ctxt.Arch.PtrSize)
|
end := funcstart + int32(ctxt.Arch.PtrSize) + 3*4 + 6*4 + numPCData*4 + int32(len(funcdata))*int32(ctxt.Arch.PtrSize)
|
||||||
if len(funcdata) > 0 && (end&int32(ctxt.Arch.PtrSize-1) != 0) {
|
if len(funcdata) > 0 && (end&int32(ctxt.Arch.PtrSize-1) != 0) {
|
||||||
end += 4
|
end += 4
|
||||||
}
|
}
|
||||||
|
|
@ -664,23 +705,21 @@ func (ctxt *Link) pclntab(container loader.Bitmap) *pclntab {
|
||||||
off = int32(ftab.SetUint32(ctxt.Arch, int64(off), deferreturn))
|
off = int32(ftab.SetUint32(ctxt.Arch, int64(off), deferreturn))
|
||||||
|
|
||||||
cu := ldr.SymUnit(s)
|
cu := ldr.SymUnit(s)
|
||||||
if fi.Valid() {
|
|
||||||
pcsp = sym.Pcdata{P: ldr.Data(fi.Pcsp())}
|
|
||||||
pcfile = sym.Pcdata{P: ldr.Data(fi.Pcfile())}
|
|
||||||
pcline = sym.Pcdata{P: ldr.Data(fi.Pcline())}
|
|
||||||
}
|
|
||||||
|
|
||||||
if fi.Valid() && fi.NumInlTree() > 0 {
|
if fi.Valid() && fi.NumInlTree() > 0 {
|
||||||
its := oldState.genInlTreeSym(cu, fi, ctxt.Arch, state)
|
its := oldState.genInlTreeSym(cu, fi, ctxt.Arch, state)
|
||||||
funcdata[objabi.FUNCDATA_InlTree] = its
|
funcdata[objabi.FUNCDATA_InlTree] = its
|
||||||
pcdata[objabi.PCDATA_InlTreeIndex] = sym.Pcdata{P: ldr.Data(fi.Pcinline())}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// pcdata
|
// pcdata
|
||||||
off = writepctab(off, pcsp.P)
|
if fi.Valid() {
|
||||||
off = writepctab(off, pcfile.P)
|
off = int32(ftab.SetUint32(ctxt.Arch, int64(off), uint32(ldr.SymValue(fi.Pcsp()))))
|
||||||
off = writepctab(off, pcline.P)
|
off = int32(ftab.SetUint32(ctxt.Arch, int64(off), uint32(ldr.SymValue(fi.Pcfile()))))
|
||||||
off = int32(ftab.SetUint32(ctxt.Arch, int64(off), uint32(len(pcdata))))
|
off = int32(ftab.SetUint32(ctxt.Arch, int64(off), uint32(ldr.SymValue(fi.Pcline()))))
|
||||||
|
} else {
|
||||||
|
off += 12
|
||||||
|
}
|
||||||
|
off = int32(ftab.SetUint32(ctxt.Arch, int64(off), uint32(numPCData)))
|
||||||
|
|
||||||
// Store the offset to compilation unit's file table.
|
// Store the offset to compilation unit's file table.
|
||||||
cuIdx := ^uint32(0)
|
cuIdx := ^uint32(0)
|
||||||
|
|
@ -700,9 +739,17 @@ func (ctxt *Link) pclntab(container loader.Bitmap) *pclntab {
|
||||||
|
|
||||||
// nfuncdata must be the final entry.
|
// nfuncdata must be the final entry.
|
||||||
off = int32(ftab.SetUint8(ctxt.Arch, int64(off), uint8(len(funcdata))))
|
off = int32(ftab.SetUint8(ctxt.Arch, int64(off), uint8(len(funcdata))))
|
||||||
for i := range pcdata {
|
|
||||||
off = writepctab(off, pcdata[i].P)
|
// Output the pcdata.
|
||||||
|
if fi.Valid() {
|
||||||
|
for i, pcSym := range fi.Pcdata() {
|
||||||
|
ftab.SetUint32(ctxt.Arch, int64(off+int32(i*4)), uint32(ldr.SymValue(pcSym)))
|
||||||
|
}
|
||||||
|
if writeInlPCData {
|
||||||
|
ftab.SetUint32(ctxt.Arch, int64(off+objabi.PCDATA_InlTreeIndex*4), uint32(ldr.SymValue(fi.Pcinline())))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
off += numPCData * 4
|
||||||
|
|
||||||
// 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).
|
||||||
|
|
@ -724,7 +771,7 @@ func (ctxt *Link) pclntab(container loader.Bitmap) *pclntab {
|
||||||
}
|
}
|
||||||
|
|
||||||
if off != end {
|
if off != end {
|
||||||
ctxt.Errorf(s, "bad math in functab: funcstart=%d off=%d but end=%d (npcdata=%d nfuncdata=%d ptrsize=%d)", funcstart, off, end, len(pcdata), len(funcdata), ctxt.Arch.PtrSize)
|
ctxt.Errorf(s, "bad math in functab: funcstart=%d off=%d but end=%d (npcdata=%d nfuncdata=%d ptrsize=%d)", funcstart, off, end, numPCData, len(funcdata), ctxt.Arch.PtrSize)
|
||||||
errorexit()
|
errorexit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -627,6 +627,10 @@ func (ctxt *Link) symtab(pcln *pclntab) []sym.SymKind {
|
||||||
moduledata.AddAddr(ctxt.Arch, pcln.filetab)
|
moduledata.AddAddr(ctxt.Arch, pcln.filetab)
|
||||||
moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.filetab)))
|
moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.filetab)))
|
||||||
moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.filetab)))
|
moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.filetab)))
|
||||||
|
// The pctab slice
|
||||||
|
moduledata.AddAddr(ctxt.Arch, pcln.pctab)
|
||||||
|
moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.pctab)))
|
||||||
|
moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.pctab)))
|
||||||
// The pclntab slice
|
// The pclntab slice
|
||||||
moduledata.AddAddr(ctxt.Arch, pcln.pclntab)
|
moduledata.AddAddr(ctxt.Arch, pcln.pclntab)
|
||||||
moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.pclntab)))
|
moduledata.AddUint(ctxt.Arch, uint64(ldr.SymSize(pcln.pclntab)))
|
||||||
|
|
|
||||||
|
|
@ -336,6 +336,15 @@ func (sb *SymbolBuilder) Addstring(str string) int64 {
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (sb *SymbolBuilder) SetBytesAt(off int64, b []byte) int64 {
|
||||||
|
datLen := int64(len(b))
|
||||||
|
if off+datLen > int64(len(sb.data)) {
|
||||||
|
panic("attempt to write past end of buffer")
|
||||||
|
}
|
||||||
|
copy(sb.data[off:off+datLen], b)
|
||||||
|
return off + datLen
|
||||||
|
}
|
||||||
|
|
||||||
func (sb *SymbolBuilder) addSymRef(tgt Sym, add int64, typ objabi.RelocType, rsize int) int64 {
|
func (sb *SymbolBuilder) addSymRef(tgt Sym, add int64, typ objabi.RelocType, rsize int) int64 {
|
||||||
if sb.kind == 0 {
|
if sb.kind == 0 {
|
||||||
sb.kind = sym.SDATA
|
sb.kind = sym.SDATA
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,3 @@ func VersionToABI(v int) (obj.ABI, bool) {
|
||||||
}
|
}
|
||||||
return ^obj.ABI(0), false
|
return ^obj.ABI(0), false
|
||||||
}
|
}
|
||||||
|
|
||||||
type Pcdata struct {
|
|
||||||
P []byte
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@ type LineTable struct {
|
||||||
functab []byte
|
functab []byte
|
||||||
nfunctab uint32
|
nfunctab uint32
|
||||||
filetab []byte
|
filetab []byte
|
||||||
|
pctab []byte // points to the pctables.
|
||||||
nfiletab uint32
|
nfiletab uint32
|
||||||
funcNames map[uint32]string // cache the function names
|
funcNames map[uint32]string // cache the function names
|
||||||
strings map[uint32]string // interned substrings of Data, keyed by offset
|
strings map[uint32]string // interned substrings of Data, keyed by offset
|
||||||
|
|
@ -235,6 +236,8 @@ func (t *LineTable) parsePclnTab() {
|
||||||
offset = t.uintptr(t.Data[8+4*t.ptrsize:])
|
offset = t.uintptr(t.Data[8+4*t.ptrsize:])
|
||||||
t.filetab = t.Data[offset:]
|
t.filetab = t.Data[offset:]
|
||||||
offset = t.uintptr(t.Data[8+5*t.ptrsize:])
|
offset = t.uintptr(t.Data[8+5*t.ptrsize:])
|
||||||
|
t.pctab = t.Data[offset:]
|
||||||
|
offset = t.uintptr(t.Data[8+6*t.ptrsize:])
|
||||||
t.funcdata = t.Data[offset:]
|
t.funcdata = t.Data[offset:]
|
||||||
t.functab = t.Data[offset:]
|
t.functab = t.Data[offset:]
|
||||||
functabsize := t.nfunctab*2*t.ptrsize + t.ptrsize
|
functabsize := t.nfunctab*2*t.ptrsize + t.ptrsize
|
||||||
|
|
@ -244,6 +247,7 @@ func (t *LineTable) parsePclnTab() {
|
||||||
t.funcdata = t.Data
|
t.funcdata = t.Data
|
||||||
t.funcnametab = t.Data
|
t.funcnametab = t.Data
|
||||||
t.functab = t.Data[8+t.ptrsize:]
|
t.functab = t.Data[8+t.ptrsize:]
|
||||||
|
t.pctab = t.Data
|
||||||
functabsize := t.nfunctab*2*t.ptrsize + t.ptrsize
|
functabsize := t.nfunctab*2*t.ptrsize + t.ptrsize
|
||||||
fileoff := t.binary.Uint32(t.functab[functabsize:])
|
fileoff := t.binary.Uint32(t.functab[functabsize:])
|
||||||
t.functab = t.functab[:functabsize]
|
t.functab = t.functab[:functabsize]
|
||||||
|
|
@ -373,7 +377,7 @@ func (t *LineTable) step(p *[]byte, pc *uint64, val *int32, first bool) bool {
|
||||||
// off is the offset to the beginning of the pc-value table,
|
// off is the offset to the beginning of the pc-value table,
|
||||||
// and entry is the start PC for the corresponding function.
|
// and entry is the start PC for the corresponding function.
|
||||||
func (t *LineTable) pcvalue(off uint32, entry, targetpc uint64) int32 {
|
func (t *LineTable) pcvalue(off uint32, entry, targetpc uint64) int32 {
|
||||||
p := t.funcdata[off:]
|
p := t.pctab[off:]
|
||||||
|
|
||||||
val := int32(-1)
|
val := int32(-1)
|
||||||
pc := entry
|
pc := entry
|
||||||
|
|
@ -396,8 +400,8 @@ func (t *LineTable) findFileLine(entry uint64, filetab, linetab uint32, filenum,
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
fp := t.funcdata[filetab:]
|
fp := t.pctab[filetab:]
|
||||||
fl := t.funcdata[linetab:]
|
fl := t.pctab[linetab:]
|
||||||
fileVal := int32(-1)
|
fileVal := int32(-1)
|
||||||
filePC := entry
|
filePC := entry
|
||||||
lineVal := int32(-1)
|
lineVal := int32(-1)
|
||||||
|
|
|
||||||
|
|
@ -800,10 +800,10 @@ type _func struct {
|
||||||
args int32 // in/out args size
|
args int32 // in/out args size
|
||||||
deferreturn uint32 // offset of start of a deferreturn call instruction from entry, if any.
|
deferreturn uint32 // offset of start of a deferreturn call instruction from entry, if any.
|
||||||
|
|
||||||
pcsp int32
|
pcsp uint32
|
||||||
pcfile int32
|
pcfile uint32
|
||||||
pcln int32
|
pcln uint32
|
||||||
npcdata int32
|
npcdata uint32
|
||||||
cuOffset uint32 // runtime.cutab offset of this function's CU
|
cuOffset uint32 // runtime.cutab offset of this function's CU
|
||||||
funcID funcID // set for certain special runtime functions
|
funcID funcID // set for certain special runtime functions
|
||||||
_ [2]byte // pad
|
_ [2]byte // pad
|
||||||
|
|
|
||||||
|
|
@ -345,6 +345,7 @@ type pcHeader struct {
|
||||||
funcnameOffset uintptr // offset to the funcnametab variable from pcHeader
|
funcnameOffset uintptr // offset to the funcnametab variable from pcHeader
|
||||||
cuOffset uintptr // offset to the cutab variable from pcHeader
|
cuOffset uintptr // offset to the cutab variable from pcHeader
|
||||||
filetabOffset uintptr // offset to the filetab variable from pcHeader
|
filetabOffset uintptr // offset to the filetab variable from pcHeader
|
||||||
|
pctabOffset uintptr // offset to the pctab varible from pcHeader
|
||||||
pclnOffset uintptr // offset to the pclntab variable from pcHeader
|
pclnOffset uintptr // offset to the pclntab variable from pcHeader
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -358,6 +359,7 @@ type moduledata struct {
|
||||||
funcnametab []byte
|
funcnametab []byte
|
||||||
cutab []uint32
|
cutab []uint32
|
||||||
filetab []byte
|
filetab []byte
|
||||||
|
pctab []byte
|
||||||
pclntable []byte
|
pclntable []byte
|
||||||
ftab []functab
|
ftab []functab
|
||||||
findfunctab uintptr
|
findfunctab uintptr
|
||||||
|
|
@ -721,7 +723,7 @@ type pcvalueCache struct {
|
||||||
type pcvalueCacheEnt struct {
|
type pcvalueCacheEnt struct {
|
||||||
// targetpc and off together are the key of this cache entry.
|
// targetpc and off together are the key of this cache entry.
|
||||||
targetpc uintptr
|
targetpc uintptr
|
||||||
off int32
|
off uint32
|
||||||
// val is the value of this cached pcvalue entry.
|
// val is the value of this cached pcvalue entry.
|
||||||
val int32
|
val int32
|
||||||
}
|
}
|
||||||
|
|
@ -736,7 +738,7 @@ func pcvalueCacheKey(targetpc uintptr) uintptr {
|
||||||
|
|
||||||
// Returns the PCData value, and the PC where this value starts.
|
// Returns the PCData value, and the PC where this value starts.
|
||||||
// TODO: the start PC is returned only when cache is nil.
|
// TODO: the start PC is returned only when cache is nil.
|
||||||
func pcvalue(f funcInfo, off int32, targetpc uintptr, cache *pcvalueCache, strict bool) (int32, uintptr) {
|
func pcvalue(f funcInfo, off uint32, targetpc uintptr, cache *pcvalueCache, strict bool) (int32, uintptr) {
|
||||||
if off == 0 {
|
if off == 0 {
|
||||||
return -1, 0
|
return -1, 0
|
||||||
}
|
}
|
||||||
|
|
@ -770,7 +772,7 @@ func pcvalue(f funcInfo, off int32, targetpc uintptr, cache *pcvalueCache, stric
|
||||||
return -1, 0
|
return -1, 0
|
||||||
}
|
}
|
||||||
datap := f.datap
|
datap := f.datap
|
||||||
p := datap.pclntable[off:]
|
p := datap.pctab[off:]
|
||||||
pc := f.entry
|
pc := f.entry
|
||||||
prevpc := pc
|
prevpc := pc
|
||||||
val := int32(-1)
|
val := int32(-1)
|
||||||
|
|
@ -812,7 +814,7 @@ func pcvalue(f funcInfo, off int32, targetpc uintptr, cache *pcvalueCache, stric
|
||||||
|
|
||||||
print("runtime: invalid pc-encoded table f=", funcname(f), " pc=", hex(pc), " targetpc=", hex(targetpc), " tab=", p, "\n")
|
print("runtime: invalid pc-encoded table f=", funcname(f), " pc=", hex(pc), " targetpc=", hex(targetpc), " tab=", p, "\n")
|
||||||
|
|
||||||
p = datap.pclntable[off:]
|
p = datap.pctab[off:]
|
||||||
pc = f.entry
|
pc = f.entry
|
||||||
val = -1
|
val = -1
|
||||||
for {
|
for {
|
||||||
|
|
@ -893,7 +895,7 @@ func funcspdelta(f funcInfo, targetpc uintptr, cache *pcvalueCache) int32 {
|
||||||
// funcMaxSPDelta returns the maximum spdelta at any point in f.
|
// funcMaxSPDelta returns the maximum spdelta at any point in f.
|
||||||
func funcMaxSPDelta(f funcInfo) int32 {
|
func funcMaxSPDelta(f funcInfo) int32 {
|
||||||
datap := f.datap
|
datap := f.datap
|
||||||
p := datap.pclntable[f.pcsp:]
|
p := datap.pctab[f.pcsp:]
|
||||||
pc := f.entry
|
pc := f.entry
|
||||||
val := int32(-1)
|
val := int32(-1)
|
||||||
max := int32(0)
|
max := int32(0)
|
||||||
|
|
@ -909,20 +911,20 @@ func funcMaxSPDelta(f funcInfo) int32 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func pcdatastart(f funcInfo, table int32) int32 {
|
func pcdatastart(f funcInfo, table uint32) uint32 {
|
||||||
return *(*int32)(add(unsafe.Pointer(&f.nfuncdata), unsafe.Sizeof(f.nfuncdata)+uintptr(table)*4))
|
return *(*uint32)(add(unsafe.Pointer(&f.nfuncdata), unsafe.Sizeof(f.nfuncdata)+uintptr(table)*4))
|
||||||
}
|
}
|
||||||
|
|
||||||
func pcdatavalue(f funcInfo, table int32, targetpc uintptr, cache *pcvalueCache) int32 {
|
func pcdatavalue(f funcInfo, table uint32, targetpc uintptr, cache *pcvalueCache) int32 {
|
||||||
if table < 0 || table >= f.npcdata {
|
if table >= f.npcdata {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
r, _ := pcvalue(f, pcdatastart(f, table), targetpc, cache, true)
|
r, _ := pcvalue(f, pcdatastart(f, table), targetpc, cache, true)
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func pcdatavalue1(f funcInfo, table int32, targetpc uintptr, cache *pcvalueCache, strict bool) int32 {
|
func pcdatavalue1(f funcInfo, table uint32, targetpc uintptr, cache *pcvalueCache, strict bool) int32 {
|
||||||
if table < 0 || table >= f.npcdata {
|
if table >= f.npcdata {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
r, _ := pcvalue(f, pcdatastart(f, table), targetpc, cache, strict)
|
r, _ := pcvalue(f, pcdatastart(f, table), targetpc, cache, strict)
|
||||||
|
|
@ -931,8 +933,8 @@ func pcdatavalue1(f funcInfo, table int32, targetpc uintptr, cache *pcvalueCache
|
||||||
|
|
||||||
// Like pcdatavalue, but also return the start PC of this PCData value.
|
// Like pcdatavalue, but also return the start PC of this PCData value.
|
||||||
// It doesn't take a cache.
|
// It doesn't take a cache.
|
||||||
func pcdatavalue2(f funcInfo, table int32, targetpc uintptr) (int32, uintptr) {
|
func pcdatavalue2(f funcInfo, table uint32, targetpc uintptr) (int32, uintptr) {
|
||||||
if table < 0 || table >= f.npcdata {
|
if table >= f.npcdata {
|
||||||
return -1, 0
|
return -1, 0
|
||||||
}
|
}
|
||||||
return pcvalue(f, pcdatastart(f, table), targetpc, nil, true)
|
return pcvalue(f, pcdatastart(f, table), targetpc, nil, true)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue