forked from pkujhd/goloader
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstackobject.go
53 lines (46 loc) · 1.47 KB
/
stackobject.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
// +build go1.12
// +build !go1.17
package goloader
import (
"fmt"
"unsafe"
)
const stackObjectRecordSize = unsafe.Sizeof(stackObjectRecord{})
// A stackObjectRecord is generated by the compiler for each stack object in a stack frame.
// This record must match the generator code in cmd/compile/internal/gc/ssa.go:emitStackObjects.
type stackObjectRecord struct {
// offset in frame
// if negative, offset from varp
// if non-negative, offset from argp
off int
typ *_type
}
func addr2stackObjectRecords(addr unsafe.Pointer) *[]stackObjectRecord {
n := int(*(*uintptr)(addr))
slice := sliceHeader{
Data: uintptr(add(addr, uintptr(PtrSize))),
Len: n,
Cap: n,
}
return (*[]stackObjectRecord)(unsafe.Pointer(&slice))
}
func (linker *Linker) _addStackObject(funcname string, symbolMap map[string]uintptr) (err error) {
Func := linker.symMap[funcname].Func
if Func != nil && len(Func.FuncData) > _FUNCDATA_StackObjects &&
Func.FuncData[_FUNCDATA_StackObjects] != 0 {
objects := addr2stackObjectRecords(adduintptr(Func.FuncData[_FUNCDATA_StackObjects], 0))
for i := range *objects {
name := EmptyString
stkobjName := funcname + StkobjSuffix
if symbol := linker.symMap[stkobjName]; symbol != nil {
name = symbol.Reloc[i].Sym.Name
}
if ptr, ok := symbolMap[name]; ok {
(*objects)[i].typ = (*_type)(adduintptr(ptr, 0))
} else {
return fmt.Errorf("unresolve external Var! Function name:%s index:%d, name:%s", funcname, i, name)
}
}
}
return nil
}