From 328a5ad3ac6541216f66796aeb1aca6b50a4a58e Mon Sep 17 00:00:00 2001 From: pkujhd Date: Fri, 24 Nov 2023 19:48:36 +0800 Subject: [PATCH] optimize code --- LICENSE | 2 +- func.1.12.go | 7 +-- func.1.16.go | 4 +- func.1.18.go | 4 +- func.1.20.go | 4 +- func.1.8.go | 4 +- gcdata.go | 4 +- inlinetree.go | 4 +- ld.go | 115 +++++++++++++++++++++++----------------- obj/readobj.1.16.go | 6 +-- obj/readobj.1.8.go | 4 +- obj/readobj.go | 2 +- pcdata.go => pcvalue.go | 12 ++--- readobj.go | 8 +-- relocate.go | 10 ++-- utils.go | 14 +++++ 16 files changed, 117 insertions(+), 87 deletions(-) rename pcdata.go => pcvalue.go (86%) diff --git a/LICENSE b/LICENSE index 0fd71c41..ea320c8b 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2019-2022 pkujhd + Copyright 2019-2023 pkujhd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/func.1.12.go b/func.1.12.go index 6f0538a6..9a8a8dcb 100644 --- a/func.1.12.go +++ b/func.1.12.go @@ -5,8 +5,9 @@ package goloader import ( "cmd/objfile/objabi" - "github.com/pkujhd/goloader/obj" "strings" + + "github.com/pkujhd/goloader/obj" ) // A funcID identifies particular functions that need to be treated @@ -36,13 +37,13 @@ type _func struct { nfuncdata uint8 // must be last } -func initfunc(symbol *obj.ObjSymbol, nameOff, spOff, pcfileOff, pclnOff int, cuOff int) _func { +func initfunc(symbol *obj.ObjSymbol, nameOff, pcspOff, pcfileOff, pclnOff int, cuOff int) _func { fdata := _func{ entry: uintptr(0), nameoff: int32(nameOff), args: int32(symbol.Func.Args), deferreturn: uint32(0), - pcsp: int32(spOff), + pcsp: int32(pcspOff), pcfile: int32(pcfileOff), pcln: int32(pclnOff), npcdata: int32(len(symbol.Func.PCData)), diff --git a/func.1.16.go b/func.1.16.go index d465e13c..f210c693 100644 --- a/func.1.16.go +++ b/func.1.16.go @@ -33,13 +33,13 @@ type _func struct { nfuncdata uint8 // must be last } -func initfunc(symbol *obj.ObjSymbol, nameOff, spOff, pcfileOff, pclnOff, cuOff int) _func { +func initfunc(symbol *obj.ObjSymbol, nameOff, pcspOff, pcfileOff, pclnOff, cuOff int) _func { fdata := _func{ entry: uintptr(0), nameoff: int32(nameOff), args: int32(symbol.Func.Args), deferreturn: uint32(0), - pcsp: uint32(spOff), + pcsp: uint32(pcspOff), pcfile: uint32(pcfileOff), pcln: uint32(pclnOff), npcdata: uint32(len(symbol.Func.PCData)), diff --git a/func.1.18.go b/func.1.18.go index 29cbdae5..73385139 100644 --- a/func.1.18.go +++ b/func.1.18.go @@ -38,13 +38,13 @@ type _func struct { nfuncdata uint8 // must be last, must end on a uint32-aligned boundary } -func initfunc(symbol *obj.ObjSymbol, nameOff, spOff, pcfileOff, pclnOff, cuOff int) _func { +func initfunc(symbol *obj.ObjSymbol, nameOff, pcspOff, pcfileOff, pclnOff, cuOff int) _func { fdata := _func{ entryoff: uint32(0), nameoff: int32(nameOff), args: int32(symbol.Func.Args), deferreturn: uint32(0), - pcsp: uint32(spOff), + pcsp: uint32(pcspOff), pcfile: uint32(pcfileOff), pcln: uint32(pclnOff), npcdata: uint32(len(symbol.Func.PCData)), diff --git a/func.1.20.go b/func.1.20.go index c7a185f7..13f1c5ec 100644 --- a/func.1.20.go +++ b/func.1.20.go @@ -61,13 +61,13 @@ type _func struct { // funcdata [nfuncdata]uint32 } -func initfunc(symbol *obj.ObjSymbol, nameOff, spOff, pcfileOff, pclnOff, cuOff int) _func { +func initfunc(symbol *obj.ObjSymbol, nameOff, pcspOff, pcfileOff, pclnOff, cuOff int) _func { fdata := _func{ entryoff: uint32(0), nameoff: int32(nameOff), args: int32(symbol.Func.Args), deferreturn: uint32(0), - pcsp: uint32(spOff), + pcsp: uint32(pcspOff), pcfile: uint32(pcfileOff), pcln: uint32(pclnOff), npcdata: uint32(len(symbol.Func.PCData)), diff --git a/func.1.8.go b/func.1.8.go index b046e610..2ce74f5c 100644 --- a/func.1.8.go +++ b/func.1.8.go @@ -19,12 +19,12 @@ type _func struct { nfuncdata int32 } -func initfunc(symbol *obj.ObjSymbol, nameOff, spOff, pcfileOff, pclnOff, cuOff int) _func { +func initfunc(symbol *obj.ObjSymbol, nameOff, pcspOff, pcfileOff, pclnOff, cuOff int) _func { fdata := _func{ entry: uintptr(0), nameoff: int32(nameOff), args: int32(symbol.Func.Args), - pcsp: int32(spOff), + pcsp: int32(pcspOff), pcfile: int32(pcfileOff), pcln: int32(pclnOff), npcdata: int32(len(symbol.Func.PCData)), diff --git a/gcdata.go b/gcdata.go index 982c4559..2d75a761 100644 --- a/gcdata.go +++ b/gcdata.go @@ -17,10 +17,10 @@ const ( func generategcdata(linker *Linker, codeModule *CodeModule, symbolMap map[string]uintptr, w *gcprog.Writer, sym *obj.Sym) error { segment := &codeModule.segment //if symbol is in loader, ignore generate gc data - if symbolMap[sym.Name] < uintptr(segment.dataBase) || symbolMap[sym.Name] > uintptr(segment.dataBase+segment.sumDataLen) { + if symbolMap[sym.Name] < uintptr(segment.dataBase) || symbolMap[sym.Name] > uintptr(segment.dataBase+segment.dataSeg.length) { return nil } - objsym := linker.objsymbolMap[sym.Name] + objsym := linker.objSymbolMap[sym.Name] typeName := objsym.Type if len(typeName) == 0 && objsym.Size > 0 { // This is likely a global var with no type information encoded, so can't be GC'd (ignore it) diff --git a/inlinetree.go b/inlinetree.go index 3989ca8b..070049fc 100644 --- a/inlinetree.go +++ b/inlinetree.go @@ -36,8 +36,8 @@ func (linker *Linker) addInlineTree(_func *_func, symbol *obj.ObjSymbol) (err er bytes := make([]byte, len(Func.InlTree)*obj.InlinedCallSize) for k, inl := range Func.InlTree { funcID := uint8(0) - if _, ok := linker.objsymbolMap[inl.Func]; ok { - funcID = linker.objsymbolMap[inl.Func].Func.FuncID + if _, ok := linker.objSymbolMap[inl.Func]; ok { + funcID = linker.objSymbolMap[inl.Func].Func.FuncID } inlinedcall := obj.InitInlinedCall(inl, funcID, linker.nameMap, linker.filetab) copy2Slice(bytes[k*obj.InlinedCallSize:], uintptr(unsafe.Pointer(&inlinedcall)), obj.InlinedCallSize) diff --git a/ld.go b/ld.go index 43913e57..774350aa 100644 --- a/ld.go +++ b/ld.go @@ -20,21 +20,30 @@ import ( // ourself defined struct // code segment +type codeSeg struct { + codeByte []byte + codeBase int + length int + maxLen int + codeOff int +} + +// data segment +type dataSeg struct { + dataByte []byte + dataBase int + length int + maxLen int + dataLen int + noptrdataLen int + bssLen int + noptrbssLen int + dataOff int +} + type segment struct { - codeByte []byte - dataByte []byte - codeBase int - dataBase int - sumDataLen int - dataLen int - noptrdataLen int - bssLen int - noptrbssLen int - codeLen int - maxCodeLength int - maxDataLength int - codeOff int - dataOff int + codeSeg + dataSeg } type Linker struct { @@ -44,7 +53,7 @@ type Linker struct { bss []byte noptrbss []byte symMap map[string]*obj.Sym - objsymbolMap map[string]*obj.ObjSymbol + objSymbolMap map[string]*obj.ObjSymbol nameMap map[string]int stringMap map[string]*string filetab []uint32 @@ -72,7 +81,7 @@ var ( func initLinker() *Linker { linker := &Linker{ symMap: make(map[string]*obj.Sym), - objsymbolMap: make(map[string]*obj.ObjSymbol), + objSymbolMap: make(map[string]*obj.ObjSymbol), nameMap: make(map[string]int), stringMap: make(map[string]*string), } @@ -104,7 +113,7 @@ func (linker *Linker) addFiles(files []string) { func (linker *Linker) addSymbols() error { //static_tmp is 0, golang compile not allocate memory. linker.noptrdata = append(linker.noptrdata, make([]byte, IntSize)...) - for _, objSym := range linker.objsymbolMap { + for _, objSym := range linker.objSymbolMap { if objSym.Kind == symkind.STEXT && objSym.DupOK == false { if _, err := linker.addSymbol(objSym.Name); err != nil { return err @@ -142,7 +151,7 @@ func (linker *Linker) addSymbol(name string) (symbol *obj.Sym, err error) { if symbol, ok := linker.symMap[name]; ok { return symbol, nil } - objsym := linker.objsymbolMap[name] + objsym := linker.objSymbolMap[name] symbol = &obj.Sym{Name: objsym.Name, Kind: objsym.Kind} linker.symMap[symbol.Name] = symbol @@ -156,7 +165,7 @@ func (linker *Linker) addSymbol(name string) (symbol *obj.Sym, err error) { } bytearrayAlignNops(linker.Arch, &linker.code, funcalign.GetFuncAlign(linker.Arch)) symbol.Func = &obj.Func{} - if err := linker.readFuncData(linker.objsymbolMap[name], symbol.Offset); err != nil { + if err := linker.readFuncData(linker.objSymbolMap[name], symbol.Offset); err != nil { return nil, err } case symkind.SDATA: @@ -193,12 +202,12 @@ func (linker *Linker) addSymbol(name string) (symbol *obj.Sym, err error) { if reloc.Epilogue.Offset != 0 { reloc.Epilogue.Offset += symbol.Offset } - if _, ok := linker.objsymbolMap[reloc.Sym.Name]; ok { + if _, ok := linker.objSymbolMap[reloc.Sym.Name]; ok { reloc.Sym, err = linker.addSymbol(reloc.Sym.Name) if err != nil { return nil, err } - if len(linker.objsymbolMap[reloc.Sym.Name].Data) == 0 && reloc.Size > 0 { + if len(linker.objSymbolMap[reloc.Sym.Name].Data) == 0 && reloc.Size > 0 { //static_tmp is 0, golang compile not allocate memory. //goloader add IntSize bytes on linker.noptrdata[0] if reloc.Size <= IntSize { @@ -252,7 +261,7 @@ func (linker *Linker) addSymbol(name string) (symbol *obj.Sym, err error) { if objsym.Type != EmptyString { if _, ok := linker.symMap[objsym.Type]; !ok { - if _, ok := linker.objsymbolMap[objsym.Type]; !ok { + if _, ok := linker.objSymbolMap[objsym.Type]; !ok { linker.symMap[objsym.Type] = &obj.Sym{Name: objsym.Type, Offset: InvalidOffset} } } @@ -307,7 +316,7 @@ func (linker *Linker) readFuncData(symbol *obj.ObjSymbol, codeLen int) (err erro Func.FuncData = append(Func.FuncData, (uintptr)(0)) } else { if _, ok := linker.symMap[name]; !ok { - if _, ok := linker.objsymbolMap[name]; ok { + if _, ok := linker.objSymbolMap[name]; ok { if _, err = linker.addSymbol(name); err != nil { return err } @@ -478,38 +487,44 @@ func Load(linker *Linker, symPtr map[string]uintptr) (codeModule *CodeModule, er Syms: make(map[string]uintptr), module: &moduledata{typemap: nil}, } - codeModule.codeLen = len(linker.code) - codeModule.dataLen = len(linker.data) - codeModule.noptrdataLen = len(linker.noptrdata) - codeModule.bssLen = len(linker.bss) - codeModule.noptrbssLen = len(linker.noptrbss) - codeModule.sumDataLen = codeModule.dataLen + codeModule.noptrdataLen + codeModule.bssLen + codeModule.noptrbssLen - codeModule.maxCodeLength = alignof((codeModule.codeLen)*2, PageSize) - codeModule.maxDataLength = alignof((codeModule.sumDataLen)*2, PageSize) - codeByte, err := Mmap(codeModule.maxCodeLength) + + //init code segment + codeSeg := &codeModule.segment.codeSeg + codeSeg.length = len(linker.code) + codeSeg.maxLen = alignof((codeSeg.length)*2, PageSize) + codeByte, err := Mmap(codeSeg.maxLen) if err != nil { return nil, err } - dataByte, err := MmapData(codeModule.maxDataLength) + codeSeg.codeByte = codeByte + codeSeg.codeBase = int((*sliceHeader)(unsafe.Pointer(&codeByte)).Data) + copy(codeSeg.codeByte, linker.code) + codeSeg.codeOff = codeSeg.length + + //init data segment + dataSeg := &codeModule.segment.dataSeg + dataSeg.dataLen = len(linker.data) + dataSeg.noptrdataLen = len(linker.noptrdata) + dataSeg.bssLen = len(linker.bss) + dataSeg.noptrbssLen = len(linker.noptrbss) + dataSeg.length = dataSeg.dataLen + dataSeg.noptrdataLen + dataSeg.bssLen + dataSeg.noptrbssLen + dataSeg.maxLen = alignof((dataSeg.length)*2, PageSize) + dataSeg.dataOff = 0 + dataByte, err := MmapData(dataSeg.maxLen) if err != nil { + Munmap(dataSeg.dataByte) return nil, err } - - codeModule.codeByte = codeByte - codeModule.codeBase = int((*sliceHeader)(unsafe.Pointer(&codeByte)).Data) - copy(codeModule.codeByte, linker.code) - codeModule.codeOff = codeModule.codeLen - - codeModule.dataByte = dataByte - codeModule.dataBase = int((*sliceHeader)(unsafe.Pointer(&dataByte)).Data) - copy(codeModule.dataByte[codeModule.dataOff:], linker.data) - codeModule.dataOff = codeModule.dataLen - copy(codeModule.dataByte[codeModule.dataOff:], linker.noptrdata) - codeModule.dataOff += codeModule.noptrdataLen - copy(codeModule.dataByte[codeModule.dataOff:], linker.bss) - codeModule.dataOff += codeModule.bssLen - copy(codeModule.dataByte[codeModule.dataOff:], linker.noptrbss) - codeModule.dataOff += codeModule.noptrbssLen + dataSeg.dataByte = dataByte + dataSeg.dataBase = int((*sliceHeader)(unsafe.Pointer(&dataByte)).Data) + copy(dataSeg.dataByte[dataSeg.dataOff:], linker.data) + dataSeg.dataOff = dataSeg.dataLen + copy(dataSeg.dataByte[dataSeg.dataOff:], linker.noptrdata) + dataSeg.dataOff += dataSeg.noptrdataLen + copy(dataSeg.dataByte[dataSeg.dataOff:], linker.bss) + dataSeg.dataOff += dataSeg.bssLen + copy(dataSeg.dataByte[dataSeg.dataOff:], linker.noptrbss) + dataSeg.dataOff += dataSeg.noptrbssLen codeModule.stringMap = linker.stringMap @@ -517,7 +532,7 @@ func Load(linker *Linker, symPtr map[string]uintptr) (codeModule *CodeModule, er if symbolMap, err = linker.addSymbolMap(symPtr, codeModule); err == nil { if err = linker.relocate(codeModule, symbolMap, symPtr); err == nil { if err = linker.buildModule(codeModule, symbolMap); err == nil { - MakeThreadJITCodeExecutable(uintptr(codeModule.codeBase), codeModule.maxCodeLength) + MakeThreadJITCodeExecutable(uintptr(codeModule.codeBase), codeSeg.maxLen) if err = linker.doInitialize(symPtr, symbolMap); err == nil { return codeModule, err } diff --git a/obj/readobj.1.16.go b/obj/readobj.1.16.go index ce9c99a9..b4a6ed88 100644 --- a/obj/readobj.1.16.go +++ b/obj/readobj.1.16.go @@ -14,7 +14,7 @@ import ( ) func (pkg *Pkg) Symbols() error { - a, err := archive.Parse(pkg.F, false) + a, err := archive.Parse(pkg.File, false) if err != nil { return err } @@ -24,7 +24,7 @@ func (pkg *Pkg) Symbols() error { //nothing todo case archive.EntryGoObj: b := make([]byte, e.Obj.Size) - _, err := pkg.F.ReadAt(b, e.Obj.Offset) + _, err := pkg.File.ReadAt(b, e.Obj.Offset) if err != nil { return err } @@ -45,7 +45,7 @@ func (pkg *Pkg) Symbols() error { pkg.addSym(r, uint32(i), &refNames) } default: - return fmt.Errorf("Parse open %s: unrecognized archive member %s\n", pkg.F.Name(), e.Name) + return fmt.Errorf("Parse open %s: unrecognized archive member %s\n", pkg.File.Name(), e.Name) } } for _, sym := range pkg.Syms { diff --git a/obj/readobj.1.8.go b/obj/readobj.1.8.go index e3a8a884..63ae9ad3 100644 --- a/obj/readobj.1.8.go +++ b/obj/readobj.1.8.go @@ -23,12 +23,12 @@ func (r *readAtSeeker) BytesAt(offset, size int64) (bytes []byte, err error) { } func (pkg *Pkg) Symbols() error { - obj, err := goobj.Parse(pkg.F, pkg.PkgPath) + obj, err := goobj.Parse(pkg.File, pkg.PkgPath) if err != nil { return fmt.Errorf("read error: %v", err) } pkg.Arch = obj.Arch - fd := readAtSeeker{ReadSeeker: pkg.F} + fd := readAtSeeker{ReadSeeker: pkg.File} for _, sym := range obj.Syms { symbol := &ObjSymbol{} symbol.Name = sym.Name diff --git a/obj/readobj.go b/obj/readobj.go index 84a65058..f9a942bb 100644 --- a/obj/readobj.go +++ b/obj/readobj.go @@ -8,7 +8,7 @@ type Pkg struct { Syms map[string]*ObjSymbol Arch string PkgPath string - F *os.File + File *os.File CUFiles []string } diff --git a/pcdata.go b/pcvalue.go similarity index 86% rename from pcdata.go rename to pcvalue.go index 8c39c49a..a52a9692 100644 --- a/pcdata.go +++ b/pcvalue.go @@ -18,7 +18,7 @@ func findFileTab(filename string, namemap map[string]int, filetab []uint32) int3 return -1 } -func dumpPCData(b []byte, prefix string) { +func dumpPCValue(b []byte, prefix string) { fmt.Println(prefix, b) var pc uintptr val := int32(-1) @@ -34,7 +34,7 @@ func dumpPCData(b []byte, prefix string) { } } -func writePCData(p []byte, val int64, pc uint64) []byte { +func writePCValue(p []byte, val int64, pc uint64) []byte { buf := make([]byte, 32) n := binary.PutVarint(buf, val) p = append(p, buf[:n]...) @@ -58,7 +58,7 @@ func rewritePCFile(symbol *obj.ObjSymbol, linker *Linker) { break } nval := findFileTab(symbol.Func.File[val], linker.nameMap, linker.filetab) - pcfile = writePCData(pcfile, int64(nval-lastval), uint64(pc-lastpc)) + pcfile = writePCValue(pcfile, int64(nval-lastval), uint64(pc-lastpc)) lastpc = pc lastval = nval p, ok = step(p, &pc, &val, false) @@ -97,14 +97,14 @@ func updateLastPCValue(pcVals *[]byte, nval int32, npc, pcQuantum uintptr) { var ok bool p, ok = step(p, &pc, &val, pc == 0) if len(p) == 1 && p[0] == 0 && val == nval { - npcVals = writePCData(npcVals, int64(nval-lastval), uint64((npc-lastpc)/pcQuantum)) + npcVals = writePCValue(npcVals, int64(nval-lastval), uint64((npc-lastpc)/pcQuantum)) break } if !ok || len(p) == 0 { - npcVals = writePCData(npcVals, int64(nval-lastval), uint64((npc-lastpc)/pcQuantum)) + npcVals = writePCValue(npcVals, int64(nval-lastval), uint64((npc-lastpc)/pcQuantum)) break } - npcVals = writePCData(npcVals, int64(val-lastval), uint64((pc-lastpc)/pcQuantum)) + npcVals = writePCValue(npcVals, int64(val-lastval), uint64((pc-lastpc)/pcQuantum)) lastpc = pc lastval = val } diff --git a/readobj.go b/readobj.go index 3413e1a0..e6016694 100644 --- a/readobj.go +++ b/readobj.go @@ -10,7 +10,7 @@ import ( ) func Parse(f *os.File, pkgpath *string) ([]string, error) { - pkg := obj.Pkg{Syms: make(map[string]*obj.ObjSymbol, 0), F: f, PkgPath: *pkgpath} + pkg := obj.Pkg{Syms: make(map[string]*obj.ObjSymbol, 0), File: f, PkgPath: *pkgpath} symbols := make([]string, 0) if err := pkg.Symbols(); err != nil { return symbols, err @@ -51,7 +51,7 @@ func readObj(pkg *obj.Pkg, linker *Linker, cuOffset int) error { } } for _, sym := range pkg.Syms { - linker.objsymbolMap[sym.Name] = sym + linker.objSymbolMap[sym.Name] = sym } linker.initFuncs = append(linker.initFuncs, getInitFuncName(pkg.PkgPath)) return nil @@ -59,7 +59,7 @@ func readObj(pkg *obj.Pkg, linker *Linker, cuOffset int) error { func ReadObj(f *os.File, pkgpath *string) (*Linker, error) { linker := initLinker() - pkg := obj.Pkg{Syms: make(map[string]*obj.ObjSymbol, 0), F: f, PkgPath: *pkgpath} + pkg := obj.Pkg{Syms: make(map[string]*obj.ObjSymbol, 0), File: f, PkgPath: *pkgpath} if err := readObj(&pkg, linker, 0); err != nil { return nil, err } @@ -80,7 +80,7 @@ func ReadObjs(files []string, pkgPath []string) (*Linker, error) { return nil, err } defer f.Close() - pkg := obj.Pkg{Syms: make(map[string]*obj.ObjSymbol, 0), F: f, PkgPath: pkgPath[i]} + pkg := obj.Pkg{Syms: make(map[string]*obj.ObjSymbol, 0), File: f, PkgPath: pkgPath[i]} if err := readObj(&pkg, linker, cuOffset); err != nil { return nil, err } diff --git a/relocate.go b/relocate.go index 221bd4fa..a9af4782 100644 --- a/relocate.go +++ b/relocate.go @@ -153,7 +153,7 @@ func (linker *Linker) relocateADRP(mCode []byte, loc obj.Reloc, segment *segment func (linker *Linker) relocateCALL(addr uintptr, loc obj.Reloc, segment *segment, relocByte []byte, addrBase int) { byteorder := linker.Arch.ByteOrder offset := int(addr) - (addrBase + loc.Offset + loc.Size) + loc.Add - if offset > 0x7FFFFFFF || offset < -0x80000000 { + if isOverflowInt32(offset) { segment.dataOff = alignof(segment.dataOff, PtrSize) epilogueOffset := loc.Epilogue.Offset offset = (segment.codeBase + epilogueOffset) - (addrBase + loc.Offset + loc.Size) @@ -172,7 +172,7 @@ func (linker *Linker) relocateCALL(addr uintptr, loc obj.Reloc, segment *segment func (linker *Linker) relocatePCREL(addr uintptr, loc obj.Reloc, segment *segment, relocByte []byte, addrBase int) (err error) { byteorder := linker.Arch.ByteOrder offset := int(addr) - (addrBase + loc.Offset + loc.Size) + loc.Add - if offset > 0x7FFFFFFF || offset < -0x80000000 { + if isOverflowInt32(offset) { epilogueOffset := loc.Epilogue.Offset offset = (segment.codeBase + epilogueOffset) - (addrBase + loc.Offset + loc.Size) bytes := relocByte[loc.Offset-2:] @@ -248,7 +248,7 @@ func (linker *Linker) relocteCALLARM(addr uintptr, loc obj.Reloc, segment *segme add = int(signext24(int64(loc.Add&0xFFFFFF)) * 4) } offset := (int(addr) + add - (segment.codeBase + loc.Offset)) / 4 - if offset > 0x7FFFFF || offset < -0x800000 { + if isOverflowInt24(offset) { epilogueOffset := loc.Epilogue.Offset off := uint32(epilogueOffset-loc.Offset) / 4 if loc.Type == reloctype.R_CALLARM { @@ -318,7 +318,7 @@ func (linker *Linker) relocate(codeModule *CodeModule, symbolMap, symPtr map[str //nothing todo case reloctype.R_ADDROFF, reloctype.R_WEAKADDROFF: offset := int(addr) - addrBase + loc.Add - if offset > 0x7FFFFFFF || offset < -0x80000000 { + if isOverflowInt32(offset) { err = fmt.Errorf("symName:%s relocateType:%s, offset:%d is overflow!\n", sym.Name, reloctype.RelocTypeString(loc.Type), offset) } byteorder.PutUint32(relocByte[loc.Offset:], uint32(offset)) @@ -327,7 +327,7 @@ func (linker *Linker) relocate(codeModule *CodeModule, symbolMap, symPtr map[str addrBase = segment.codeBase } offset := int(addr) - addrBase + loc.Add - if offset > 0x7FFFFFFF || offset < -0x80000000 { + if isOverflowInt32(offset) { err = fmt.Errorf("symName:%s relocateType:%s, offset:%d is overflow!\n", sym.Name, reloctype.RelocTypeString(loc.Type), offset) } byteorder.PutUint32(relocByte[loc.Offset:], uint32(offset)) diff --git a/utils.go b/utils.go index 43ae2320..0aacf972 100644 --- a/utils.go +++ b/utils.go @@ -10,6 +10,20 @@ import ( "github.com/pkujhd/goloader/mmap" ) +func isOverflowInt32(offset int) bool { + if offset > 0x7FFFFFFF || offset < -0x80000000 { + return true + } + return false +} + +func isOverflowInt24(offset int) bool { + if offset > 0x7FFFFF || offset < -0x800000 { + return true + } + return false +} + //go:linkname add runtime.add func add(p unsafe.Pointer, x uintptr) unsafe.Pointer