github.com/cilium/ebpf@v0.15.1-0.20240517100537-8079b37aa138/asm/load_store.go (about) 1 package asm 2 3 //go:generate go run golang.org/x/tools/cmd/stringer@latest -output load_store_string.go -type=Mode,Size 4 5 // Mode for load and store operations 6 // 7 // msb lsb 8 // +---+--+---+ 9 // |MDE|sz|cls| 10 // +---+--+---+ 11 type Mode uint8 12 13 const modeMask OpCode = 0xe0 14 15 const ( 16 // InvalidMode is returned by getters when invoked 17 // on non load / store OpCodes 18 InvalidMode Mode = 0xff 19 // ImmMode - immediate value 20 ImmMode Mode = 0x00 21 // AbsMode - immediate value + offset 22 AbsMode Mode = 0x20 23 // IndMode - indirect (imm+src) 24 IndMode Mode = 0x40 25 // MemMode - load from memory 26 MemMode Mode = 0x60 27 // MemSXMode - load from memory, sign extension 28 MemSXMode Mode = 0x80 29 // XAddMode - add atomically across processors. 30 XAddMode Mode = 0xc0 31 ) 32 33 // Size of load and store operations 34 // 35 // msb lsb 36 // +---+--+---+ 37 // |mde|SZ|cls| 38 // +---+--+---+ 39 type Size uint8 40 41 const sizeMask OpCode = 0x18 42 43 const ( 44 // InvalidSize is returned by getters when invoked 45 // on non load / store OpCodes 46 InvalidSize Size = 0xff 47 // DWord - double word; 64 bits 48 DWord Size = 0x18 49 // Word - word; 32 bits 50 Word Size = 0x00 51 // Half - half-word; 16 bits 52 Half Size = 0x08 53 // Byte - byte; 8 bits 54 Byte Size = 0x10 55 ) 56 57 // Sizeof returns the size in bytes. 58 func (s Size) Sizeof() int { 59 switch s { 60 case DWord: 61 return 8 62 case Word: 63 return 4 64 case Half: 65 return 2 66 case Byte: 67 return 1 68 default: 69 return -1 70 } 71 } 72 73 // LoadMemOp returns the OpCode to load a value of given size from memory. 74 func LoadMemOp(size Size) OpCode { 75 return OpCode(LdXClass).SetMode(MemMode).SetSize(size) 76 } 77 78 // LoadMemSXOp returns the OpCode to load a value of given size from memory sign extended. 79 func LoadMemSXOp(size Size) OpCode { 80 return OpCode(LdXClass).SetMode(MemSXMode).SetSize(size) 81 } 82 83 // LoadMem emits `dst = *(size *)(src + offset)`. 84 func LoadMem(dst, src Register, offset int16, size Size) Instruction { 85 return Instruction{ 86 OpCode: LoadMemOp(size), 87 Dst: dst, 88 Src: src, 89 Offset: offset, 90 } 91 } 92 93 // LoadMemSX emits `dst = *(size *)(src + offset)` but sign extends dst. 94 func LoadMemSX(dst, src Register, offset int16, size Size) Instruction { 95 if size == DWord { 96 return Instruction{OpCode: InvalidOpCode} 97 } 98 99 return Instruction{ 100 OpCode: LoadMemSXOp(size), 101 Dst: dst, 102 Src: src, 103 Offset: offset, 104 } 105 } 106 107 // LoadImmOp returns the OpCode to load an immediate of given size. 108 // 109 // As of kernel 4.20, only DWord size is accepted. 110 func LoadImmOp(size Size) OpCode { 111 return OpCode(LdClass).SetMode(ImmMode).SetSize(size) 112 } 113 114 // LoadImm emits `dst = (size)value`. 115 // 116 // As of kernel 4.20, only DWord size is accepted. 117 func LoadImm(dst Register, value int64, size Size) Instruction { 118 return Instruction{ 119 OpCode: LoadImmOp(size), 120 Dst: dst, 121 Constant: value, 122 } 123 } 124 125 // LoadMapPtr stores a pointer to a map in dst. 126 func LoadMapPtr(dst Register, fd int) Instruction { 127 if fd < 0 { 128 return Instruction{OpCode: InvalidOpCode} 129 } 130 131 return Instruction{ 132 OpCode: LoadImmOp(DWord), 133 Dst: dst, 134 Src: PseudoMapFD, 135 Constant: int64(uint32(fd)), 136 } 137 } 138 139 // LoadMapValue stores a pointer to the value at a certain offset of a map. 140 func LoadMapValue(dst Register, fd int, offset uint32) Instruction { 141 if fd < 0 { 142 return Instruction{OpCode: InvalidOpCode} 143 } 144 145 fdAndOffset := (uint64(offset) << 32) | uint64(uint32(fd)) 146 return Instruction{ 147 OpCode: LoadImmOp(DWord), 148 Dst: dst, 149 Src: PseudoMapValue, 150 Constant: int64(fdAndOffset), 151 } 152 } 153 154 // LoadIndOp returns the OpCode for loading a value of given size from an sk_buff. 155 func LoadIndOp(size Size) OpCode { 156 return OpCode(LdClass).SetMode(IndMode).SetSize(size) 157 } 158 159 // LoadInd emits `dst = ntoh(*(size *)(((sk_buff *)R6)->data + src + offset))`. 160 func LoadInd(dst, src Register, offset int32, size Size) Instruction { 161 return Instruction{ 162 OpCode: LoadIndOp(size), 163 Dst: dst, 164 Src: src, 165 Constant: int64(offset), 166 } 167 } 168 169 // LoadAbsOp returns the OpCode for loading a value of given size from an sk_buff. 170 func LoadAbsOp(size Size) OpCode { 171 return OpCode(LdClass).SetMode(AbsMode).SetSize(size) 172 } 173 174 // LoadAbs emits `r0 = ntoh(*(size *)(((sk_buff *)R6)->data + offset))`. 175 func LoadAbs(offset int32, size Size) Instruction { 176 return Instruction{ 177 OpCode: LoadAbsOp(size), 178 Dst: R0, 179 Constant: int64(offset), 180 } 181 } 182 183 // StoreMemOp returns the OpCode for storing a register of given size in memory. 184 func StoreMemOp(size Size) OpCode { 185 return OpCode(StXClass).SetMode(MemMode).SetSize(size) 186 } 187 188 // StoreMem emits `*(size *)(dst + offset) = src` 189 func StoreMem(dst Register, offset int16, src Register, size Size) Instruction { 190 return Instruction{ 191 OpCode: StoreMemOp(size), 192 Dst: dst, 193 Src: src, 194 Offset: offset, 195 } 196 } 197 198 // StoreImmOp returns the OpCode for storing an immediate of given size in memory. 199 func StoreImmOp(size Size) OpCode { 200 return OpCode(StClass).SetMode(MemMode).SetSize(size) 201 } 202 203 // StoreImm emits `*(size *)(dst + offset) = value`. 204 func StoreImm(dst Register, offset int16, value int64, size Size) Instruction { 205 return Instruction{ 206 OpCode: StoreImmOp(size), 207 Dst: dst, 208 Offset: offset, 209 Constant: value, 210 } 211 } 212 213 // StoreXAddOp returns the OpCode to atomically add a register to a value in memory. 214 func StoreXAddOp(size Size) OpCode { 215 return OpCode(StXClass).SetMode(XAddMode).SetSize(size) 216 } 217 218 // StoreXAdd atomically adds src to *dst. 219 func StoreXAdd(dst, src Register, size Size) Instruction { 220 return Instruction{ 221 OpCode: StoreXAddOp(size), 222 Dst: dst, 223 Src: src, 224 } 225 }