github.com/pkujhd/goloader@v0.0.0-20240411034752-1a28096bd7bd/module.go (about) 1 package goloader 2 3 import ( 4 "unsafe" 5 ) 6 7 //go:linkname firstmoduledata runtime.firstmoduledata 8 var firstmoduledata moduledata 9 10 // findfunctab is an array of these structures. 11 // Each bucket represents 4096 bytes of the text segment. 12 // Each subbucket represents 256 bytes of the text segment. 13 // To find a function given a pc, locate the bucket and subbucket for 14 // that pc. Add together the idx and subbucket value to obtain a 15 // function index. Then scan the functab array starting at that 16 // index to find the target function. 17 // This table uses 20 bytes for every 4096 bytes of code, or ~0.5% overhead. 18 type findfuncbucket struct { 19 idx uint32 20 subbuckets [16]byte 21 } 22 23 // Mapping information for secondary text sections 24 type textsect struct { 25 vaddr uintptr // prelinked section vaddr 26 length uintptr // section length 27 baseaddr uintptr // relocated section address 28 } 29 30 type nameOff int32 31 type typeOff int32 32 type textOff int32 33 34 // A ptabEntry is generated by the compiler for each exported function 35 // and global variable in the main package of a plugin. It is used to 36 // initialize the plugin module's symbol map. 37 type ptabEntry struct { 38 name nameOff 39 typ typeOff 40 } 41 42 type modulehash struct { 43 modulename string 44 linktimehash string 45 runtimehash *string 46 } 47 48 type bitvector struct { 49 n int32 // # of bits 50 bytedata *uint8 51 } 52 53 type stackmap struct { 54 n int32 // number of bitmaps 55 nbit int32 // number of bits in each bitmap 56 bytedata [1]byte // bitmaps, each starting on a byte boundary 57 } 58 59 type funcInfo struct { 60 *_func 61 datap *moduledata 62 } 63 64 const minfunc = 16 // minimum function size 65 const pcbucketsize = 256 * minfunc // size of bucket in the pc->func lookup table 66 const nsub = len(findfuncbucket{}.subbuckets) 67 68 //go:linkname step runtime.step 69 func step(p []byte, pc *uintptr, val *int32, first bool) (newp []byte, ok bool) 70 71 //go:linkname findfunc runtime.findfunc 72 func findfunc(pc uintptr) funcInfo 73 74 //go:linkname funcdata runtime.funcdata 75 func funcdata(f funcInfo, i int32) unsafe.Pointer 76 77 //go:linkname funcname runtime.funcname 78 func funcname(f funcInfo) string 79 80 //go:linkname gostringnocopy runtime.gostringnocopy 81 func gostringnocopy(str *byte) string 82 83 //go:linkname moduledataverify1 runtime.moduledataverify1 84 func moduledataverify1(datap *moduledata) 85 86 //go:linkname modulesinit runtime.modulesinit 87 func modulesinit() 88 89 //go:linkname progToPointerMask runtime.progToPointerMask 90 func progToPointerMask(prog *byte, size uintptr) bitvector 91 92 func addModule(module *moduledata) { 93 modules[module] = true 94 for datap := &firstmoduledata; ; { 95 if datap.next == nil { 96 datap.next = module 97 break 98 } 99 datap = datap.next 100 } 101 } 102 func removeModule(module interface{}) { 103 prevp := &firstmoduledata 104 for datap := &firstmoduledata; datap != nil; { 105 if datap == module { 106 prevp.next = datap.next 107 break 108 } 109 prevp = datap 110 datap = datap.next 111 } 112 delete(modules, module) 113 }