github.com/google/syzkaller@v0.0.0-20251211124644-a066d2bc4b02/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 PreviousInstructionPC(target *targets.Target, vm string, pc uint64) uint64 { 13 if vm == targets.GVisor { 14 // gVisor coverage returns real PCs that don't need adjustment. 15 return pc 16 } 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, vm string, pc uint64) uint64 { 28 if vm == targets.GVisor { 29 return pc 30 } 31 offset := instructionLen(target.Arch) 32 pc += offset 33 // THUMB instructions are 2 or 4 bytes with low bit set. 34 // ARM instructions are always 4 bytes. 35 if target.Arch == targets.ARM { 36 return pc & ^uint64(1) 37 } 38 return pc 39 } 40 41 func instructionLen(arch string) uint64 { 42 switch arch { 43 case targets.AMD64: 44 return 5 45 case targets.I386: 46 return 5 47 case targets.ARM64: 48 return 4 49 case targets.ARM: 50 return 3 51 case targets.PPC64LE: 52 return 4 53 case targets.MIPS64LE: 54 return 8 55 case targets.S390x: 56 return 6 57 case targets.RiscV64: 58 return 4 59 case targets.TestArch64: 60 return 0 61 default: 62 panic(fmt.Sprintf("unknown arch %q", arch)) 63 } 64 }