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 }