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

     1  package emulator
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  
     7  	"github.com/dylandreimerink/gobpfld/ebpf"
     8  )
     9  
    10  var _ Instruction = (*LoadConstant64bit)(nil)
    11  
    12  type LoadConstant64bit struct {
    13  	ebpf.LoadConstant64bit
    14  }
    15  
    16  func (i *LoadConstant64bit) Clone() Instruction {
    17  	c := *i
    18  	return &c
    19  }
    20  
    21  func (i *LoadConstant64bit) Execute(vm *VM) error {
    22  	dr, err := vm.Registers.Get(i.Dest)
    23  	if err != nil {
    24  		return fmt.Errorf("get: %w", err)
    25  	}
    26  
    27  	if i.Src == ebpf.BPF_PSEUDO_MAP_FD {
    28  		err = vm.Registers.Assign(i.Dest, newIMM(int64(i.Val1)))
    29  		if err != nil {
    30  			return fmt.Errorf("assign register: %w", err)
    31  		}
    32  
    33  		return nil
    34  	}
    35  
    36  	if i.Src == ebpf.BPF_PSEUDO_MAP_FD_VALUE {
    37  		// This is a special load instruction which will return an offset into the value of key 0 of a map.
    38  		// It is only used to access ELF data sections.
    39  
    40  		if int(i.Val1) >= len(vm.Maps) {
    41  			return fmt.Errorf("no map loaded at index '%d'", i.Val1)
    42  		}
    43  
    44  		m := vm.Maps[i.Val1]
    45  		mapValue, err := m.Lookup(&MemoryPtr{Memory: &ByteMemory{MemName: "(tmp mem)", Backing: make([]byte, 4)}})
    46  		if err != nil {
    47  			return fmt.Errorf("map lookup: %w", err)
    48  		}
    49  
    50  		mapValuePtr, ok := mapValue.(*MemoryPtr)
    51  		if !ok {
    52  			return fmt.Errorf("map lookup didn't return a memory pointer")
    53  		}
    54  
    55  		mapValuePtr.Offset = int64(i.Val2)
    56  
    57  		err = vm.Registers.Assign(i.Dest, mapValuePtr)
    58  		if err != nil {
    59  			return fmt.Errorf("assign register: %w", err)
    60  		}
    61  
    62  		return nil
    63  	}
    64  
    65  	err = dr.Assign(int64(i.Val2)<<32 + int64(i.Val1))
    66  	if err != nil {
    67  		return fmt.Errorf("assign value: %w", err)
    68  	}
    69  
    70  	return nil
    71  }
    72  
    73  var _ Instruction = (*LoadMemory)(nil)
    74  
    75  type LoadMemory struct {
    76  	ebpf.LoadMemory
    77  }
    78  
    79  func (i *LoadMemory) Clone() Instruction {
    80  	c := *i
    81  	return &c
    82  }
    83  
    84  func (i *LoadMemory) Execute(vm *VM) error {
    85  	sr, err := vm.Registers.Copy(i.Src)
    86  	if err != nil {
    87  		return fmt.Errorf("copy %s: %w", i.Dest, err)
    88  	}
    89  
    90  	var off int64
    91  	var memory Memory
    92  	switch smp := sr.(type) {
    93  	case *MemoryPtr:
    94  		// Memory pointers point to the start of a memory block
    95  		off = smp.Offset + int64(i.Offset)
    96  		memory = smp.Memory
    97  
    98  	case *FramePointer:
    99  		// Frame pointers point to the end of a stack frame
   100  		off = int64(smp.Memory.Size()) + smp.Offset + int64(i.Offset)
   101  		memory = smp.Memory
   102  
   103  	default:
   104  		return fmt.Errorf("can't read from a non-pointer register value")
   105  	}
   106  
   107  	val, err := memory.Read(int(off), i.Size)
   108  	if err != nil {
   109  		return fmt.Errorf("read from memory: %w", err)
   110  	}
   111  
   112  	err = vm.Registers.Assign(i.Dest, val)
   113  	if err != nil {
   114  		return fmt.Errorf("assign '%s': %w", i.Dest, err)
   115  	}
   116  
   117  	return nil
   118  }
   119  
   120  var _ Instruction = (*LoadSocketBuf)(nil)
   121  
   122  type LoadSocketBuf struct {
   123  	ebpf.LoadSocketBuf
   124  }
   125  
   126  func (i *LoadSocketBuf) Clone() Instruction {
   127  	c := *i
   128  	return &c
   129  }
   130  
   131  func (i *LoadSocketBuf) Execute(vm *VM) error {
   132  	return errors.New("not implemented")
   133  }
   134  
   135  var _ Instruction = (*LoadSocketBuf)(nil)
   136  
   137  type LoadSocketBufConstant struct {
   138  	ebpf.LoadSocketBufConstant
   139  }
   140  
   141  func (i *LoadSocketBufConstant) Clone() Instruction {
   142  	c := *i
   143  	return &c
   144  }
   145  
   146  func (i *LoadSocketBufConstant) Execute(vm *VM) error {
   147  	return errors.New("not implemented")
   148  }