gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/bpf/bpf_test.go (about) 1 // Copyright 2023 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package bpf 16 17 import ( 18 "testing" 19 ) 20 21 func TestEqual(t *testing.T) { 22 for _, test := range []struct { 23 name string 24 a, b Instruction 25 want bool 26 }{ 27 { 28 name: "empty instructions", 29 want: true, 30 }, 31 { 32 name: "two different invalid instructions", 33 a: Instruction{ 34 OpCode: 0xffff, 35 }, 36 b: Instruction{ 37 OpCode: 0xfffe, 38 }, 39 want: false, 40 }, 41 { 42 name: "two loads from different offsets", 43 a: Instruction{ 44 OpCode: Ld | Imm | W, 45 K: 1234, 46 }, 47 b: Instruction{ 48 OpCode: Ld | Imm | W, 49 K: 5678, 50 }, 51 want: false, 52 }, 53 { 54 name: "two loads from same offsets but different source", 55 a: Instruction{ 56 OpCode: Ld | Mem | W, 57 K: 1234, 58 }, 59 b: Instruction{ 60 OpCode: Ld | Imm | W, 61 K: 1234, 62 }, 63 want: false, 64 }, 65 { 66 name: "two loads from same offsets but different conditional jump fields", 67 a: Instruction{ 68 OpCode: Ld | Mem | W, 69 K: 1234, 70 JumpIfTrue: 12, 71 }, 72 b: Instruction{ 73 OpCode: Ld | Mem | W, 74 K: 1234, 75 }, 76 want: true, 77 }, 78 { 79 name: "two length loads", 80 a: Instruction{ 81 OpCode: Ld | Len | W, 82 K: 1234, 83 JumpIfTrue: 12, 84 }, 85 b: Instruction{ 86 OpCode: Ld | Len | W, 87 K: 5678, 88 JumpIfTrue: 99, 89 }, 90 want: true, 91 }, 92 { 93 name: "two length loads in different registers", 94 a: Instruction{ 95 OpCode: Ld | Len | W, 96 K: 1234, 97 JumpIfTrue: 12, 98 }, 99 b: Instruction{ 100 OpCode: Ldx | Len | W, 101 K: 1234, 102 JumpIfTrue: 12, 103 }, 104 want: false, 105 }, 106 { 107 name: "two stores at different offsets", 108 a: Instruction{ 109 OpCode: St, 110 K: 1234, 111 }, 112 b: Instruction{ 113 OpCode: St, 114 K: 5678, 115 }, 116 want: false, 117 }, 118 { 119 name: "two stores at same offsets but different source", 120 a: Instruction{ 121 OpCode: St, 122 K: 1234, 123 }, 124 b: Instruction{ 125 OpCode: Stx, 126 K: 1234, 127 }, 128 want: false, 129 }, 130 { 131 name: "two stores at same offsets but different conditional jump fields", 132 a: Instruction{ 133 OpCode: St, 134 K: 1234, 135 JumpIfTrue: 12, 136 }, 137 b: Instruction{ 138 OpCode: St, 139 K: 1234, 140 }, 141 want: true, 142 }, 143 { 144 name: "two negation ALUs with different other fields", 145 a: Instruction{ 146 OpCode: Alu | Neg, 147 K: 1234, 148 JumpIfTrue: 12, 149 }, 150 b: Instruction{ 151 OpCode: Alu | Neg, 152 K: 5678, 153 JumpIfTrue: 34, 154 }, 155 want: true, 156 }, 157 { 158 name: "two 'add K' ALUs with different K", 159 a: Instruction{ 160 OpCode: Alu | Add | K, 161 K: 1234, 162 JumpIfTrue: 12, 163 }, 164 b: Instruction{ 165 OpCode: Alu | Add | K, 166 K: 5678, 167 JumpIfTrue: 34, 168 }, 169 want: false, 170 }, 171 { 172 name: "two 'add X' ALUs with different K", 173 a: Instruction{ 174 OpCode: Alu | Add | X, 175 K: 1234, 176 JumpIfTrue: 12, 177 }, 178 b: Instruction{ 179 OpCode: Alu | Add | X, 180 K: 5678, 181 JumpIfTrue: 34, 182 }, 183 want: true, 184 }, 185 { 186 name: "two 'return A' instructions with different K", 187 a: Instruction{ 188 OpCode: Ret | A, 189 K: 1234, 190 JumpIfTrue: 12, 191 }, 192 b: Instruction{ 193 OpCode: Ret | A, 194 K: 5678, 195 JumpIfTrue: 34, 196 }, 197 want: true, 198 }, 199 { 200 name: "two 'return K' instructions with same K", 201 a: Instruction{ 202 OpCode: Ret | K, 203 K: 1234, 204 JumpIfTrue: 12, 205 }, 206 b: Instruction{ 207 OpCode: Ret | K, 208 K: 1234, 209 JumpIfTrue: 34, 210 }, 211 want: true, 212 }, 213 { 214 name: "two 'return K' instructions with different K", 215 a: Instruction{ 216 OpCode: Ret | K, 217 K: 1234, 218 }, 219 b: Instruction{ 220 OpCode: Ret | K, 221 K: 5678, 222 }, 223 want: false, 224 }, 225 { 226 name: "two unconditional jumps with different K", 227 a: Instruction{ 228 OpCode: Jmp | Ja, 229 K: 1234, 230 }, 231 b: Instruction{ 232 OpCode: Jmp | Ja, 233 K: 5678, 234 }, 235 want: false, 236 }, 237 { 238 name: "two unconditional jumps with same K", 239 a: Instruction{ 240 OpCode: Jmp | Ja, 241 K: 1234, 242 JumpIfTrue: 12, 243 }, 244 b: Instruction{ 245 OpCode: Jmp | Ja, 246 K: 1234, 247 JumpIfTrue: 34, 248 }, 249 want: true, 250 }, 251 { 252 name: "two conditional jumps using K with same K", 253 a: Instruction{ 254 OpCode: Jmp | Jgt | K, 255 K: 1234, 256 JumpIfTrue: 12, 257 JumpIfFalse: 21, 258 }, 259 b: Instruction{ 260 OpCode: Jmp | Jgt | K, 261 K: 1234, 262 JumpIfTrue: 12, 263 JumpIfFalse: 21, 264 }, 265 want: true, 266 }, 267 { 268 name: "two conditional jumps using K with different K", 269 a: Instruction{ 270 OpCode: Jmp | Jgt | K, 271 K: 1234, 272 JumpIfTrue: 12, 273 JumpIfFalse: 21, 274 }, 275 b: Instruction{ 276 OpCode: Jmp | Jgt | K, 277 K: 5678, 278 JumpIfTrue: 12, 279 JumpIfFalse: 21, 280 }, 281 want: false, 282 }, 283 { 284 name: "two conditional jumps using X with different K", 285 a: Instruction{ 286 OpCode: Jmp | Jgt | X, 287 K: 1234, 288 JumpIfTrue: 12, 289 JumpIfFalse: 21, 290 }, 291 b: Instruction{ 292 OpCode: Jmp | Jgt | X, 293 K: 5678, 294 JumpIfTrue: 12, 295 JumpIfFalse: 21, 296 }, 297 want: true, 298 }, 299 { 300 name: "two conditional jumps with different 'true' jump target", 301 a: Instruction{ 302 OpCode: Jmp | Jgt | X, 303 K: 1234, 304 JumpIfTrue: 12, 305 JumpIfFalse: 21, 306 }, 307 b: Instruction{ 308 OpCode: Jmp | Jgt | X, 309 K: 1234, 310 JumpIfTrue: 99, 311 JumpIfFalse: 21, 312 }, 313 want: false, 314 }, 315 { 316 name: "two conditional jumps with different 'false' jump target", 317 a: Instruction{ 318 OpCode: Jmp | Jgt | X, 319 K: 1234, 320 JumpIfTrue: 12, 321 JumpIfFalse: 21, 322 }, 323 b: Instruction{ 324 OpCode: Jmp | Jgt | X, 325 K: 1234, 326 JumpIfTrue: 12, 327 JumpIfFalse: 99, 328 }, 329 want: false, 330 }, 331 { 332 name: "two txa instructions", 333 a: Instruction{ 334 OpCode: Misc | Txa, 335 K: 1234, 336 JumpIfTrue: 12, 337 JumpIfFalse: 21, 338 }, 339 b: Instruction{ 340 OpCode: Misc | Txa, 341 K: 5678, 342 JumpIfTrue: 34, 343 JumpIfFalse: 42, 344 }, 345 want: true, 346 }, 347 { 348 name: "two tax instructions", 349 a: Instruction{ 350 OpCode: Misc | Tax, 351 K: 1234, 352 JumpIfTrue: 12, 353 JumpIfFalse: 21, 354 }, 355 b: Instruction{ 356 OpCode: Misc | Tax, 357 K: 5678, 358 JumpIfTrue: 34, 359 JumpIfFalse: 42, 360 }, 361 want: true, 362 }, 363 { 364 name: "two different misc instructions", 365 a: Instruction{ 366 OpCode: Misc | Txa, 367 K: 1234, 368 JumpIfTrue: 12, 369 JumpIfFalse: 21, 370 }, 371 b: Instruction{ 372 OpCode: Misc | Tax, 373 K: 1234, 374 JumpIfTrue: 12, 375 JumpIfFalse: 21, 376 }, 377 want: false, 378 }, 379 } { 380 t.Run(test.name, func(t *testing.T) { 381 as := test.a.String() 382 bs := test.b.String() 383 got := test.a.Equal(test.b) 384 if got != test.want { 385 t.Errorf("%v.Equal(%v) = %v, want %v", as, bs, got, test.want) 386 } 387 if reverse := test.b.Equal(test.a); reverse != got { 388 t.Errorf("%v.Equal(%v) [%v] != %v.Equal(%v) [%v]", as, bs, got, bs, as, reverse) 389 } 390 if !t.Failed() && !got && test.a == test.b { 391 t.Errorf("%v == %v, yet %v.Equal(%v) is false", as, bs, as, bs) 392 } 393 }) 394 } 395 }