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

     1  package ebpf
     2  
     3  import "fmt"
     4  
     5  const (
     6  	// BPF_PSEUDO_MAP_FD is used in the SRC register to mark the imm value as a map file descriptor
     7  	// https://elixir.bootlin.com/linux/v5.12.4/source/include/uapi/linux/bpf.h#L376
     8  	BPF_PSEUDO_MAP_FD = 1
     9  	// BPF_PSEUDO_MAP_FD_VALUE is used in the SRC register to mark the imm value as a map value
    10  	// https://elixir.bootlin.com/linux/v5.12.4/source/include/uapi/linux/bpf.h#L385
    11  	BPF_PSEUDO_MAP_FD_VALUE = 2
    12  	// BPF_PSEUDO_BTF_ID is used in the SRC register to mark the imm value as BTF ID
    13  	// https://elixir.bootlin.com/linux/v5.12.4/source/include/uapi/linux/bpf.h#L376
    14  	BPF_PSEUDO_BTF_ID = 3
    15  )
    16  
    17  var _ Instruction = (*LoadConstant64bit)(nil)
    18  
    19  type LoadConstant64bit struct {
    20  	Dest Register
    21  	Src  Register
    22  	Val1 uint32
    23  	Val2 uint32
    24  }
    25  
    26  func (lc *LoadConstant64bit) Raw() ([]RawInstruction, error) {
    27  	return []RawInstruction{
    28  		{Op: BPF_LD | uint8(BPF_DW) | BPF_IMM, Reg: NewReg(lc.Src, lc.Dest), Imm: int32(lc.Val1)},
    29  		{Op: 0, Reg: 0, Imm: int32(lc.Val2)},
    30  	}, nil
    31  }
    32  
    33  func (lc *LoadConstant64bit) String() string {
    34  	if lc.Src == BPF_PSEUDO_MAP_FD {
    35  		return fmt.Sprintf("r%s = map fd#%d", lc.Dest, lc.Val1)
    36  	}
    37  
    38  	if lc.Src == BPF_PSEUDO_MAP_FD_VALUE {
    39  		return fmt.Sprintf("r%s = map value#%d[%d]", lc.Dest, lc.Val1, lc.Val2)
    40  	}
    41  
    42  	return fmt.Sprintf("r%s = %d ll", lc.Dest, (uint64(lc.Val2)<<32)+uint64(lc.Val1))
    43  }
    44  
    45  var _ Instruction = (*LoadMemory)(nil)
    46  
    47  type LoadMemory struct {
    48  	Src    Register
    49  	Dest   Register
    50  	Offset int16
    51  	Size   Size
    52  }
    53  
    54  func (lm *LoadMemory) Raw() ([]RawInstruction, error) {
    55  	return []RawInstruction{
    56  		{
    57  			Op:  BPF_LDX | uint8(lm.Size) | BPF_MEM,
    58  			Reg: NewReg(lm.Src, lm.Dest),
    59  			Off: lm.Offset,
    60  		},
    61  	}, nil
    62  }
    63  
    64  func (lm *LoadMemory) String() string {
    65  	sign := "+"
    66  	offset := lm.Offset
    67  	if offset < 0 {
    68  		sign = "-"
    69  		offset = -offset
    70  	}
    71  
    72  	return fmt.Sprintf("r%s = *(%s *)(r%s %s %d)", lm.Dest, lm.Size, lm.Src, sign, offset)
    73  }
    74  
    75  var _ Instruction = (*LoadSocketBuf)(nil)
    76  
    77  type LoadSocketBuf struct {
    78  	Src    Register
    79  	Size   Size
    80  	Offset int32
    81  }
    82  
    83  func (lm *LoadSocketBuf) Raw() ([]RawInstruction, error) {
    84  	return []RawInstruction{
    85  		{
    86  			Op:  BPF_IND | uint8(lm.Size) | BPF_LD,
    87  			Reg: NewReg(lm.Src, 0),
    88  			Imm: lm.Offset,
    89  		},
    90  	}, nil
    91  }
    92  
    93  func (lm *LoadSocketBuf) String() string {
    94  	sign := "+"
    95  	off := lm.Offset
    96  	if lm.Offset < 0 {
    97  		sign = "-"
    98  		off = -lm.Offset
    99  	}
   100  
   101  	return fmt.Sprintf("r0 = ntohl((%s) (((struct sk_buff *) r6)->data[r%s %s %d]))", lm.Size, lm.Src, sign, off)
   102  }
   103  
   104  var _ Instruction = (*LoadSocketBufConstant)(nil)
   105  
   106  type LoadSocketBufConstant struct {
   107  	Value int32
   108  	Size  Size
   109  }
   110  
   111  func (lm *LoadSocketBufConstant) Raw() ([]RawInstruction, error) {
   112  	return []RawInstruction{
   113  		{
   114  			Op:  BPF_ABS | uint8(lm.Size) | BPF_LD,
   115  			Imm: lm.Value,
   116  		},
   117  	}, nil
   118  }
   119  
   120  func (lm *LoadSocketBufConstant) String() string {
   121  	return fmt.Sprintf("r0 = ntohl((%s) (((struct sk_buff *) r6)->data[%d]))", lm.Size, lm.Value)
   122  }