forked from pkujhd/goloader
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtype.go
104 lines (85 loc) · 2.21 KB
/
type.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package goloader
import (
"reflect"
"runtime"
"strings"
"unsafe"
)
type tflag uint8
// See reflect/value.go emptyInterface
type emptyInterface struct {
typ unsafe.Pointer
word unsafe.Pointer
}
// See reflect/value.go sliceHeader
type sliceHeader struct {
Data uintptr
Len int
Cap int
}
// Method on non-interface type
type method struct {
name nameOff // name of method
mtyp typeOff // method type (without receiver)
ifn textOff // fn used in interface call (one-word receiver)
tfn textOff // fn used for normal method call
}
type imethod struct {
name nameOff
ityp typeOff
}
type interfacetype struct {
typ _type
pkgpath name
mhdr []imethod
}
type name struct {
bytes *byte
}
//go:linkname (*_type).uncommon runtime.(*_type).uncommon
func (t *_type) uncommon() *uncommonType
//go:linkname (*_type).nameOff runtime.(*_type).nameOff
func (t *_type) nameOff(off nameOff) name
//go:linkname (*_type).typeOff runtime.(*_type).typeOff
func (t *_type) typeOff(off typeOff) *_type
//go:linkname name.name runtime.name.name
func (n name) name() string
//go:linkname (*uncommonType).methods reflect.(*uncommonType).methods
func (t *uncommonType) methods() []method
//go:linkname (*_type).Kind reflect.(*rtype).Kind
func (t *_type) Kind() reflect.Kind
func pkgname(pkgpath string) string {
slash := strings.LastIndexByte(pkgpath, '/')
if slash > -1 {
return pkgpath[slash+1:]
} else {
return pkgpath
}
}
func (t *_type) PkgPath() string {
ut := t.uncommon()
if ut == nil {
return EmptyString
}
return t.nameOff(ut.pkgPath).name()
}
func RegTypes(symPtr map[string]uintptr, interfaces ...interface{}) {
for _, inter := range interfaces {
v := reflect.ValueOf(inter)
regType(symPtr, v)
if v.Kind() == reflect.Ptr {
regType(symPtr, v.Elem())
}
}
}
func regType(symPtr map[string]uintptr, v reflect.Value) {
inter := v.Interface()
if v.Kind() == reflect.Func && getFunctionPtr(inter) != 0 {
symPtr[runtime.FuncForPC(v.Pointer()).Name()] = getFunctionPtr(inter)
} else {
header := (*emptyInterface)(unsafe.Pointer(&inter))
pkgpath := (*_type)(header.typ).PkgPath()
name := strings.Replace(v.Type().String(), pkgname(pkgpath), pkgpath, 1)
symPtr[TypePrefix+name] = uintptr(header.typ)
}
}