forked from pkujhd/goloader
-
Notifications
You must be signed in to change notification settings - Fork 4
/
module.go
120 lines (97 loc) · 3.18 KB
/
module.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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package goloader
import (
"unsafe"
)
//go:linkname firstmoduledata runtime.firstmoduledata
var firstmoduledata moduledata
//go:linkname pinnedTypemaps runtime.pinnedTypemaps
var pinnedTypemaps []unsafe.Pointer
// Avoids "go:info.runtime.pinnedTypemaps: relocation target go:info.[]map[github.com/eh-steve/goloader.typeOff]*github.com/eh-steve/goloader._type not defined"
var pinnedTypemapsTyped = (*[]map[typeOff]*_type)(unsafe.Pointer(&pinnedTypemaps))
// findfunctab is an array of these structures.
// Each bucket represents 4096 bytes of the text segment.
// Each subbucket represents 256 bytes of the text segment.
// To find a function given a pc, locate the bucket and subbucket for
// that pc. Add together the idx and subbucket value to obtain a
// function index. Then scan the functab array starting at that
// index to find the target function.
// This table uses 20 bytes for every 4096 bytes of code, or ~0.5% overhead.
type findfuncbucket struct {
idx uint32
subbuckets [16]byte
}
// Mapping information for secondary text sections
type textsect struct {
vaddr uintptr // prelinked section vaddr
length uintptr // section length
baseaddr uintptr // relocated section address
}
type nameOff int32
type typeOff int32
type textOff int32
// A ptabEntry is generated by the compiler for each exported function
// and global variable in the main package of a plugin. It is used to
// initialize the plugin module's symbol map.
type ptabEntry struct {
name nameOff
typ typeOff
}
type modulehash struct {
modulename string
linktimehash string
runtimehash *string
}
type bitvector struct {
n int32 // # of bits
bytedata *uint8
}
type stackmap struct {
n int32 // number of bitmaps
nbit int32 // number of bits in each bitmap
bytedata [1]byte // bitmaps, each starting on a byte boundary
}
type funcInfo struct {
*_func
datap *moduledata
}
const minfunc = 16 // minimum function size
const pcbucketsize = 256 * minfunc // size of bucket in the pc->func lookup table
const nsub = len(findfuncbucket{}.subbuckets)
//go:linkname step runtime.step
func step(p []byte, pc *uintptr, val *int32, first bool) (newp []byte, ok bool)
//go:linkname findfunc runtime.findfunc
func findfunc(pc uintptr) funcInfo
//go:linkname funcdata runtime.funcdata
func funcdata(f funcInfo, i int32) unsafe.Pointer
//go:linkname funcname runtime.funcname
func funcname(f funcInfo) string
//go:linkname gostringnocopy runtime.gostringnocopy
func gostringnocopy(str *byte) string
//go:linkname moduledataverify1 runtime.moduledataverify1
func moduledataverify1(datap *moduledata)
//go:linkname modulesinit runtime.modulesinit
func modulesinit()
//go:linkname progToPointerMask runtime.progToPointerMask
func progToPointerMask(prog *byte, size uintptr) bitvector
func addModule(cm *CodeModule) {
modules[cm] = true
for datap := &firstmoduledata; ; {
if datap.next == nil {
datap.next = cm.module
break
}
datap = datap.next
}
}
func removeModule(cm *CodeModule) {
prevp := &firstmoduledata
for datap := &firstmoduledata; datap != nil; {
if datap == cm.module {
prevp.next = datap.next
break
}
prevp = datap
datap = datap.next
}
delete(modules, cm)
}