// Copyright 2020 syzkaller project authors. All rights reserved. // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. package backend import ( "fmt" "github.com/google/syzkaller/sys/targets" ) func RestorePC(pc, base uint32) uint64 { return uint64(base)<<32 + uint64(pc) } func PreviousInstructionPC(target *targets.Target, pc uint64) uint64 { offset := instructionLen(target.Arch) pc -= offset // THUMB instructions are 2 or 4 bytes with low bit set. // ARM instructions are always 4 bytes. if target.Arch == targets.ARM { return pc & ^uint64(1) } return pc } func NextInstructionPC(target *targets.Target, pc uint64) uint64 { offset := instructionLen(target.Arch) pc += offset // THUMB instructions are 2 or 4 bytes with low bit set. // ARM instructions are always 4 bytes. if target.Arch == targets.ARM { return pc & ^uint64(1) } return pc } func instructionLen(arch string) uint64 { switch arch { case targets.AMD64: return 5 case targets.I386: return 5 case targets.ARM64: return 4 case targets.ARM: return 3 case targets.PPC64LE: return 4 case targets.MIPS64LE: return 8 case targets.S390x: return 6 case targets.RiscV64: return 4 case targets.TestArch64: return 0 default: panic(fmt.Sprintf("unknown arch %q", arch)) } }