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  }