github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/pkg/cover/backend/pc.go (about) 1 // Copyright 2020 syzkaller project authors. All rights reserved. 2 // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. 3 4 package backend 5 6 import ( 7 "fmt" 8 9 "github.com/google/syzkaller/sys/targets" 10 ) 11 12 func RestorePC(pc, base uint32) uint64 { 13 return uint64(base)<<32 + uint64(pc) 14 } 15 16 func PreviousInstructionPC(target *targets.Target, pc uint64) uint64 { 17 offset := instructionLen(target.Arch) 18 pc -= offset 19 // THUMB instructions are 2 or 4 bytes with low bit set. 20 // ARM instructions are always 4 bytes. 21 if target.Arch == targets.ARM { 22 return pc & ^uint64(1) 23 } 24 return pc 25 } 26 27 func NextInstructionPC(target *targets.Target, pc uint64) uint64 { 28 offset := instructionLen(target.Arch) 29 pc += offset 30 // THUMB instructions are 2 or 4 bytes with low bit set. 31 // ARM instructions are always 4 bytes. 32 if target.Arch == targets.ARM { 33 return pc & ^uint64(1) 34 } 35 return pc 36 } 37 38 func instructionLen(arch string) uint64 { 39 switch arch { 40 case targets.AMD64: 41 return 5 42 case targets.I386: 43 return 5 44 case targets.ARM64: 45 return 4 46 case targets.ARM: 47 return 3 48 case targets.PPC64LE: 49 return 4 50 case targets.MIPS64LE: 51 return 8 52 case targets.S390x: 53 return 6 54 case targets.RiscV64: 55 return 4 56 case targets.TestArch64: 57 return 0 58 default: 59 panic(fmt.Sprintf("unknown arch %q", arch)) 60 } 61 }