github.com/pkujhd/goloader@v0.0.0-20240411034752-1a28096bd7bd/stackobject/stackobject.go (about)

     1  //go:build go1.12 && !go1.23
     2  // +build go1.12,!go1.23
     3  
     4  package stackobject
     5  
     6  import (
     7  	"fmt"
     8  	"unsafe"
     9  
    10  	"github.com/pkujhd/goloader/obj"
    11  	"github.com/pkujhd/goloader/objabi/dataindex"
    12  )
    13  
    14  // See reflect/value.go sliceHeader
    15  type sliceHeader struct {
    16  	Data uintptr
    17  	Len  int
    18  	Cap  int
    19  }
    20  
    21  //go:linkname add runtime.add
    22  func add(p unsafe.Pointer, x uintptr) unsafe.Pointer
    23  
    24  //go:linkname adduintptr runtime.add
    25  func adduintptr(p uintptr, x int) unsafe.Pointer
    26  
    27  func addr2stackObjectRecords(addr unsafe.Pointer) *[]stackObjectRecord {
    28  	n := int(*(*uintptr)(addr))
    29  	slice := sliceHeader{
    30  		Data: uintptr(add(addr, uintptr(PtrSize))),
    31  		Len:  n,
    32  		Cap:  n,
    33  	}
    34  	return (*[]stackObjectRecord)(unsafe.Pointer(&slice))
    35  }
    36  
    37  func AddStackObject(funcname string, symMap map[string]*obj.Sym, symbolMap map[string]uintptr, noptrdata uintptr) (err error) {
    38  	Func := symMap[funcname].Func
    39  	if Func != nil && len(Func.FuncData) > dataindex.FUNCDATA_StackObjects &&
    40  		Func.FuncData[dataindex.FUNCDATA_StackObjects] != 0 {
    41  		objects := addr2stackObjectRecords(adduintptr(Func.FuncData[dataindex.FUNCDATA_StackObjects], int(noptrdata)))
    42  		for i := range *objects {
    43  			name := EmptyString
    44  			stkobjName := funcname + StkobjSuffix
    45  			if symbol := symMap[stkobjName]; symbol != nil {
    46  				name = symbol.Reloc[i].SymName
    47  			}
    48  			if ptr, ok := symbolMap[name]; ok {
    49  				setStackObjectPtr(&((*objects)[i]), adduintptr(ptr, 0), noptrdata)
    50  			} else {
    51  				return fmt.Errorf("unresolve external Var! Function name:%s index:%d, name:%s", funcname, i, name)
    52  
    53  			}
    54  		}
    55  	}
    56  	return nil
    57  }