github.com/eh-steve/goloader@v0.0.0-20240111193454-90ff3cfdae39/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/eh-steve/goloader.itabTableType not defined" 35 var itabTableTyped = (**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/eh-steve/goloader.mutex not defined" 41 var itabLockTyped = (*mutex)(unsafe.Pointer(&itabLock)) 42 43 //go:linkname itabAdd runtime.itabAdd 44 func itabAdd(m *itab) 45 46 func additabs(module *moduledata) { 47 lock(itabLockTyped) 48 for _, itab := range module.itablinks { 49 itabAdd(itab) 50 } 51 unlock(itabLockTyped) 52 } 53 54 func removeitabs(module *moduledata) bool { 55 lock(itabLockTyped) 56 defer unlock(itabLockTyped) 57 58 t := *itabTableTyped 59 for i := uintptr(0); i < t.size; i++ { 60 p := (**itab)(add(unsafe.Pointer(&t.entries), i*PtrSize)) 61 m := (*itab)(loadp(unsafe.Pointer(p))) 62 if m != nil { 63 uintptrm := uintptr(unsafe.Pointer(m)) 64 inter := uintptr(unsafe.Pointer(m.inter)) 65 _type := uintptr(unsafe.Pointer(m._type)) 66 if (inter >= module.types && inter <= module.etypes) || (_type >= module.types && _type <= module.etypes) || 67 (uintptrm >= module.types && uintptrm <= module.etypes) { 68 atomicstorep(unsafe.Pointer(p), unsafe.Pointer(nil)) 69 t.count = t.count - 1 70 } 71 } 72 } 73 return true 74 }