github.com/tencent/goom@v1.0.1/internal/bytecode/func.go (about)

     1  package bytecode
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"sync"
     7  	"unsafe"
     8  
     9  	"github.com/tencent/goom/internal/bytecode/memory"
    10  	"github.com/tencent/goom/internal/logger"
    11  	"github.com/tencent/goom/internal/unexports"
    12  )
    13  
    14  // 调试日志相关
    15  const (
    16  	// PrintShort 默认打印的指令数量(短)
    17  	PrintShort = 20
    18  	// PrintMiddle 默认打印的指令数量(中)
    19  	PrintMiddle = 30
    20  	// PrintLong 默认打印的指令数量(长)
    21  	PrintLong = 35
    22  )
    23  
    24  var (
    25  	// funcSizeCache 函数长度缓存
    26  	funcSizeCache = make(map[uintptr]int)
    27  	// funcSizeReadLock 并发读写 funcSizeCache 锁
    28  	funcSizeReadLock sync.Mutex
    29  )
    30  
    31  var (
    32  	//nolint it is for arm arch
    33  	// armFuncPrologue64 arm64 func prologue
    34  	armFuncPrologue64 = []byte{0x81, 0x0B, 0x40, 0xF9, 0xE2, 0x03, 0x00, 0x91, 0x5F, 0x00, 0x01, 0xEB}
    35  )
    36  
    37  // value value keep async with reflect.Value
    38  type value struct {
    39  	_   uintptr
    40  	ptr unsafe.Pointer
    41  }
    42  
    43  // GetPtr 获取函数的调用地址(和函数的指令地址不一样)
    44  func GetPtr(v reflect.Value) unsafe.Pointer {
    45  	return (*value)(unsafe.Pointer(&v)).ptr
    46  }
    47  
    48  // isNil 判断 interface{}是否为空
    49  func isNil(i interface{}) bool {
    50  	if i == nil {
    51  		return true
    52  	}
    53  	switch reflect.TypeOf(i).Kind() {
    54  	case reflect.Ptr, reflect.Map, reflect.Array, reflect.Chan, reflect.Slice:
    55  		return reflect.ValueOf(i).Elem().IsNil()
    56  	}
    57  	return reflect.ValueOf(i).IsNil()
    58  }
    59  
    60  // GetTrampolinePtr 获取跳板函数的地址
    61  func GetTrampolinePtr(trampoline interface{}) (uintptr, error) {
    62  	if isNil(trampoline) {
    63  		return 0, nil
    64  	}
    65  
    66  	var result uintptr
    67  	typ := reflect.TypeOf(trampoline)
    68  	if typ.Kind() == reflect.Ptr {
    69  		result = reflect.ValueOf(trampoline).Elem().Pointer()
    70  	} else if typ.Kind() == reflect.Func {
    71  		result = reflect.ValueOf(trampoline).Pointer()
    72  	}
    73  	logger.Debugf("trampoline value: 0x%x 0x%x", GetPtr(reflect.ValueOf(trampoline)), result)
    74  	return result, nil
    75  }
    76  
    77  // IsValidPtr 判断函数 value 是否为指针类型
    78  func IsValidPtr(value interface{}) bool {
    79  	if value == nil {
    80  		return false
    81  	}
    82  	t := reflect.TypeOf(value)
    83  	return t.Kind() == reflect.Ptr
    84  }
    85  
    86  // PrintInst PrintInst 调试内存指令替换,对原指令、替换之后的指令进行输出对比
    87  func PrintInst(name string, from uintptr, size int, level int) {
    88  	_, funcName, _ := unexports.FindFuncByPtr(from)
    89  	instBytes := memory.RawRead(from, size)
    90  	PrintInstf(fmt.Sprintf("show [%s = %s] inst>>: ", name, funcName), from, instBytes, level)
    91  }
    92  
    93  // MinSize 最小 size,不超出 fixOrigin 长度的 size 大小
    94  func MinSize(showSize int, fixOrigin []byte) int {
    95  	if showSize > len(fixOrigin) {
    96  		showSize = len(fixOrigin)
    97  	}
    98  	return showSize
    99  }