Skip to content

Commit 7701df1

Browse files
committed
add support#24 loader is dynamic library
1 parent 5bfa3d7 commit 7701df1

File tree

2 files changed

+34
-6
lines changed

2 files changed

+34
-6
lines changed

Diff for: dymcode.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ func (linker *Linker) addSymbolMap(symPtr map[string]uintptr, codeModule *CodeMo
313313
return nil, fmt.Errorf("unresolve external:%s", sym.Name)
314314
}
315315
} else if sym.Name == TLSNAME {
316-
regTLS(symbolMap, sym.Offset)
316+
//nothing todo
317317
} else if sym.Kind == STEXT {
318318
symbolMap[name] = uintptr(linker.symMap[name].Offset + segment.codeBase)
319319
codeModule.Syms[sym.Name] = uintptr(symbolMap[name])
@@ -493,6 +493,9 @@ func (linker *Linker) relocate(codeModule *CodeModule, symbolMap map[string]uint
493493
if addr != InvalidHandleValue {
494494
switch loc.Type {
495495
case R_TLS_LE:
496+
if _, ok := symbolMap[TLSNAME]; !ok {
497+
regTLS(symbolMap, segment.codeByte[symbol.Offset:loc.Offset])
498+
}
496499
binary.LittleEndian.PutUint32(segment.codeByte[loc.Offset:], uint32(symbolMap[TLSNAME]))
497500
case R_CALL:
498501
relocateCALL(addr, loc, segment, relocByte, addrBase)

Diff for: register.go

+30-5
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,20 @@ func typelinksinit(symPtr map[string]uintptr) {
3636
registerFunc(&md, symPtr)
3737
}
3838

39+
func RegSymbolWithSo(symPtr map[string]uintptr, path string) error {
40+
return regSymbol(symPtr, path)
41+
}
42+
3943
func RegSymbol(symPtr map[string]uintptr) error {
40-
exe, err := os.Executable()
44+
path, err := os.Executable()
4145
if err != nil {
4246
return err
4347
}
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)
4553
if err != nil {
4654
return err
4755
}
@@ -69,13 +77,30 @@ func RegSymbol(symPtr map[string]uintptr) error {
6977
return nil
7078
}
7179

72-
func regTLS(symPtr map[string]uintptr, offset int) {
80+
func regTLS(symPtr map[string]uintptr, oper []byte) {
7381
//FUNCTION HEADER
7482
//x86/amd64
7583
//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)
7789
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)))
79104
symPtr[TLSNAME] = uintptr(tlsptr)
80105
}
81106

0 commit comments

Comments
 (0)