github.com/dylandreimerink/gobpfld@v0.6.1-0.20220205171531-e79c330ad608/emulator/inst_exit.go (about) 1 package emulator 2 3 import ( 4 "errors" 5 6 "github.com/dylandreimerink/gobpfld/ebpf" 7 ) 8 9 var _ Instruction = (*Exit)(nil) 10 11 type Exit struct { 12 ebpf.Exit 13 } 14 15 var errExit = errors.New("function/program exit") 16 17 func (i *Exit) Clone() Instruction { 18 c := *i 19 return &c 20 } 21 22 func (i *Exit) Execute(vm *VM) error { 23 // If the call stack is empty, we exit the program 24 if len(vm.PreservedRegisters) == 0 { 25 return errExit 26 } 27 28 // If there are values on the call stack, this is a return statement 29 preserved := vm.PreservedRegisters[len(vm.PreservedRegisters)-1] 30 vm.PreservedRegisters = vm.PreservedRegisters[:len(vm.PreservedRegisters)-1] 31 32 // Restore preserved Program counter and callee saved registers 33 vm.Registers.PC = preserved.PC 34 vm.Registers.R6 = preserved.R6 35 vm.Registers.R7 = preserved.R7 36 vm.Registers.R8 = preserved.R8 37 vm.Registers.R9 = preserved.R9 38 39 // Restore the previous stack frame 40 vm.Registers.R10 = FramePointer{ 41 Memory: &vm.StackFrames[vm.Registers.R10.Index-1], 42 Index: vm.Registers.R10.Index - 1, 43 Offset: 0, 44 Readonly: true, 45 } 46 47 return nil 48 }