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 }