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  }