github.com/dylandreimerink/gobpfld@v0.6.1-0.20220205171531-e79c330ad608/ebpf/decode.go (about) 1 package ebpf 2 3 import ( 4 "fmt" 5 ) 6 7 // Decode decodes a slice of raw instructions into interpreted instructions 8 func Decode(rawIns []RawInstruction) ([]Instruction, error) { 9 instructions := make([]Instruction, 0, len(rawIns)) 10 for i := 0; i < len(rawIns); i++ { 11 raw := rawIns[i] 12 op := raw.Op 13 imm := raw.Imm 14 dst := raw.GetDestReg() 15 src := raw.GetSourceReg() 16 off := raw.Off 17 18 var inst Instruction 19 20 switch op { 21 case BPF_LD | uint8(BPF_DW) | BPF_IMM: 22 if i+1 >= len(rawIns) { 23 return nil, fmt.Errorf("%d: load double word imm op code found but not enough instructions available"+ 24 " for full decoding", i) 25 } 26 27 instructions = append(instructions, &LoadConstant64bit{ 28 Dest: dst, 29 Src: src, 30 Val1: uint32(imm), 31 Val2: uint32(rawIns[i+1].Imm), 32 }) 33 34 inst = &Nop{} 35 36 i++ 37 38 case BPF_LD | BPF_ABS | uint8(BPF_W): 39 inst = &LoadSocketBufConstant{ 40 Value: imm, 41 Size: BPF_W, 42 } 43 44 case BPF_LD | BPF_ABS | uint8(BPF_H): 45 inst = &LoadSocketBufConstant{ 46 Value: imm, 47 Size: BPF_H, 48 } 49 50 case BPF_LD | BPF_ABS | uint8(BPF_B): 51 inst = &LoadSocketBufConstant{ 52 Value: imm, 53 Size: BPF_B, 54 } 55 56 case BPF_LD | BPF_ABS | uint8(BPF_DW): 57 inst = &LoadSocketBufConstant{ 58 Value: imm, 59 Size: BPF_DW, 60 } 61 62 case BPF_LD | BPF_IND | uint8(BPF_W): 63 inst = &LoadSocketBuf{ 64 Src: src, 65 Offset: imm, 66 Size: BPF_W, 67 } 68 69 case BPF_LD | BPF_IND | uint8(BPF_H): 70 inst = &LoadSocketBuf{ 71 Src: src, 72 Offset: imm, 73 Size: BPF_H, 74 } 75 76 case BPF_LD | BPF_IND | uint8(BPF_B): 77 inst = &LoadSocketBuf{ 78 Src: src, 79 Offset: imm, 80 Size: BPF_B, 81 } 82 83 case BPF_LD | BPF_IND | uint8(BPF_DW): 84 inst = &LoadSocketBuf{ 85 Src: src, 86 Offset: imm, 87 Size: BPF_DW, 88 } 89 90 case BPF_LDX | BPF_MEM | uint8(BPF_W), 91 BPF_LDX | BPF_MEM | uint8(BPF_H), 92 BPF_LDX | BPF_MEM | uint8(BPF_B), 93 BPF_LDX | BPF_MEM | uint8(BPF_DW): 94 95 inst = &LoadMemory{ 96 Src: src, 97 Dest: dst, 98 Offset: off, 99 Size: Size(op ^ (BPF_LDX | BPF_MEM)), 100 } 101 102 case BPF_ST | BPF_MEM | uint8(BPF_W), 103 BPF_ST | BPF_MEM | uint8(BPF_H), 104 BPF_ST | BPF_MEM | uint8(BPF_B), 105 BPF_ST | BPF_MEM | uint8(BPF_DW): 106 inst = &StoreMemoryConstant{ 107 Dest: dst, 108 Offset: off, 109 Size: Size(op ^ (BPF_ST | BPF_MEM)), 110 Value: imm, 111 } 112 113 case BPF_STX | BPF_MEM | uint8(BPF_W), 114 BPF_STX | BPF_MEM | uint8(BPF_H), 115 BPF_STX | BPF_MEM | uint8(BPF_B), 116 BPF_STX | BPF_MEM | uint8(BPF_DW): 117 inst = &StoreMemoryRegister{ 118 Dest: dst, 119 Src: src, 120 Offset: off, 121 Size: Size(op ^ (BPF_STX | BPF_MEM)), 122 } 123 124 case BPF_STX | BPF_ATOMIC | uint8(BPF_W), 125 BPF_STX | BPF_ATOMIC | uint8(BPF_H), 126 BPF_STX | BPF_ATOMIC | uint8(BPF_B), 127 BPF_STX | BPF_ATOMIC | uint8(BPF_DW): 128 129 switch imm { 130 case int32(BPF_ADD), int32(BPF_ADD | BPF_FETCH): 131 inst = &AtomicAdd{ 132 Src: src, 133 Dest: dst, 134 Offset: off, 135 Size: Size(op ^ (BPF_STX | BPF_ATOMIC)), 136 Fetch: imm == int32(BPF_ADD|BPF_FETCH), 137 } 138 case int32(BPF_SUB), int32(BPF_SUB | BPF_FETCH): 139 inst = &AtomicSub{ 140 Src: src, 141 Dest: dst, 142 Offset: off, 143 Size: Size(op ^ (BPF_STX | BPF_ATOMIC)), 144 Fetch: imm == int32(BPF_SUB|BPF_FETCH), 145 } 146 case int32(BPF_AND), int32(BPF_AND | BPF_FETCH): 147 inst = &AtomicAnd{ 148 Src: src, 149 Dest: dst, 150 Offset: off, 151 Size: Size(op ^ (BPF_STX | BPF_ATOMIC)), 152 Fetch: imm == int32(BPF_AND|BPF_FETCH), 153 } 154 case int32(BPF_OR), int32(BPF_OR | BPF_FETCH): 155 inst = &AtomicOr{ 156 Src: src, 157 Dest: dst, 158 Offset: off, 159 Size: Size(op ^ (BPF_STX | BPF_ATOMIC)), 160 Fetch: imm == int32(BPF_OR|BPF_FETCH), 161 } 162 case int32(BPF_XOR), int32(BPF_XOR | BPF_FETCH): 163 inst = &AtomicXor{ 164 Src: src, 165 Dest: dst, 166 Offset: off, 167 Size: Size(op ^ (BPF_STX | BPF_ATOMIC)), 168 Fetch: imm == int32(BPF_XOR|BPF_FETCH), 169 } 170 case int32(BPF_XCHG): 171 inst = &AtomicExchange{ 172 Src: src, 173 Dest: dst, 174 Offset: off, 175 Size: Size(op ^ (BPF_STX | BPF_ATOMIC)), 176 } 177 case int32(BPF_CMPXCHG): 178 inst = &AtomicCompareAndExchange{ 179 Src: src, 180 Dest: dst, 181 Offset: off, 182 Size: Size(op ^ (BPF_STX | BPF_ATOMIC)), 183 } 184 } 185 186 case BPF_ALU | BPF_K | BPF_ADD: 187 inst = &Add32{ 188 Dest: dst, 189 Value: imm, 190 } 191 192 case BPF_ALU64 | BPF_K | BPF_ADD: 193 inst = &Add64{ 194 Dest: dst, 195 Value: imm, 196 } 197 198 case BPF_ALU | BPF_X | BPF_ADD: 199 inst = &Add32Register{ 200 Dest: dst, 201 Src: src, 202 } 203 204 case BPF_ALU64 | BPF_X | BPF_ADD: 205 inst = &Add64Register{ 206 Dest: dst, 207 Src: src, 208 } 209 210 // 211 212 case BPF_ALU | BPF_K | BPF_SUB: 213 inst = &Sub32{ 214 Dest: dst, 215 Value: imm, 216 } 217 218 case BPF_ALU64 | BPF_K | BPF_SUB: 219 inst = &Sub64{ 220 Dest: dst, 221 Value: imm, 222 } 223 224 case BPF_ALU | BPF_X | BPF_SUB: 225 inst = &Sub32Register{ 226 Dest: dst, 227 Src: src, 228 } 229 230 case BPF_ALU64 | BPF_X | BPF_SUB: 231 inst = &Sub64Register{ 232 Dest: dst, 233 Src: src, 234 } 235 236 // 237 238 case BPF_ALU | BPF_K | BPF_MUL: 239 inst = &Mul32{ 240 Dest: dst, 241 Value: imm, 242 } 243 244 case BPF_ALU64 | BPF_K | BPF_MUL: 245 inst = &Mul64{ 246 Dest: dst, 247 Value: imm, 248 } 249 250 case BPF_ALU | BPF_X | BPF_MUL: 251 inst = &Mul32Register{ 252 Dest: dst, 253 Src: src, 254 } 255 256 case BPF_ALU64 | BPF_X | BPF_MUL: 257 inst = &Mul64Register{ 258 Dest: dst, 259 Src: src, 260 } 261 262 // 263 264 case BPF_ALU | BPF_K | BPF_DIV: 265 inst = &Div32{ 266 Dest: dst, 267 Value: imm, 268 } 269 270 case BPF_ALU64 | BPF_K | BPF_DIV: 271 inst = &Div64{ 272 Dest: dst, 273 Value: imm, 274 } 275 276 case BPF_ALU | BPF_X | BPF_DIV: 277 inst = &Div32Register{ 278 Dest: dst, 279 Src: src, 280 } 281 282 case BPF_ALU64 | BPF_X | BPF_DIV: 283 inst = &Div64Register{ 284 Dest: dst, 285 Src: src, 286 } 287 288 // 289 290 case BPF_ALU | BPF_K | BPF_OR: 291 inst = &Or32{ 292 Dest: dst, 293 Value: imm, 294 } 295 296 case BPF_ALU64 | BPF_K | BPF_OR: 297 inst = &Or64{ 298 Dest: dst, 299 Value: imm, 300 } 301 302 case BPF_ALU | BPF_X | BPF_OR: 303 inst = &Or32Register{ 304 Dest: dst, 305 Src: src, 306 } 307 308 case BPF_ALU64 | BPF_X | BPF_OR: 309 inst = &Or64Register{ 310 Dest: dst, 311 Src: src, 312 } 313 314 // 315 316 case BPF_ALU | BPF_K | BPF_AND: 317 inst = &And32{ 318 Dest: dst, 319 Value: imm, 320 } 321 322 case BPF_ALU64 | BPF_K | BPF_AND: 323 inst = &And64{ 324 Dest: dst, 325 Value: imm, 326 } 327 328 case BPF_ALU | BPF_X | BPF_AND: 329 inst = &And32Register{ 330 Dest: dst, 331 Src: src, 332 } 333 334 case BPF_ALU64 | BPF_X | BPF_AND: 335 inst = &And64Register{ 336 Dest: dst, 337 Src: src, 338 } 339 340 // 341 342 case BPF_ALU | BPF_K | BPF_LSH: 343 inst = &Lsh32{ 344 Dest: dst, 345 Value: imm, 346 } 347 348 case BPF_ALU64 | BPF_K | BPF_LSH: 349 inst = &Lsh64{ 350 Dest: dst, 351 Value: imm, 352 } 353 354 case BPF_ALU | BPF_X | BPF_LSH: 355 inst = &Lsh32Register{ 356 Dest: dst, 357 Src: src, 358 } 359 360 case BPF_ALU64 | BPF_X | BPF_LSH: 361 inst = &Lsh64Register{ 362 Dest: dst, 363 Src: src, 364 } 365 366 // 367 368 case BPF_ALU | BPF_K | BPF_RSH: 369 inst = &Rsh32{ 370 Dest: dst, 371 Value: imm, 372 } 373 374 case BPF_ALU64 | BPF_K | BPF_RSH: 375 inst = &Rsh64{ 376 Dest: dst, 377 Value: imm, 378 } 379 380 case BPF_ALU | BPF_X | BPF_RSH: 381 inst = &Rsh32Register{ 382 Dest: dst, 383 Src: src, 384 } 385 386 case BPF_ALU64 | BPF_X | BPF_RSH: 387 inst = &Rsh64Register{ 388 Dest: dst, 389 Src: src, 390 } 391 392 // 393 394 case BPF_ALU | BPF_NEG: 395 inst = &Neg32{ 396 Dest: dst, 397 } 398 399 case BPF_ALU64 | BPF_NEG: 400 inst = &Neg64{ 401 Dest: dst, 402 } 403 404 // 405 406 case BPF_ALU | BPF_K | BPF_MOD: 407 inst = &Mod32{ 408 Dest: dst, 409 Value: imm, 410 } 411 412 case BPF_ALU64 | BPF_K | BPF_MOD: 413 inst = &Mod64{ 414 Dest: dst, 415 Value: imm, 416 } 417 418 case BPF_ALU | BPF_X | BPF_MOD: 419 inst = &Mod32Register{ 420 Dest: dst, 421 Src: src, 422 } 423 424 case BPF_ALU64 | BPF_X | BPF_MOD: 425 inst = &Mod64Register{ 426 Dest: dst, 427 Src: src, 428 } 429 430 // 431 432 case BPF_ALU | BPF_K | BPF_XOR: 433 inst = &Xor32{ 434 Dest: dst, 435 Value: imm, 436 } 437 438 case BPF_ALU64 | BPF_K | BPF_XOR: 439 inst = &Xor64{ 440 Dest: dst, 441 Value: imm, 442 } 443 444 case BPF_ALU | BPF_X | BPF_XOR: 445 inst = &Xor32Register{ 446 Dest: dst, 447 Src: src, 448 } 449 450 case BPF_ALU64 | BPF_X | BPF_XOR: 451 inst = &Xor64Register{ 452 Dest: dst, 453 Src: src, 454 } 455 456 // 457 458 case BPF_ALU | BPF_K | BPF_MOV: 459 inst = &Mov32{ 460 Dest: dst, 461 Value: imm, 462 } 463 464 case BPF_ALU64 | BPF_K | BPF_MOV: 465 inst = &Mov64{ 466 Dest: dst, 467 Value: imm, 468 } 469 470 case BPF_ALU | BPF_X | BPF_MOV: 471 inst = &Mov32Register{ 472 Dest: dst, 473 Src: src, 474 } 475 476 case BPF_ALU64 | BPF_X | BPF_MOV: 477 inst = &Mov64Register{ 478 Dest: dst, 479 Src: src, 480 } 481 482 // 483 484 case BPF_ALU | BPF_K | BPF_ARSH: 485 inst = &ARSH32{ 486 Dest: dst, 487 Value: imm, 488 } 489 490 case BPF_ALU64 | BPF_K | BPF_ARSH: 491 inst = &ARSH64{ 492 Dest: dst, 493 Value: imm, 494 } 495 496 case BPF_ALU | BPF_X | BPF_ARSH: 497 inst = &ARSH32Register{ 498 Dest: dst, 499 Src: src, 500 } 501 502 case BPF_ALU64 | BPF_X | BPF_ARSH: 503 inst = &ARSH64Register{ 504 Dest: dst, 505 Src: src, 506 } 507 508 // 509 510 case BPF_ALU | BPF_END | BPF_TO_LE: 511 switch imm { 512 case 16: 513 inst = &End16ToLE{ 514 Dest: dst, 515 } 516 case 32: 517 inst = &End32ToLE{ 518 Dest: dst, 519 } 520 case 64: 521 inst = &End64ToLE{ 522 Dest: dst, 523 } 524 } 525 526 case BPF_ALU | BPF_END | BPF_TO_BE: 527 switch imm { 528 case 16: 529 inst = &End16ToBE{ 530 Dest: dst, 531 } 532 case 32: 533 inst = &End32ToBE{ 534 Dest: dst, 535 } 536 case 64: 537 inst = &End64ToBE{ 538 Dest: dst, 539 } 540 } 541 542 // 543 544 case BPF_JMP | BPF_JA: 545 inst = &Jump{ 546 Offset: off, 547 } 548 549 // 550 551 case BPF_JMP | BPF_K | BPF_JEQ: 552 inst = &JumpEqual{ 553 Dest: dst, 554 Offset: off, 555 Value: imm, 556 } 557 558 case BPF_JMP32 | BPF_K | BPF_JEQ: 559 inst = &JumpEqual32{ 560 Dest: dst, 561 Offset: off, 562 Value: imm, 563 } 564 565 case BPF_JMP | BPF_X | BPF_JEQ: 566 inst = &JumpEqualRegister{ 567 Dest: dst, 568 Src: src, 569 Offset: off, 570 } 571 572 case BPF_JMP32 | BPF_X | BPF_JEQ: 573 inst = &JumpEqualRegister32{ 574 Dest: dst, 575 Src: src, 576 Offset: off, 577 } 578 579 // 580 581 case BPF_JMP | BPF_K | BPF_JGT: 582 inst = &JumpGreaterThan{ 583 Dest: dst, 584 Offset: off, 585 Value: imm, 586 } 587 588 case BPF_JMP32 | BPF_K | BPF_JGT: 589 inst = &JumpGreaterThan32{ 590 Dest: dst, 591 Offset: off, 592 Value: imm, 593 } 594 595 case BPF_JMP | BPF_X | BPF_JGT: 596 inst = &JumpGreaterThanRegister{ 597 Dest: dst, 598 Src: src, 599 Offset: off, 600 } 601 602 case BPF_JMP32 | BPF_X | BPF_JGT: 603 inst = &JumpGreaterThanRegister32{ 604 Dest: dst, 605 Src: src, 606 Offset: off, 607 } 608 609 // 610 611 case BPF_JMP | BPF_K | BPF_JGE: 612 inst = &JumpGreaterThanEqual{ 613 Dest: dst, 614 Offset: off, 615 Value: imm, 616 } 617 618 case BPF_JMP32 | BPF_K | BPF_JGE: 619 inst = &JumpGreaterThanEqual32{ 620 Dest: dst, 621 Offset: off, 622 Value: imm, 623 } 624 625 case BPF_JMP | BPF_X | BPF_JGE: 626 inst = &JumpGreaterThanEqualRegister{ 627 Dest: dst, 628 Src: src, 629 Offset: off, 630 } 631 632 case BPF_JMP32 | BPF_X | BPF_JGE: 633 inst = &JumpGreaterThanEqualRegister32{ 634 Dest: dst, 635 Src: src, 636 Offset: off, 637 } 638 639 // 640 641 case BPF_JMP | BPF_K | BPF_JSET: 642 inst = &JumpAnd{ 643 Dest: dst, 644 Offset: off, 645 Value: imm, 646 } 647 648 case BPF_JMP32 | BPF_K | BPF_JSET: 649 inst = &JumpAnd32{ 650 Dest: dst, 651 Offset: off, 652 Value: imm, 653 } 654 655 case BPF_JMP | BPF_X | BPF_JSET: 656 inst = &JumpAndRegister{ 657 Dest: dst, 658 Src: src, 659 Offset: off, 660 } 661 662 case BPF_JMP32 | BPF_X | BPF_JSET: 663 inst = &JumpAndRegister32{ 664 Dest: dst, 665 Src: src, 666 Offset: off, 667 } 668 669 // 670 671 case BPF_JMP | BPF_K | BPF_JNE: 672 inst = &JumpNotEqual{ 673 Dest: dst, 674 Offset: off, 675 Value: imm, 676 } 677 678 case BPF_JMP32 | BPF_K | BPF_JNE: 679 inst = &JumpNotEqual32{ 680 Dest: dst, 681 Offset: off, 682 Value: imm, 683 } 684 685 case BPF_JMP | BPF_X | BPF_JNE: 686 inst = &JumpNotEqualRegister{ 687 Dest: dst, 688 Src: src, 689 Offset: off, 690 } 691 692 case BPF_JMP32 | BPF_X | BPF_JNE: 693 inst = &JumpNotEqualRegister32{ 694 Dest: dst, 695 Src: src, 696 Offset: off, 697 } 698 699 // 700 701 case BPF_JMP | BPF_K | BPF_JSGT: 702 inst = &JumpSignedGreaterThan{ 703 Dest: dst, 704 Offset: off, 705 Value: imm, 706 } 707 708 case BPF_JMP32 | BPF_K | BPF_JSGT: 709 inst = &JumpSignedGreaterThan32{ 710 Dest: dst, 711 Offset: off, 712 Value: imm, 713 } 714 715 case BPF_JMP | BPF_X | BPF_JSGT: 716 inst = &JumpSignedGreaterThanRegister{ 717 Dest: dst, 718 Src: src, 719 Offset: off, 720 } 721 722 case BPF_JMP32 | BPF_X | BPF_JSGT: 723 inst = &JumpSignedGreaterThanRegister32{ 724 Dest: dst, 725 Src: src, 726 Offset: off, 727 } 728 729 // 730 731 case BPF_JMP | BPF_K | BPF_JSGE: 732 inst = &JumpSignedGreaterThanOrEqual{ 733 Dest: dst, 734 Offset: off, 735 Value: imm, 736 } 737 738 case BPF_JMP32 | BPF_K | BPF_JSGE: 739 inst = &JumpSignedGreaterThanOrEqual32{ 740 Dest: dst, 741 Offset: off, 742 Value: imm, 743 } 744 745 case BPF_JMP | BPF_X | BPF_JSGE: 746 inst = &JumpSignedGreaterThanOrEqualRegister{ 747 Dest: dst, 748 Src: src, 749 Offset: off, 750 } 751 752 case BPF_JMP32 | BPF_X | BPF_JSGE: 753 inst = &JumpSignedGreaterThanOrEqualRegister32{ 754 Dest: dst, 755 Src: src, 756 Offset: off, 757 } 758 759 // 760 761 case BPF_JMP | BPF_CALL: 762 763 if src == PSEUDO_CALL { 764 inst = &CallBPF{ 765 Offset: imm, 766 } 767 } else { 768 inst = &CallHelper{ 769 Function: imm, 770 } 771 } 772 773 case BPF_JMP | BPF_CALLX: 774 775 inst = &CallHelperIndirect{ 776 Register: Register(imm), 777 } 778 779 // 780 781 case BPF_JMP | BPF_EXIT: 782 inst = &Exit{} 783 784 // 785 786 case BPF_JMP | BPF_K | BPF_JLT: 787 inst = &JumpSmallerThan{ 788 Dest: dst, 789 Offset: off, 790 Value: imm, 791 } 792 793 case BPF_JMP32 | BPF_K | BPF_JLT: 794 inst = &JumpSmallerThan32{ 795 Dest: dst, 796 Offset: off, 797 Value: imm, 798 } 799 800 case BPF_JMP | BPF_X | BPF_JLT: 801 inst = &JumpSmallerThanRegister{ 802 Dest: dst, 803 Src: src, 804 Offset: off, 805 } 806 807 case BPF_JMP32 | BPF_X | BPF_JLT: 808 inst = &JumpSmallerThanRegister32{ 809 Dest: dst, 810 Src: src, 811 Offset: off, 812 } 813 814 // 815 816 case BPF_JMP | BPF_K | BPF_JLE: 817 inst = &JumpSmallerThanEqual{ 818 Dest: dst, 819 Offset: off, 820 Value: imm, 821 } 822 823 case BPF_JMP32 | BPF_K | BPF_JLE: 824 inst = &JumpSmallerThanEqual32{ 825 Dest: dst, 826 Offset: off, 827 Value: imm, 828 } 829 830 case BPF_JMP | BPF_X | BPF_JLE: 831 inst = &JumpSmallerThanEqualRegister{ 832 Dest: dst, 833 Src: src, 834 Offset: off, 835 } 836 837 case BPF_JMP32 | BPF_X | BPF_JLE: 838 inst = &JumpSmallerThanEqualRegister32{ 839 Dest: dst, 840 Src: src, 841 Offset: off, 842 } 843 844 // 845 846 case BPF_JMP | BPF_K | BPF_JSLT: 847 inst = &JumpSignedSmallerThan{ 848 Dest: dst, 849 Offset: off, 850 Value: imm, 851 } 852 853 case BPF_JMP32 | BPF_K | BPF_JSLT: 854 inst = &JumpSignedSmallerThan32{ 855 Dest: dst, 856 Offset: off, 857 Value: imm, 858 } 859 860 case BPF_JMP | BPF_X | BPF_JSLT: 861 inst = &JumpSignedSmallerThanRegister{ 862 Dest: dst, 863 Src: src, 864 Offset: off, 865 } 866 867 case BPF_JMP32 | BPF_X | BPF_JSLT: 868 inst = &JumpSignedSmallerThanRegister32{ 869 Dest: dst, 870 Src: src, 871 Offset: off, 872 } 873 874 // 875 876 case BPF_JMP | BPF_K | BPF_JSLE: 877 inst = &JumpSignedSmallerThanOrEqual{ 878 Dest: dst, 879 Offset: off, 880 Value: imm, 881 } 882 883 case BPF_JMP32 | BPF_K | BPF_JSLE: 884 inst = &JumpSignedSmallerThanOrEqual32{ 885 Dest: dst, 886 Offset: off, 887 Value: imm, 888 } 889 890 case BPF_JMP | BPF_X | BPF_JSLE: 891 inst = &JumpSignedSmallerThanOrEqualRegister{ 892 Dest: dst, 893 Src: src, 894 Offset: off, 895 } 896 897 case BPF_JMP32 | BPF_X | BPF_JSLE: 898 inst = &JumpSignedSmallerThanOrEqualRegister32{ 899 Dest: dst, 900 Src: src, 901 Offset: off, 902 } 903 } 904 905 if inst != nil { 906 instructions = append(instructions, inst) 907 continue 908 } 909 910 return nil, fmt.Errorf( 911 "unable to decode raw instruction, inst: %d, op: %2x, src: %s, dst: %s, off: %4x, imm: %8x", 912 i, op, src, dst, off, imm, 913 ) 914 } 915 916 return instructions, nil 917 }