github.com/dylandreimerink/gobpfld@v0.6.1-0.20220205171531-e79c330ad608/emulator/inst_call_bpf.go (about)

     1  package emulator
     2  
     3  import (
     4  	"github.com/dylandreimerink/gobpfld/ebpf"
     5  )
     6  
     7  var _ Instruction = (*CallBPF)(nil)
     8  
     9  type CallBPF struct {
    10  	ebpf.CallBPF
    11  }
    12  
    13  func (i *CallBPF) Clone() Instruction {
    14  	c := *i
    15  	return &c
    16  }
    17  
    18  func (i *CallBPF) Execute(vm *VM) error {
    19  	// Preserve current registers
    20  	vm.PreservedRegisters = append(vm.PreservedRegisters, vm.Registers.Clone())
    21  
    22  	// Change R10 to the next stack frame
    23  	vm.Registers.R10 = FramePointer{
    24  		Memory:   &vm.StackFrames[vm.Registers.R10.Index+1],
    25  		Index:    vm.Registers.R10.Index + 1,
    26  		Offset:   0,
    27  		Readonly: true,
    28  	}
    29  
    30  	// Wipe the stack frame in case there was any memory from earlier use
    31  	frame, ok := vm.Registers.R10.Memory.(*ValueMemory)
    32  	if !ok {
    33  		panic("r10 != *ValueMemory")
    34  	}
    35  
    36  	for i := range frame.Mapping {
    37  		frame.Mapping[i] = nil
    38  	}
    39  
    40  	// Change the program counter to the function.
    41  	vm.Registers.PC += int(i.Offset)
    42  
    43  	return nil
    44  }