mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 08:02:27 -05:00 
			
		
		
		
	[chore] Update gin to v1.9.0 (#1553)
This commit is contained in:
		
					parent
					
						
							
								689a10fe17
							
						
					
				
			
			
				commit
				
					
						ecdc8379fa
					
				
			
		
					 347 changed files with 166814 additions and 3671 deletions
				
			
		
							
								
								
									
										545
									
								
								vendor/github.com/bytedance/sonic/loader/funcdata_go120.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										545
									
								
								vendor/github.com/bytedance/sonic/loader/funcdata_go120.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,545 @@ | |||
| //go:build go1.20 && !go1.21 | ||||
| // +build go1.20,!go1.21 | ||||
| 
 | ||||
| /* | ||||
|  * Copyright 2021 ByteDance Inc. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| package loader | ||||
| 
 | ||||
| import ( | ||||
|     `encoding` | ||||
|     `os` | ||||
|     `unsafe` | ||||
| 
 | ||||
|     `github.com/bytedance/sonic/internal/rt` | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
|     _Magic uint32 = 0xFFFFFFF1 | ||||
| ) | ||||
| 
 | ||||
| type moduledata struct { | ||||
|     pcHeader     *pcHeader | ||||
|     funcnametab  []byte | ||||
|     cutab        []uint32 | ||||
|     filetab      []byte | ||||
|     pctab        []byte | ||||
|     pclntable    []byte | ||||
|     ftab         []funcTab | ||||
|     findfunctab  uintptr | ||||
|     minpc, maxpc uintptr // first func address, last func address + last func size | ||||
| 
 | ||||
|     text, etext           uintptr // start/end of text, (etext-text) must be greater than MIN_FUNC | ||||
|     noptrdata, enoptrdata uintptr | ||||
|     data, edata           uintptr | ||||
|     bss, ebss             uintptr | ||||
|     noptrbss, enoptrbss   uintptr | ||||
|     covctrs, ecovctrs     uintptr | ||||
|     end, gcdata, gcbss    uintptr | ||||
|     types, etypes         uintptr | ||||
|     rodata                uintptr | ||||
| 
 | ||||
|     // TODO: generate funcinfo object to memory | ||||
|     gofunc                uintptr // go.func.* is actual funcinfo object in image | ||||
| 
 | ||||
|     textsectmap []textSection // see runtime/symtab.go: textAddr() | ||||
|     typelinks   []int32 // offsets from types | ||||
|     itablinks   []*rt.GoItab | ||||
| 
 | ||||
|     ptab []ptabEntry | ||||
| 
 | ||||
|     pluginpath string | ||||
|     pkghashes  []modulehash | ||||
| 
 | ||||
|     modulename   string | ||||
|     modulehashes []modulehash | ||||
| 
 | ||||
|     hasmain uint8 // 1 if module contains the main function, 0 otherwise | ||||
| 
 | ||||
|     gcdatamask, gcbssmask bitVector | ||||
| 
 | ||||
|     typemap map[int32]*rt.GoType // offset to *_rtype in previous module | ||||
| 
 | ||||
|     bad bool // module failed to load and should be ignored | ||||
| 
 | ||||
|     next *moduledata | ||||
| } | ||||
| 
 | ||||
| type _func struct { | ||||
|     entryOff uint32 // start pc, as offset from moduledata.text/pcHeader.textStart | ||||
|     nameOff  int32  // function name, as index into moduledata.funcnametab. | ||||
| 
 | ||||
|     args        int32  // in/out args size | ||||
|     deferreturn uint32 // offset of start of a deferreturn call instruction from entry, if any. | ||||
| 
 | ||||
|     pcsp      uint32  | ||||
|     pcfile    uint32 | ||||
|     pcln      uint32 | ||||
|     npcdata   uint32 | ||||
|     cuOffset  uint32 // runtime.cutab offset of this function's CU | ||||
|     startLine int32  // line number of start of function (func keyword/TEXT directive) | ||||
|     funcID    uint8 // set for certain special runtime functions | ||||
|     flag      uint8 | ||||
|     _         [1]byte // pad | ||||
|     nfuncdata uint8   //  | ||||
|      | ||||
|     // The end of the struct is followed immediately by two variable-length | ||||
|     // arrays that reference the pcdata and funcdata locations for this | ||||
|     // function. | ||||
| 
 | ||||
|     // pcdata contains the offset into moduledata.pctab for the start of | ||||
|     // that index's table. e.g., | ||||
|     // &moduledata.pctab[_func.pcdata[_PCDATA_UnsafePoint]] is the start of | ||||
|     // the unsafe point table. | ||||
|     // | ||||
|     // An offset of 0 indicates that there is no table. | ||||
|     // | ||||
|     // pcdata [npcdata]uint32 | ||||
| 
 | ||||
|     // funcdata contains the offset past moduledata.gofunc which contains a | ||||
|     // pointer to that index's funcdata. e.g., | ||||
|     // *(moduledata.gofunc +  _func.funcdata[_FUNCDATA_ArgsPointerMaps]) is | ||||
|     // the argument pointer map. | ||||
|     // | ||||
|     // An offset of ^uint32(0) indicates that there is no entry. | ||||
|     // | ||||
|     // funcdata [nfuncdata]uint32 | ||||
| } | ||||
| 
 | ||||
| type funcTab struct { | ||||
|     entry   uint32 | ||||
|     funcoff uint32 | ||||
| } | ||||
| 
 | ||||
| type pcHeader struct { | ||||
|     magic          uint32  // 0xFFFFFFF0 | ||||
|     pad1, pad2     uint8   // 0,0 | ||||
|     minLC          uint8   // min instruction size | ||||
|     ptrSize        uint8   // size of a ptr in bytes | ||||
|     nfunc          int     // number of functions in the module | ||||
|     nfiles         uint    // number of entries in the file tab | ||||
|     textStart      uintptr // base for function entry PC offsets in this module, equal to moduledata.text | ||||
|     funcnameOffset uintptr // offset to the funcnametab variable from pcHeader | ||||
|     cuOffset       uintptr // offset to the cutab variable from pcHeader | ||||
|     filetabOffset  uintptr // offset to the filetab variable from pcHeader | ||||
|     pctabOffset    uintptr // offset to the pctab variable from pcHeader | ||||
|     pclnOffset     uintptr // offset to the pclntab variable from pcHeader | ||||
| } | ||||
| 
 | ||||
| type bitVector struct { | ||||
|     n        int32 // # of bits | ||||
|     bytedata *uint8 | ||||
| } | ||||
| 
 | ||||
| type ptabEntry struct { | ||||
|     name int32 | ||||
|     typ  int32 | ||||
| } | ||||
| 
 | ||||
| type textSection struct { | ||||
|     vaddr    uintptr // prelinked section vaddr | ||||
|     end      uintptr // vaddr + section length | ||||
|     baseaddr uintptr // relocated section address | ||||
| } | ||||
| 
 | ||||
| type modulehash struct { | ||||
|     modulename   string | ||||
|     linktimehash string | ||||
|     runtimehash  *string | ||||
| } | ||||
| 
 | ||||
| // findfuncbucket is an array of these structures. | ||||
| // Each bucket represents 4096 bytes of the text segment. | ||||
| // Each subbucket represents 256 bytes of the text segment. | ||||
| // To find a function given a pc, locate the bucket and subbucket for | ||||
| // that pc. Add together the idx and subbucket value to obtain a | ||||
| // function index. Then scan the functab array starting at that | ||||
| // index to find the target function. | ||||
| // This table uses 20 bytes for every 4096 bytes of code, or ~0.5% overhead. | ||||
| type findfuncbucket struct { | ||||
|     idx        uint32 | ||||
|     _SUBBUCKETS [16]byte | ||||
| } | ||||
| 
 | ||||
| // func name table format:  | ||||
| //   nameOff[0] -> namePartA namePartB namePartC \x00  | ||||
| //   nameOff[1] -> namePartA namePartB namePartC \x00 | ||||
| //  ... | ||||
| func makeFuncnameTab(funcs []Func) (tab []byte, offs []int32) { | ||||
|     offs = make([]int32, len(funcs)) | ||||
|     offset := 0 | ||||
| 
 | ||||
|     for i, f := range funcs { | ||||
|         offs[i] = int32(offset) | ||||
| 
 | ||||
|         a, b, c := funcNameParts(f.Name) | ||||
|         tab = append(tab, a...) | ||||
|         tab = append(tab, b...) | ||||
|         tab = append(tab, c...) | ||||
|         tab = append(tab, 0) | ||||
|         offset += len(a) + len(b) + len(c) + 1 | ||||
|     } | ||||
| 
 | ||||
|     return | ||||
| } | ||||
| 
 | ||||
| type compilationUnit struct { | ||||
|     fileNames []string | ||||
| } | ||||
| 
 | ||||
| // CU table format: | ||||
| //  cuOffsets[0] -> filetabOffset[0] filetabOffset[1] ... filetabOffset[len(CUs[0].fileNames)-1] | ||||
| //  cuOffsets[1] -> filetabOffset[len(CUs[0].fileNames)] ... filetabOffset[len(CUs[0].fileNames) + len(CUs[1].fileNames)-1] | ||||
| //  ... | ||||
| // | ||||
| // file name table format: | ||||
| //  filetabOffset[0] -> CUs[0].fileNames[0] \x00 | ||||
| //  ... | ||||
| //  filetabOffset[len(CUs[0]-1)] -> CUs[0].fileNames[len(CUs[0].fileNames)-1] \x00 | ||||
| //  ... | ||||
| //  filetabOffset[SUM(CUs,fileNames)-1] -> CUs[len(CU)-1].fileNames[len(CUs[len(CU)-1].fileNames)-1] \x00 | ||||
| func makeFilenametab(cus []compilationUnit) (cutab []uint32, filetab []byte, cuOffsets []uint32) { | ||||
|     cuOffsets = make([]uint32, len(cus)) | ||||
|     cuOffset := 0 | ||||
|     fileOffset := 0 | ||||
| 
 | ||||
|     for i, cu := range cus { | ||||
|         cuOffsets[i] = uint32(cuOffset) | ||||
| 
 | ||||
|         for _, name := range cu.fileNames { | ||||
|             cutab = append(cutab, uint32(fileOffset)) | ||||
| 
 | ||||
|             fileOffset += len(name) + 1 | ||||
|             filetab = append(filetab, name...) | ||||
|             filetab = append(filetab, 0) | ||||
|         } | ||||
| 
 | ||||
|         cuOffset += len(cu.fileNames) | ||||
|     } | ||||
| 
 | ||||
|     return | ||||
| } | ||||
| 
 | ||||
| func writeFuncdata(out *[]byte, funcs []Func) (fstart int, funcdataOffs [][]uint32) { | ||||
|     fstart = len(*out) | ||||
|     *out = append(*out, byte(0)) | ||||
|     offs := uint32(1) | ||||
| 
 | ||||
|     funcdataOffs = make([][]uint32, len(funcs)) | ||||
|     for i, f := range funcs { | ||||
| 
 | ||||
|         var writer = func(fd encoding.BinaryMarshaler) { | ||||
|             var ab []byte | ||||
|             var err error | ||||
|             if fd != nil { | ||||
|                 ab, err = fd.MarshalBinary() | ||||
|                 if err != nil { | ||||
|                     panic(err) | ||||
|                 } | ||||
|                 funcdataOffs[i] = append(funcdataOffs[i], offs) | ||||
|             } else { | ||||
|                 ab = []byte{0} | ||||
|                 funcdataOffs[i] = append(funcdataOffs[i], _INVALID_FUNCDATA_OFFSET) | ||||
|             } | ||||
|             *out = append(*out, ab...) | ||||
|             offs += uint32(len(ab)) | ||||
|         } | ||||
| 
 | ||||
|         writer(f.ArgsPointerMaps) | ||||
|         writer(f.LocalsPointerMaps) | ||||
|         writer(f.StackObjects) | ||||
|         writer(f.InlTree) | ||||
|         writer(f.OpenCodedDeferInfo) | ||||
|         writer(f.ArgInfo) | ||||
|         writer(f.ArgLiveInfo) | ||||
|         writer(f.WrapInfo) | ||||
|     } | ||||
|     return  | ||||
| } | ||||
| 
 | ||||
| func makeFtab(funcs []_func, lastFuncSize uint32) (ftab []funcTab) { | ||||
|     // Allocate space for the pc->func table. This structure consists of a pc offset | ||||
|     // and an offset to the func structure. After that, we have a single pc | ||||
|     // value that marks the end of the last function in the binary. | ||||
|     var size int64 = int64(len(funcs)*2*4 + 4) | ||||
|     var startLocations = make([]uint32, len(funcs)) | ||||
|     for i, f := range funcs { | ||||
|         size = rnd(size, int64(_PtrSize)) | ||||
|         //writePCToFunc | ||||
|         startLocations[i] = uint32(size) | ||||
|         size += int64(uint8(_FUNC_SIZE)+f.nfuncdata*4+uint8(f.npcdata)*4) | ||||
|     } | ||||
| 
 | ||||
|     ftab = make([]funcTab, 0, len(funcs)+1) | ||||
| 
 | ||||
|     // write a map of pc->func info offsets  | ||||
|     for i, f := range funcs { | ||||
|         ftab = append(ftab, funcTab{uint32(f.entryOff), uint32(startLocations[i])}) | ||||
|     } | ||||
| 
 | ||||
|     // Final entry of table is just end pc offset. | ||||
|     lastFunc := funcs[len(funcs)-1] | ||||
|     ftab = append(ftab, funcTab{uint32(lastFunc.entryOff + lastFuncSize), 0}) | ||||
| 
 | ||||
|     return | ||||
| } | ||||
| 
 | ||||
| // Pcln table format: [...]funcTab + [...]_Func | ||||
| func makePclntable(funcs []_func, lastFuncSize uint32, pcdataOffs [][]uint32, funcdataOffs [][]uint32) (pclntab []byte) { | ||||
|     // Allocate space for the pc->func table. This structure consists of a pc offset | ||||
|     // and an offset to the func structure. After that, we have a single pc | ||||
|     // value that marks the end of the last function in the binary. | ||||
|     var size int64 = int64(len(funcs)*2*4 + 4) | ||||
|     var startLocations = make([]uint32, len(funcs)) | ||||
|     for i := range funcs { | ||||
|         size = rnd(size, int64(_PtrSize)) | ||||
|         //writePCToFunc | ||||
|         startLocations[i] = uint32(size) | ||||
|         size += int64(int(_FUNC_SIZE)+len(funcdataOffs[i])*4+len(pcdataOffs[i])*4) | ||||
|     } | ||||
| 
 | ||||
|     pclntab = make([]byte, size, size) | ||||
| 
 | ||||
|     // write a map of pc->func info offsets  | ||||
|     offs := 0 | ||||
|     for i, f := range funcs { | ||||
|         byteOrder.PutUint32(pclntab[offs:offs+4], uint32(f.entryOff)) | ||||
|         byteOrder.PutUint32(pclntab[offs+4:offs+8], uint32(startLocations[i])) | ||||
|         offs += 8 | ||||
|     } | ||||
|     // Final entry of table is just end pc offset. | ||||
|     lastFunc := funcs[len(funcs)-1] | ||||
|     byteOrder.PutUint32(pclntab[offs:offs+4], uint32(lastFunc.entryOff+lastFuncSize)) | ||||
| 
 | ||||
|     // write func info table | ||||
|     for i, f := range funcs { | ||||
|         off := startLocations[i] | ||||
| 
 | ||||
|         // write _func structure to pclntab | ||||
|         fb := rt.BytesFrom(unsafe.Pointer(&f), int(_FUNC_SIZE), int(_FUNC_SIZE)) | ||||
|         copy(pclntab[off:off+uint32(_FUNC_SIZE)], fb) | ||||
|         off += uint32(_FUNC_SIZE) | ||||
| 
 | ||||
|         // NOTICE: _func.pcdata always starts from PcUnsafePoint, which is index 3 | ||||
|         for j := 3; j < len(pcdataOffs[i]); j++ { | ||||
|             byteOrder.PutUint32(pclntab[off:off+4], uint32(pcdataOffs[i][j])) | ||||
|             off += 4 | ||||
|         } | ||||
| 
 | ||||
|         // funcdata refs as offsets from gofunc | ||||
|         for _, funcdata := range funcdataOffs[i] { | ||||
|             byteOrder.PutUint32(pclntab[off:off+4], uint32(funcdata)) | ||||
|             off += 4 | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     return | ||||
| } | ||||
| 
 | ||||
| // findfunc table used to map pc to belonging func,  | ||||
| // returns the index in the func table. | ||||
| // | ||||
| // All text section are divided into buckets sized _BUCKETSIZE(4K): | ||||
| //   every bucket is divided into _SUBBUCKETS sized _SUB_BUCKETSIZE(64), | ||||
| //   and it has a base idx to plus the offset stored in jth subbucket. | ||||
| // see findfunc() in runtime/symtab.go | ||||
| func writeFindfunctab(out *[]byte, ftab []funcTab) (start int) { | ||||
|     start = len(*out) | ||||
| 
 | ||||
|     max := ftab[len(ftab)-1].entry | ||||
|     min := ftab[0].entry | ||||
|     nbuckets := (max - min + _BUCKETSIZE - 1) / _BUCKETSIZE | ||||
|     n := (max - min + _SUB_BUCKETSIZE - 1) / _SUB_BUCKETSIZE | ||||
| 
 | ||||
|     tab := make([]findfuncbucket, 0, nbuckets) | ||||
|     var s, e = 0, 0 | ||||
|     for i := 0; i<int(nbuckets); i++ { | ||||
|         var pc = min + uint32((i+1)*_BUCKETSIZE) | ||||
|         // find the end func of the bucket | ||||
|         for ; e < len(ftab)-1 && ftab[e+1].entry <= pc; e++ {} | ||||
|         // store the start func of the bucket | ||||
|         var fb = findfuncbucket{idx: uint32(s)} | ||||
| 
 | ||||
|         for j := 0; j<_SUBBUCKETS && (i*_SUBBUCKETS+j)<int(n); j++ { | ||||
|             pc = min + uint32(i*_BUCKETSIZE) + uint32((j+1)*_SUB_BUCKETSIZE) | ||||
|             var ss = s | ||||
|             // find the end func of the subbucket | ||||
|             for ; ss < len(ftab)-1 && ftab[ss+1].entry <= pc; ss++ {} | ||||
|             // store the start func of the subbucket | ||||
|             fb._SUBBUCKETS[j] = byte(uint32(s) - fb.idx) | ||||
|             s = ss | ||||
|         } | ||||
|         s = e | ||||
|         tab = append(tab, fb) | ||||
|     } | ||||
| 
 | ||||
|     // write findfuncbucket | ||||
|     if len(tab) > 0 { | ||||
|         size := int(unsafe.Sizeof(findfuncbucket{}))*len(tab) | ||||
|         *out = append(*out, rt.BytesFrom(unsafe.Pointer(&tab[0]), size, size)...) | ||||
|     } | ||||
|     return  | ||||
| } | ||||
| 
 | ||||
| func makeModuledata(name string, filenames []string, funcs []Func, text []byte) (mod *moduledata) { | ||||
|     mod = new(moduledata) | ||||
|     mod.modulename = name | ||||
| 
 | ||||
|     // make filename table | ||||
|     cu := make([]string, 0, len(filenames)) | ||||
|     for _, f := range filenames { | ||||
|         cu = append(cu, f) | ||||
|     } | ||||
|     cutab, filetab, cuOffs := makeFilenametab([]compilationUnit{{cu}}) | ||||
|     mod.cutab = cutab | ||||
|     mod.filetab = filetab | ||||
| 
 | ||||
|     // make funcname table | ||||
|     funcnametab, nameOffs := makeFuncnameTab(funcs) | ||||
|     mod.funcnametab = funcnametab | ||||
| 
 | ||||
|     // make pcdata table | ||||
|     // NOTICE: _func only use offset to index pcdata, thus no need mmap() pcdata  | ||||
|     pctab, pcdataOffs, _funcs := makePctab(funcs, cuOffs, nameOffs) | ||||
|     mod.pctab = pctab | ||||
| 
 | ||||
|     // write func data | ||||
|     // NOTICE: _func use mod.gofunc+offset to directly point funcdata, thus need cache funcdata | ||||
|     // TODO: estimate accurate capacity | ||||
|     cache := make([]byte, 0, len(funcs)*int(_PtrSize))  | ||||
|     fstart, funcdataOffs := writeFuncdata(&cache, funcs) | ||||
| 
 | ||||
|     // make pc->func (binary search) func table | ||||
|     lastFuncsize := funcs[len(funcs)-1].TextSize | ||||
|     ftab := makeFtab(_funcs, lastFuncsize) | ||||
|     mod.ftab = ftab | ||||
| 
 | ||||
|     // write pc->func (modmap) findfunc table | ||||
|     ffstart := writeFindfunctab(&cache, ftab) | ||||
| 
 | ||||
|     // make pclnt table | ||||
|     pclntab := makePclntable(_funcs, lastFuncsize, pcdataOffs, funcdataOffs) | ||||
|     mod.pclntable = pclntab | ||||
| 
 | ||||
|     // mmap() text and funcdata segements | ||||
|     p := os.Getpagesize() | ||||
|     size := int(rnd(int64(len(text)), int64(p))) | ||||
|     addr := mmap(size) | ||||
|     // copy the machine code | ||||
|     s := rt.BytesFrom(unsafe.Pointer(addr), len(text), size) | ||||
|     copy(s, text) | ||||
|     // make it executable | ||||
|     mprotect(addr, size) | ||||
| 
 | ||||
|     // assign addresses | ||||
|     mod.text = addr | ||||
|     mod.etext = addr + uintptr(size) | ||||
|     mod.minpc = addr | ||||
|     mod.maxpc = addr + uintptr(len(text)) | ||||
| 
 | ||||
|     // cache funcdata and findfuncbucket | ||||
|     moduleCache.Lock() | ||||
|     moduleCache.m[mod] = cache | ||||
|     moduleCache.Unlock() | ||||
|     mod.gofunc = uintptr(unsafe.Pointer(&cache[fstart])) | ||||
|     mod.findfunctab = uintptr(unsafe.Pointer(&cache[ffstart])) | ||||
| 
 | ||||
|     // make pc header | ||||
|     mod.pcHeader = &pcHeader { | ||||
|         magic   : _Magic, | ||||
|         minLC   : _MinLC, | ||||
|         ptrSize : _PtrSize, | ||||
|         nfunc   : len(funcs), | ||||
|         nfiles: uint(len(cu)), | ||||
|         textStart: mod.text, | ||||
|         funcnameOffset: getOffsetOf(moduledata{}, "funcnametab"), | ||||
|         cuOffset: getOffsetOf(moduledata{}, "cutab"), | ||||
|         filetabOffset: getOffsetOf(moduledata{}, "filetab"), | ||||
|         pctabOffset: getOffsetOf(moduledata{}, "pctab"), | ||||
|         pclnOffset: getOffsetOf(moduledata{}, "pclntable"), | ||||
|     } | ||||
| 
 | ||||
|     // sepecial case: gcdata and gcbss must by non-empty | ||||
|     mod.gcdata = uintptr(unsafe.Pointer(&emptyByte)) | ||||
|     mod.gcbss = uintptr(unsafe.Pointer(&emptyByte)) | ||||
| 
 | ||||
|     return | ||||
| } | ||||
| 
 | ||||
| // makePctab generates pcdelta->valuedelta tables for functions, | ||||
| // and returns the table and the entry offset of every kind pcdata in the table. | ||||
| func makePctab(funcs []Func, cuOffset []uint32, nameOffset []int32) (pctab []byte, pcdataOffs [][]uint32, _funcs []_func) { | ||||
|     _funcs = make([]_func, len(funcs)) | ||||
| 
 | ||||
|     // 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. | ||||
|     pctab = make([]byte, 1, 12*len(funcs)+1) | ||||
|     pcdataOffs = make([][]uint32, len(funcs)) | ||||
| 
 | ||||
|     for i, f := range funcs { | ||||
|         _f := &_funcs[i] | ||||
| 
 | ||||
|         var writer = func(pc *Pcdata) { | ||||
|             var ab []byte | ||||
|             var err error | ||||
|             if pc != nil { | ||||
|                 ab, err = pc.MarshalBinary() | ||||
|                 if err != nil { | ||||
|                     panic(err) | ||||
|                 } | ||||
|                 pcdataOffs[i] = append(pcdataOffs[i], uint32(len(pctab))) | ||||
|             } else { | ||||
|                 ab = []byte{0} | ||||
|                 pcdataOffs[i] = append(pcdataOffs[i], _PCDATA_INVALID_OFFSET) | ||||
|             } | ||||
|             pctab = append(pctab, ab...) | ||||
|         } | ||||
| 
 | ||||
|         if f.Pcsp != nil { | ||||
|             _f.pcsp = uint32(len(pctab)) | ||||
|         } | ||||
|         writer(f.Pcsp) | ||||
|         if f.Pcfile != nil { | ||||
|             _f.pcfile = uint32(len(pctab)) | ||||
|         } | ||||
|         writer(f.Pcfile) | ||||
|         if f.Pcline != nil { | ||||
|             _f.pcln = uint32(len(pctab)) | ||||
|         } | ||||
|         writer(f.Pcline) | ||||
|         writer(f.PcUnsafePoint) | ||||
|         writer(f.PcStackMapIndex) | ||||
|         writer(f.PcInlTreeIndex) | ||||
|         writer(f.PcArgLiveIndex) | ||||
|          | ||||
|         _f.entryOff = f.EntryOff | ||||
|         _f.nameOff = nameOffset[i] | ||||
|         _f.args = f.ArgsSize | ||||
|         _f.deferreturn = f.DeferReturn | ||||
|         // NOTICE: _func.pcdata is always as [PCDATA_UnsafePoint(0) : PCDATA_ArgLiveIndex(3)] | ||||
|         _f.npcdata = uint32(_N_PCDATA) | ||||
|         _f.cuOffset = cuOffset[i] | ||||
|         _f.funcID = f.ID | ||||
|         _f.flag = f.Flag | ||||
|         _f.nfuncdata = uint8(_N_FUNCDATA) | ||||
|     } | ||||
| 
 | ||||
|     return | ||||
| } | ||||
| 
 | ||||
| func registerFunction(name string, pc uintptr, textSize uintptr, fp int, args int, size uintptr, argptrs uintptr, localptrs uintptr) {} | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue