github.com/pkujhd/goloader@v0.0.0-20240411034752-1a28096bd7bd/iface.1.10.go (about) 1 //go:build go1.10 && !go1.23 2 // +build go1.10,!go1.23 3 4 package goloader 5 6 import ( 7 "unsafe" 8 ) 9 10 // layout of Itab known to compilers 11 // allocated in non-garbage-collected memory 12 // Needs to be in sync with 13 // ../cmd/compile/internal/gc/reflect.go:/^func.dumptabs. 14 type itab struct { 15 inter *interfacetype 16 _type *_type 17 hash uint32 // copy of _type.hash. Used for type switches. 18 _ [4]byte 19 fun [1]uintptr // variable sized. fun[0]==0 means _type does not implement inter. 20 } 21 22 const itabInitSize = 512 23 24 // Note: change the formula in the mallocgc call in itabAdd if you change these fields. 25 type itabTableType struct { 26 size uintptr // length of entries array. Always a power of 2. 27 count uintptr // current number of filled entries. 28 entries [itabInitSize]*itab // really [size] large 29 } 30 31 //go:linkname __itabTable runtime.itabTable 32 var __itabTable unsafe.Pointer // pointer to current table 33 34 // Avoids "go.info.runtime.itabTable: relocation target go.info.*github.com/pkujhd/goloader.itabTableType not defined" 35 var itabTable = *(**itabTableType)(unsafe.Pointer(&__itabTable)) 36 37 //go:linkname __itabLock runtime.itabLock 38 var __itabLock uintptr 39 40 // Avoids "go.info.runtime.itabLock: relocation target go.info.github.com/pkujhd/goloader.mutex not defined" 41 var itabLock = (*mutex)(unsafe.Pointer(&__itabLock)) 42 43 //go:linkname itabAdd runtime.itabAdd 44 func itabAdd(m *itab) 45 46 func additabs(module *moduledata) { 47 lock(itabLock) 48 for _, itab := range module.itablinks { 49 itabAdd(itab) 50 } 51 unlock(itabLock) 52 } 53 54 func removeitabs(module *moduledata) bool { 55 lock(itabLock) 56 defer unlock(itabLock) 57 58 for i := uintptr(0); i < itabTable.size; i++ { 59 p := (**itab)(add(unsafe.Pointer(&itabTable.entries), i*PtrSize)) 60 m := (*itab)(loadp(unsafe.Pointer(p))) 61 if m != nil { 62 uintptrm := uintptr(unsafe.Pointer(m)) 63 inter := uintptr(unsafe.Pointer(m.inter)) 64 _type := uintptr(unsafe.Pointer(m._type)) 65 if (inter >= module.types && inter <= module.etypes) || (_type >= module.types && _type <= module.etypes) || 66 (uintptrm >= module.types && uintptrm <= module.etypes) { 67 atomicstorep(unsafe.Pointer(p), unsafe.Pointer(nil)) 68 itabTable.count = itabTable.count - 1 69 } 70 } 71 } 72 return true 73 }