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  }