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

     1  package emulator
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  
     7  	"github.com/dylandreimerink/gobpfld/ebpf"
     8  )
     9  
    10  var errDivByZero = errors.New("divide by zero")
    11  
    12  var _ Instruction = (*Div32)(nil)
    13  
    14  type Div32 struct {
    15  	ebpf.Div32
    16  }
    17  
    18  func (i *Div32) Clone() Instruction {
    19  	c := *i
    20  	return &c
    21  }
    22  
    23  func (i *Div32) Execute(vm *VM) error {
    24  	rv, r, err := readReg(vm, i.Dest)
    25  	if err != nil {
    26  		return err
    27  	}
    28  
    29  	if i.Value == 0 {
    30  		return errDivByZero
    31  	}
    32  
    33  	err = r.Assign(int64(int32(rv) / i.Value))
    34  	if err != nil {
    35  		return fmt.Errorf("assign value  %s: %w", i.Dest.String(), err)
    36  	}
    37  
    38  	return nil
    39  }
    40  
    41  var _ Instruction = (*Div64)(nil)
    42  
    43  type Div64 struct {
    44  	ebpf.Div64
    45  }
    46  
    47  func (i *Div64) Clone() Instruction {
    48  	c := *i
    49  	return &c
    50  }
    51  
    52  func (i *Div64) Execute(vm *VM) error {
    53  	rv, r, err := readReg(vm, i.Dest)
    54  	if err != nil {
    55  		return err
    56  	}
    57  
    58  	if i.Value == 0 {
    59  		return errDivByZero
    60  	}
    61  
    62  	err = r.Assign(rv / int64(i.Value))
    63  	if err != nil {
    64  		return fmt.Errorf("assign value  %s: %w", i.Dest.String(), err)
    65  	}
    66  
    67  	return nil
    68  }
    69  
    70  var _ Instruction = (*Div32Register)(nil)
    71  
    72  type Div32Register struct {
    73  	ebpf.Div32Register
    74  }
    75  
    76  func (i *Div32Register) Clone() Instruction {
    77  	c := *i
    78  	return &c
    79  }
    80  
    81  func (i *Div32Register) Execute(vm *VM) error {
    82  	dv, dr, err := readReg(vm, i.Dest)
    83  	if err != nil {
    84  		return err
    85  	}
    86  
    87  	sv, _, err := readReg(vm, i.Src)
    88  	if err != nil {
    89  		return err
    90  	}
    91  
    92  	if sv == 0 {
    93  		return errDivByZero
    94  	}
    95  
    96  	err = dr.Assign(int64(int32(dv) / int32(sv)))
    97  	if err != nil {
    98  		return fmt.Errorf("assign value %s: %w", i.Dest.String(), err)
    99  	}
   100  
   101  	return nil
   102  }
   103  
   104  var _ Instruction = (*Div64Register)(nil)
   105  
   106  type Div64Register struct {
   107  	ebpf.Div64Register
   108  }
   109  
   110  func (i *Div64Register) Clone() Instruction {
   111  	c := *i
   112  	return &c
   113  }
   114  
   115  func (i *Div64Register) Execute(vm *VM) error {
   116  	dv, dr, err := readReg(vm, i.Dest)
   117  	if err != nil {
   118  		return err
   119  	}
   120  
   121  	sv, _, err := readReg(vm, i.Src)
   122  	if err != nil {
   123  		return err
   124  	}
   125  
   126  	if sv == 0 {
   127  		return errDivByZero
   128  	}
   129  
   130  	err = dr.Assign(dv / sv)
   131  	if err != nil {
   132  		return fmt.Errorf("assign value %s: %w", i.Dest.String(), err)
   133  	}
   134  
   135  	return nil
   136  }