forked from pkujhd/goloader
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdymcode.1.14.go
82 lines (77 loc) · 2.57 KB
/
dymcode.1.14.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
// +build go1.14
// +build !go1.15
package goloader
import (
"encoding/binary"
"strconv"
"unsafe"
)
const (
R_PCREL = 16
// R_TLS_LE, used on 386, amd64, and ARM, resolves to the offset of the
// thread-local symbol from the thread local base and is used to implement the
// "local exec" model for tls access (r.Sym is not set on intel platforms but is
// set to a TLS symbol -- runtime.tlsg -- in the linker when externally linking).
R_TLS_LE = 17
// R_METHODOFF resolves to a 32-bit offset from the beginning of the section
// holding the data being relocated to the referenced symbol.
// It is a variant of R_ADDROFF used when linking from the uncommonType of a
// *rtype, and may be set to zero by the linker if it determines the method
// text is unreachable by the linked program.
R_METHODOFF = 25
)
func AddStackObject(code *CodeReloc, fi *funcInfoData, seg *segment, symPtr map[string]uintptr) {
if len(fi.funcdata) > _FUNCDATA_StackObjects && fi.funcdata[_FUNCDATA_StackObjects] != 0xFFFFFFFF {
stackObjectRecordSize := unsafe.Sizeof(stackObjectRecord{})
b := code.Mod.stkmaps[fi.funcdata[_FUNCDATA_StackObjects]]
n := *(*int)(unsafe.Pointer(&b[0]))
p := unsafe.Pointer(&b[PtrSize])
for i := 0; i < n; i++ {
obj := *(*stackObjectRecord)(p)
var name string
for _, v := range fi.Var {
if v.Offset == (int64)(obj.off) {
name = v.Type.Name
break
}
}
if len(name) == 0 {
name = fi.stkobjReloc[i].Sym.Name
}
ptr, ok := symPtr[name]
if !ok {
ptr, ok = seg.typeSymPtr[name]
}
if !ok {
sprintf(&seg.err, "unresolve external:", strconv.Itoa(i), " ", fi.name, "\n")
} else {
off := PtrSize + i*(int)(stackObjectRecordSize) + PtrSize
if PtrSize == 4 {
binary.LittleEndian.PutUint32(b[off:], *(*uint32)(unsafe.Pointer(&ptr)))
} else {
binary.LittleEndian.PutUint64(b[off:], *(*uint64)(unsafe.Pointer(&ptr)))
}
}
p = add(p, stackObjectRecordSize)
}
}
}
func AddDeferReturn(code *CodeReloc, fi *funcInfoData, seg *segment) {
if len(fi.funcdata) > _FUNCDATA_OpenCodedDeferInfo && fi.funcdata[_FUNCDATA_OpenCodedDeferInfo] != 0xFFFFFFFF {
sym := code.Syms[code.SymMap[fi.name]]
for _, r := range sym.Reloc {
if r.SymOff == code.SymMap["runtime.deferreturn"] {
//../cmd/link/internal/ld/pcln.go:pclntab
switch code.Arch {
case "amd64", "386":
fi.deferreturn = uint32(r.Offset) - uint32(sym.Offset) - 1
case "arm", "arm64":
fi.deferreturn = uint32(r.Offset) - uint32(sym.Offset)
default:
sprintf(&seg.err, "not support arch:", code.Arch, "\n")
}
break
}
}
}
}