github.com/cilium/ebpf@v0.15.1-0.20240517100537-8079b37aa138/asm/jump.go (about)

     1  package asm
     2  
     3  //go:generate go run golang.org/x/tools/cmd/stringer@latest -output jump_string.go -type=JumpOp
     4  
     5  // JumpOp affect control flow.
     6  //
     7  //	msb      lsb
     8  //	+----+-+---+
     9  //	|OP  |s|cls|
    10  //	+----+-+---+
    11  type JumpOp uint8
    12  
    13  const jumpMask OpCode = 0xf0
    14  
    15  const (
    16  	// InvalidJumpOp is returned by getters when invoked
    17  	// on non branch OpCodes
    18  	InvalidJumpOp JumpOp = 0xff
    19  	// Ja jumps by offset unconditionally
    20  	Ja JumpOp = 0x00
    21  	// JEq jumps by offset if r == imm
    22  	JEq JumpOp = 0x10
    23  	// JGT jumps by offset if r > imm
    24  	JGT JumpOp = 0x20
    25  	// JGE jumps by offset if r >= imm
    26  	JGE JumpOp = 0x30
    27  	// JSet jumps by offset if r & imm
    28  	JSet JumpOp = 0x40
    29  	// JNE jumps by offset if r != imm
    30  	JNE JumpOp = 0x50
    31  	// JSGT jumps by offset if signed r > signed imm
    32  	JSGT JumpOp = 0x60
    33  	// JSGE jumps by offset if signed r >= signed imm
    34  	JSGE JumpOp = 0x70
    35  	// Call builtin or user defined function from imm
    36  	Call JumpOp = 0x80
    37  	// Exit ends execution, with value in r0
    38  	Exit JumpOp = 0x90
    39  	// JLT jumps by offset if r < imm
    40  	JLT JumpOp = 0xa0
    41  	// JLE jumps by offset if r <= imm
    42  	JLE JumpOp = 0xb0
    43  	// JSLT jumps by offset if signed r < signed imm
    44  	JSLT JumpOp = 0xc0
    45  	// JSLE jumps by offset if signed r <= signed imm
    46  	JSLE JumpOp = 0xd0
    47  )
    48  
    49  // Return emits an exit instruction.
    50  //
    51  // Requires a return value in R0.
    52  func Return() Instruction {
    53  	return Instruction{
    54  		OpCode: OpCode(JumpClass).SetJumpOp(Exit),
    55  	}
    56  }
    57  
    58  // Op returns the OpCode for a given jump source.
    59  func (op JumpOp) Op(source Source) OpCode {
    60  	return OpCode(JumpClass).SetJumpOp(op).SetSource(source)
    61  }
    62  
    63  // Imm compares 64 bit dst to 64 bit value (sign extended), and adjusts PC by offset if the condition is fulfilled.
    64  func (op JumpOp) Imm(dst Register, value int32, label string) Instruction {
    65  	return Instruction{
    66  		OpCode:   op.opCode(JumpClass, ImmSource),
    67  		Dst:      dst,
    68  		Offset:   -1,
    69  		Constant: int64(value),
    70  	}.WithReference(label)
    71  }
    72  
    73  // Imm32 compares 32 bit dst to 32 bit value, and adjusts PC by offset if the condition is fulfilled.
    74  // Requires kernel 5.1.
    75  func (op JumpOp) Imm32(dst Register, value int32, label string) Instruction {
    76  	return Instruction{
    77  		OpCode:   op.opCode(Jump32Class, ImmSource),
    78  		Dst:      dst,
    79  		Offset:   -1,
    80  		Constant: int64(value),
    81  	}.WithReference(label)
    82  }
    83  
    84  // Reg compares 64 bit dst to 64 bit src, and adjusts PC by offset if the condition is fulfilled.
    85  func (op JumpOp) Reg(dst, src Register, label string) Instruction {
    86  	return Instruction{
    87  		OpCode: op.opCode(JumpClass, RegSource),
    88  		Dst:    dst,
    89  		Src:    src,
    90  		Offset: -1,
    91  	}.WithReference(label)
    92  }
    93  
    94  // Reg32 compares 32 bit dst to 32 bit src, and adjusts PC by offset if the condition is fulfilled.
    95  // Requires kernel 5.1.
    96  func (op JumpOp) Reg32(dst, src Register, label string) Instruction {
    97  	return Instruction{
    98  		OpCode: op.opCode(Jump32Class, RegSource),
    99  		Dst:    dst,
   100  		Src:    src,
   101  		Offset: -1,
   102  	}.WithReference(label)
   103  }
   104  
   105  func (op JumpOp) opCode(class Class, source Source) OpCode {
   106  	if op == Exit || op == Call {
   107  		return InvalidOpCode
   108  	}
   109  
   110  	return OpCode(class).SetJumpOp(op).SetSource(source)
   111  }
   112  
   113  // LongJump returns a jump always instruction with a range of [-2^31, 2^31 - 1].
   114  func LongJump(label string) Instruction {
   115  	return Instruction{
   116  		OpCode:   Ja.opCode(Jump32Class, ImmSource),
   117  		Constant: -1,
   118  	}.WithReference(label)
   119  }
   120  
   121  // Label adjusts PC to the address of the label.
   122  func (op JumpOp) Label(label string) Instruction {
   123  	if op == Call {
   124  		return Instruction{
   125  			OpCode:   OpCode(JumpClass).SetJumpOp(Call),
   126  			Src:      PseudoCall,
   127  			Constant: -1,
   128  		}.WithReference(label)
   129  	}
   130  
   131  	return Instruction{
   132  		OpCode: OpCode(JumpClass).SetJumpOp(op),
   133  		Offset: -1,
   134  	}.WithReference(label)
   135  }