github.com/dylandreimerink/gobpfld@v0.6.1-0.20220205171531-e79c330ad608/emulator/inst_add.go (about) 1 package emulator 2 3 import ( 4 "fmt" 5 6 "github.com/dylandreimerink/gobpfld/ebpf" 7 ) 8 9 var _ Instruction = (*Add32)(nil) 10 11 type Add32 struct { 12 ebpf.Add32 13 } 14 15 func (i *Add32) Clone() Instruction { 16 c := *i 17 return &c 18 } 19 20 func (i *Add32) Execute(vm *VM) error { 21 rv, r, err := readReg(vm, i.Dest) 22 if err != nil { 23 return err 24 } 25 26 err = r.Assign(int64(int32(rv) + i.Value)) 27 if err != nil { 28 return fmt.Errorf("assign value %s: %w", i.Dest.String(), err) 29 } 30 31 return nil 32 } 33 34 var _ Instruction = (*Add64)(nil) 35 36 type Add64 struct { 37 ebpf.Add64 38 } 39 40 func (i *Add64) Clone() Instruction { 41 c := *i 42 return &c 43 } 44 45 func (i *Add64) Execute(vm *VM) error { 46 rv, r, err := readReg(vm, i.Dest) 47 if err != nil { 48 return err 49 } 50 51 err = r.Assign(rv + int64(i.Value)) 52 if err != nil { 53 return fmt.Errorf("assign value %s: %w", i.Dest.String(), err) 54 } 55 56 return nil 57 } 58 59 var _ Instruction = (*Add32Register)(nil) 60 61 type Add32Register struct { 62 ebpf.Add32Register 63 } 64 65 func (i *Add32Register) Clone() Instruction { 66 c := *i 67 return &c 68 } 69 70 func (i *Add32Register) Execute(vm *VM) error { 71 dv, dr, err := readReg(vm, i.Dest) 72 if err != nil { 73 return err 74 } 75 76 sv, sr, err := readReg(vm, i.Src) 77 if err != nil { 78 return err 79 } 80 81 // Edge case: if we add a pointer to a value, we want to convert the destination type into a pointer as well 82 if _, ok := sr.(PointerValue); ok { 83 scp, err := vm.Registers.Copy(i.Src) 84 if err != nil { 85 return err 86 } 87 88 err = scp.Assign(int64(int32(dv) + int32(sv))) 89 if err != nil { 90 return err 91 } 92 93 err = vm.Registers.Assign(i.Dest, scp) 94 if err != nil { 95 return err 96 } 97 return nil 98 } 99 100 err = dr.Assign(int64(int32(dv) + int32(sv))) 101 if err != nil { 102 return fmt.Errorf("assign value %s: %w", i.Dest.String(), err) 103 } 104 105 return nil 106 } 107 108 var _ Instruction = (*Add64Register)(nil) 109 110 type Add64Register struct { 111 ebpf.Add64Register 112 } 113 114 func (i *Add64Register) Clone() Instruction { 115 c := *i 116 return &c 117 } 118 119 func (i *Add64Register) Execute(vm *VM) error { 120 dv, dr, err := readReg(vm, i.Dest) 121 if err != nil { 122 return err 123 } 124 125 sv, sr, err := readReg(vm, i.Src) 126 if err != nil { 127 return err 128 } 129 130 // Edge case: if we add a pointer to a value, we want to convert the destination type into a pointer as well 131 if _, ok := sr.(PointerValue); ok { 132 scp, err := vm.Registers.Copy(i.Src) 133 if err != nil { 134 return err 135 } 136 137 err = scp.Assign(dv + sv) 138 if err != nil { 139 return err 140 } 141 142 err = vm.Registers.Assign(i.Dest, scp) 143 if err != nil { 144 return err 145 } 146 return nil 147 } 148 149 err = dr.Assign(dv + sv) 150 if err != nil { 151 return fmt.Errorf("assign value %s: %w", i.Dest.String(), err) 152 } 153 154 return nil 155 }