github.com/dylandreimerink/gobpfld@v0.6.1-0.20220205171531-e79c330ad608/emulator/inst_store.go (about) 1 package emulator 2 3 import ( 4 "fmt" 5 6 "github.com/dylandreimerink/gobpfld/ebpf" 7 ) 8 9 var _ Instruction = (*StoreMemoryConstant)(nil) 10 11 type StoreMemoryConstant struct { 12 ebpf.StoreMemoryConstant 13 } 14 15 func (i *StoreMemoryConstant) Clone() Instruction { 16 c := *i 17 return &c 18 } 19 20 func (i *StoreMemoryConstant) Execute(vm *VM) error { 21 sv := newIMM(int64(i.Value)) 22 23 dr, err := vm.Registers.Copy(i.Dest) 24 if err != nil { 25 return fmt.Errorf("copy %s: %w", i.Dest, err) 26 } 27 28 var off int64 29 var memory Memory 30 switch dmp := dr.(type) { 31 case *MemoryPtr: 32 // Memory pointers point to the start of a memory block 33 off = dmp.Offset + int64(i.Offset) 34 memory = dmp.Memory 35 36 case *FramePointer: 37 // Frame pointers point to the end of a stack frame 38 off = int64(dmp.Memory.Size()) + dmp.Offset + int64(i.Offset) 39 memory = dmp.Memory 40 41 default: 42 return fmt.Errorf("can't store to a non-pointer register value") 43 } 44 45 err = memory.Write(int(off), sv, i.Size) 46 if err != nil { 47 return fmt.Errorf("memory write: %w", err) 48 } 49 50 return nil 51 } 52 53 var _ Instruction = (*StoreMemoryRegister)(nil) 54 55 type StoreMemoryRegister struct { 56 ebpf.StoreMemoryRegister 57 } 58 59 func (i *StoreMemoryRegister) Clone() Instruction { 60 c := *i 61 return &c 62 } 63 64 func (i *StoreMemoryRegister) Execute(vm *VM) error { 65 sr, err := vm.Registers.Get(i.Src) 66 if err != nil { 67 return fmt.Errorf("get %s: %w", i.Src.String(), err) 68 } 69 sv := sr.Copy() 70 71 dr, err := vm.Registers.Copy(i.Dest) 72 if err != nil { 73 return fmt.Errorf("copy %s: %w", i.Dest, err) 74 } 75 76 var off int64 77 var memory Memory 78 switch dmp := dr.(type) { 79 case *MemoryPtr: 80 // Memory pointers point to the start of a memory block 81 off = dmp.Offset + int64(i.Offset) 82 memory = dmp.Memory 83 84 case *FramePointer: 85 // Frame pointers point to the end of a stack frame 86 off = int64(dmp.Memory.Size()) + dmp.Offset + int64(i.Offset) 87 memory = dmp.Memory 88 89 default: 90 return fmt.Errorf("can't store to a non-pointer register value") 91 } 92 93 err = memory.Write(int(off), sv, i.Size) 94 if err != nil { 95 return fmt.Errorf("memory write: %w", err) 96 } 97 98 return nil 99 }