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  }