const funcSize … type pclntab … // addGeneratedSym adds a generator symbol to pclntab, returning the new Sym. // It is the caller's responsibility to save the symbol in state. func (state *pclntab) addGeneratedSym(ctxt *Link, name string, size int64, f generatorFunc) loader.Sym { … } // makePclntab makes a pclntab object, and assembles all the compilation units // we'll need to write pclntab. Returns the pclntab structure, a slice of the // CompilationUnits we need, and a slice of the function symbols we need to // generate pclntab. func makePclntab(ctxt *Link, container loader.Bitmap) (*pclntab, []*sym.CompilationUnit, []loader.Sym) { … } func emitPcln(ctxt *Link, s loader.Sym, container loader.Bitmap) bool { … } func computeDeferReturn(ctxt *Link, deferReturnSym, s loader.Sym) uint32 { … } // genInlTreeSym generates the InlTree sym for a function with the // specified FuncInfo. func genInlTreeSym(ctxt *Link, cu *sym.CompilationUnit, fi loader.FuncInfo, arch *sys.Arch, nameOffsets map[loader.Sym]uint32) loader.Sym { … } // makeInlSyms returns a map of loader.Sym that are created inlSyms. func makeInlSyms(ctxt *Link, funcs []loader.Sym, nameOffsets map[loader.Sym]uint32) map[loader.Sym]loader.Sym { … } // generatePCHeader creates the runtime.pcheader symbol, setting it up as a // generator to fill in its data later. func (state *pclntab) generatePCHeader(ctxt *Link) { … } // walkFuncs iterates over the funcs, calling a function for each unique // function and inlined function. func walkFuncs(ctxt *Link, funcs []loader.Sym, f func(loader.Sym)) { … } // generateFuncnametab creates the function name table. Returns a map of // func symbol to the name offset in runtime.funcnamtab. func (state *pclntab) generateFuncnametab(ctxt *Link, funcs []loader.Sym) map[loader.Sym]uint32 { … } // walkFilenames walks funcs, calling a function for each filename used in each // function's line table. func walkFilenames(ctxt *Link, funcs []loader.Sym, f func(*sym.CompilationUnit, goobj.CUFileIndex)) { … } // generateFilenameTabs creates LUTs needed for filename lookup. Returns a slice // of the index at which each CU begins in runtime.cutab. // // Function objects keep track of the files they reference to print the stack. // This function creates a per-CU list of filenames if CU[M] references // files[1-N], the following is generated: // // runtime.cutab: // CU[M] // offsetToFilename[0] // offsetToFilename[1] // .. // // runtime.filetab // filename[0] // filename[1] // // Looking up a filename then becomes: // 0. Given a func, and filename index [K] // 1. Get Func.CUIndex: M := func.cuOffset // 2. Find filename offset: fileOffset := runtime.cutab[M+K] // 3. Get the filename: getcstring(runtime.filetab[fileOffset]) func (state *pclntab) generateFilenameTabs(ctxt *Link, compUnits []*sym.CompilationUnit, funcs []loader.Sym) []uint32 { … } // generatePctab creates the runtime.pctab variable, holding all the // deduplicated pcdata. func (state *pclntab) generatePctab(ctxt *Link, funcs []loader.Sym) { … } // numPCData returns the number of PCData syms for the FuncInfo. // NB: Preload must be called on valid FuncInfos before calling this function. func numPCData(ldr *loader.Loader, s loader.Sym, fi loader.FuncInfo) uint32 { … } // generateFunctab creates the runtime.functab // // runtime.functab contains two things: // // - pc->func look up table. // - array of func objects, interleaved with pcdata and funcdata func (state *pclntab) generateFunctab(ctxt *Link, funcs []loader.Sym, inlSyms map[loader.Sym]loader.Sym, cuOffsets []uint32, nameOffsets map[loader.Sym]uint32) { … } // funcData returns the funcdata and offsets for the FuncInfo. // The funcdata are written into runtime.functab after each func // object. This is a helper function to make querying the FuncInfo object // cleaner. // // NB: Preload must be called on the FuncInfo before calling. // 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 { … } // calculateFunctabSize calculates the size of the pclntab, and the offsets in // the output buffer for individual func entries. func (state pclntab) calculateFunctabSize(ctxt *Link, funcs []loader.Sym) (int64, []uint32) { … } // writePCToFunc writes the PC->func lookup table. func writePCToFunc(ctxt *Link, sb *loader.SymbolBuilder, funcs []loader.Sym, startLocations []uint32) { … } // writeFuncs writes the func structures and pcdata to runtime.functab. func writeFuncs(ctxt *Link, sb *loader.SymbolBuilder, funcs []loader.Sym, inlSyms map[loader.Sym]loader.Sym, startLocations, cuOffsets []uint32, nameOffsets map[loader.Sym]uint32) { … } // pclntab generates the pcln table for the link output. func (ctxt *Link) pclntab(container loader.Bitmap) *pclntab { … } func expandGoroot(s string) string { … } const SUBBUCKETS … const SUBBUCKETSIZE … const NOIDX … // findfunctab generates a lookup table to quickly find the containing // function for a pc. See src/runtime/symtab.go:findfunc for details. func (ctxt *Link) findfunctab(state *pclntab, container loader.Bitmap) { … } // findContainerSyms returns a bitmap, indexed by symbol number, where there's // a 1 for every container symbol. func (ctxt *Link) findContainerSyms() loader.Bitmap { … }