github.com/pkujhd/goloader@v0.0.0-20240411034752-1a28096bd7bd/iface.1.8.go (about) 1 //go:build go1.8 && !go1.10 2 // +build go1.8,!go1.10 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.dumptypestructs. 14 type itab struct { 15 inter *interfacetype 16 _type *_type 17 link *itab 18 bad int32 19 inhash int32 // has this itab been added to hash? 20 fun [1]uintptr // variable sized 21 } 22 23 // See: src/runtime/iface.go 24 const hashSize = 1009 25 26 //go:linkname __hash runtime.hash 27 var __hash uintptr 28 29 var hash = (*[hashSize]*itab)(unsafe.Pointer(&__hash)) 30 31 //go:linkname __ifaceLock runtime.ifaceLock 32 var __ifaceLock uintptr 33 34 var ifaceLock = (*mutex)(unsafe.Pointer(&__ifaceLock)) 35 36 //go:linkname additab runtime.additab 37 func additab(m *itab, locked, canfail bool) 38 39 func additabs(module *moduledata) { 40 lock(ifaceLock) 41 for _, itab := range module.itablinks { 42 if itab.inhash == 0 { 43 additab(itab, true, false) 44 } 45 } 46 unlock(ifaceLock) 47 } 48 49 func removeitabs(module *moduledata) bool { 50 lock(ifaceLock) 51 defer unlock(ifaceLock) 52 53 //the itab alloc by runtime.persistentalloc, can't free 54 for index, h := range hash { 55 last := h 56 for m := h; m != nil; m = m.link { 57 uintptrm := uintptr(unsafe.Pointer(m)) 58 inter := uintptr(unsafe.Pointer(m.inter)) 59 _type := uintptr(unsafe.Pointer(m._type)) 60 if (inter >= module.types && inter <= module.etypes) || (_type >= module.types && _type <= module.etypes) || 61 (uintptrm >= module.types && uintptrm <= module.etypes) { 62 if m == h { 63 hash[index] = m.link 64 } else { 65 last.link = m.link 66 } 67 } 68 last = m 69 } 70 } 71 return true 72 }