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  }