Skip to content

Commit

Permalink
fix #87 rewrite R_CALL and PCRELxCALL to avoid panic 'unexpected retu…
Browse files Browse the repository at this point in the history
…rn pc 0x0' when switch stack on call instrunction
  • Loading branch information
pkujhd committed Sep 6, 2023
1 parent 00b6c09 commit f2051b2
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 8 deletions.
4 changes: 4 additions & 0 deletions asm_bytes.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ var (
x86amd64NOPcode = []byte{0x90} // NOP
x86amd64JMPLcode = []byte{0xff, 0x25, 0x00, 0x00, 0x00, 0x00} // JMPL *ADDRESS
x86amd64JMPNcode = []byte{0xE9, 0x00, 0x00, 0x00, 0x00} // JMP (PCREL offset)+4
x86amd64replaceCALLcode = []byte{
0xFF, 0x15, 0x00, 0x00, 0x00, 0x00, //CALL *(rel)rip
0xE9, 0x00, 0x00, 0x00, 0x00, //JMP (PCREL offset)+4
}
x86amd64replaceCMPLcode = []byte{
0x50, // PUSH RAX
0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // MOVABS RAX x (64 bit)
Expand Down
28 changes: 20 additions & 8 deletions relocate.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ const (
maxExtraCodeSize_ARM64_PCREL_LDST = 24
maxExtraCodeSize_PCRELxMOV = 18
maxExtraCodeSize_PCRELxCMPL = 21
maxExtraCodeSize_PCRELxCALL = 14
maxExtraCodeSize_PCRELxCALL = 11
maxExtraCodeSize_PCRELxJMP = 14
maxExtraCodeSize_CALL = 14
maxExtraCodeSize_CALL = 11
)

func expandFunc(linker *Linker, objsym *obj.ObjSymbol, symbol *obj.Sym) {
Expand Down Expand Up @@ -154,11 +154,17 @@ func (linker *Linker) relocateCALL(addr uintptr, loc obj.Reloc, segment *segment
byteorder := linker.Arch.ByteOrder
offset := int(addr) - (addrBase + loc.Offset + loc.Size) + loc.Add
if offset > 0x7FFFFFFF || offset < -0x80000000 {
segment.dataOff = alignof(segment.dataOff, PtrSize)
epilogueOffset := loc.Epilogue.Offset
offset = (segment.codeBase + epilogueOffset) - (addrBase + loc.Offset + loc.Size)
copy(segment.codeByte[epilogueOffset:], x86amd64JMPLcode)
epilogueOffset += len(x86amd64JMPLcode)
putAddressAddOffset(byteorder, segment.codeByte, &epilogueOffset, uint64(addr)+uint64(loc.Add))
relocByte[loc.Offset-1] = x86amd64JMPcode
copy(segment.codeByte[epilogueOffset:], x86amd64replaceCALLcode)
off := (segment.dataBase + segment.dataOff - segment.codeBase - epilogueOffset - 6)
byteorder.PutUint32(segment.codeByte[epilogueOffset+2:], uint32(off))
putAddressAddOffset(byteorder, segment.dataByte, &segment.dataOff, uint64(addr)+uint64(loc.Add))
epilogueOffset += len(x86amd64replaceCALLcode)
off = addrBase + loc.Offset + loc.Size - segment.codeBase - epilogueOffset
byteorder.PutUint32(segment.codeByte[epilogueOffset-4:], uint32(off))
}
byteorder.PutUint32(relocByte[loc.Offset:], uint32(offset))
}
Expand Down Expand Up @@ -202,9 +208,15 @@ func (linker *Linker) relocatePCREL(addr uintptr, loc obj.Reloc, segment *segmen
putAddress(byteorder, segment.codeByte[epilogueOffset+2:], uint64(addr)+uint64(loc.Add))
epilogueOffset += len(x86amd64replaceMOVQcode)
case x86amd64CALLcode:
copy(segment.codeByte[epilogueOffset:], x86amd64JMPLcode)
epilogueOffset += len(x86amd64JMPLcode)
putAddressAddOffset(byteorder, segment.codeByte, &epilogueOffset, uint64(addr)+uint64(loc.Add))
segment.dataOff = alignof(segment.dataOff, PtrSize)
bytes[1] = x86amd64JMPcode
copy(segment.codeByte[epilogueOffset:], x86amd64replaceCALLcode)
off := (segment.dataBase + segment.dataOff - segment.codeBase - epilogueOffset - 6)
byteorder.PutUint32(segment.codeByte[epilogueOffset+2:], uint32(off))
epilogueOffset += len(x86amd64replaceCALLcode)
putAddressAddOffset(byteorder, segment.dataByte, &segment.dataOff, uint64(addr)+uint64(loc.Add))
off = addrBase + loc.Offset + loc.Size - segment.codeBase - epilogueOffset
byteorder.PutUint32(segment.codeByte[epilogueOffset-4:], uint32(off))
case x86amd64JMPcode:
copy(segment.codeByte[epilogueOffset:], x86amd64JMPLcode)
epilogueOffset += len(x86amd64JMPLcode)
Expand Down

0 comments on commit f2051b2

Please sign in to comment.