@@ -36,12 +36,20 @@ func typelinksinit(symPtr map[string]uintptr) {
36
36
registerFunc (& md , symPtr )
37
37
}
38
38
39
+ func RegSymbolWithSo (symPtr map [string ]uintptr , path string ) error {
40
+ return regSymbol (symPtr , path )
41
+ }
42
+
39
43
func RegSymbol (symPtr map [string ]uintptr ) error {
40
- exe , err := os .Executable ()
44
+ path , err := os .Executable ()
41
45
if err != nil {
42
46
return err
43
47
}
44
- f , err := objfile .Open (exe )
48
+ return regSymbol (symPtr , path )
49
+ }
50
+
51
+ func regSymbol (symPtr map [string ]uintptr , path string ) error {
52
+ f , err := objfile .Open (path )
45
53
if err != nil {
46
54
return err
47
55
}
@@ -69,13 +77,30 @@ func RegSymbol(symPtr map[string]uintptr) error {
69
77
return nil
70
78
}
71
79
72
- func regTLS (symPtr map [string ]uintptr , offset int ) {
80
+ func regTLS (symPtr map [string ]uintptr , oper [] byte ) {
73
81
//FUNCTION HEADER
74
82
//x86/amd64
75
83
//asm: MOVQ (TLS), CX
76
- //bytes: 0x488b0c2500000000
84
+ //bytes: 0x64488b0c2500000000 or 0x65488b0c2500000000
85
+ //FS(0x64) or GS(0x65) segment register, on golang 1.8, FS/GS all generate.
86
+ //asm: MOVQ OFF(IP), CX
87
+ //bytes: 0x488b0d00000000
88
+ //MOVQ OFF(IP), CX will be generated when goloader is a c-typed dynamic lib(only on linux/amd64)
77
89
funcptr := getFunctionPtr (regTLS )
78
- tlsptr := * (* uint32 )(adduintptr (funcptr , offset ))
90
+ for i := 0 ; i < len (oper ); i ++ {
91
+ if * (* byte )(adduintptr (funcptr , i )) != oper [i ] {
92
+ //function header modified
93
+ if * (* uint32 )(unsafe .Pointer (funcptr ))& 0x00FFFFFF == 0x000d8b48 {
94
+ ptr := * (* uint32 )(adduintptr (funcptr , 3 ))
95
+ ptr = * (* uint32 )(adduintptr (funcptr , int (ptr )+ 7 ))
96
+ symPtr [TLSNAME ] = uintptr (ptr )
97
+ return
98
+ } else {
99
+ panic ("function header modified, can not relocate TLS" )
100
+ }
101
+ }
102
+ }
103
+ tlsptr := * (* uint32 )(adduintptr (funcptr , len (oper )))
79
104
symPtr [TLSNAME ] = uintptr (tlsptr )
80
105
}
81
106
0 commit comments