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  }