Blame libcpu/bpf_disasm.c

Packit Service 97d2fb
/* Disassembler for BPF.
Packit Service 97d2fb
   Copyright (C) 2016, 2018 Red Hat, Inc.
Packit Service 97d2fb
   This file is part of elfutils.
Packit Service 97d2fb
Packit Service 97d2fb
   This file is free software; you can redistribute it and/or modify
Packit Service 97d2fb
   it under the terms of either
Packit Service 97d2fb
Packit Service 97d2fb
     * the GNU Lesser General Public License as published by the Free
Packit Service 97d2fb
       Software Foundation; either version 3 of the License, or (at
Packit Service 97d2fb
       your option) any later version
Packit Service 97d2fb
Packit Service 97d2fb
   or
Packit Service 97d2fb
Packit Service 97d2fb
     * the GNU General Public License as published by the Free
Packit Service 97d2fb
       Software Foundation; either version 2 of the License, or (at
Packit Service 97d2fb
       your option) any later version
Packit Service 97d2fb
Packit Service 97d2fb
   or both in parallel, as here.
Packit Service 97d2fb
Packit Service 97d2fb
   elfutils is distributed in the hope that it will be useful, but
Packit Service 97d2fb
   WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 97d2fb
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 97d2fb
   General Public License for more details.
Packit Service 97d2fb
Packit Service 97d2fb
   You should have received copies of the GNU General Public License and
Packit Service 97d2fb
   the GNU Lesser General Public License along with this program.  If
Packit Service 97d2fb
   not, see <http://www.gnu.org/licenses/>.  */
Packit Service 97d2fb
Packit Service 97d2fb
#ifdef HAVE_CONFIG_H
Packit Service 97d2fb
# include <config.h>
Packit Service 97d2fb
#endif
Packit Service 97d2fb
Packit Service 97d2fb
#include <assert.h>
Packit Service 97d2fb
#include <string.h>
Packit Service 97d2fb
#include <stdio.h>
Packit Service 97d2fb
#include <gelf.h>
Packit Service 97d2fb
#include <inttypes.h>
Packit Service 97d2fb
#include "bpf.h"
Packit Service 97d2fb
Packit Service 97d2fb
#include "../libelf/common.h"
Packit Service 97d2fb
#include "../libebl/libeblP.h"
Packit Service 97d2fb
Packit Service 97d2fb
static const char class_string[8][8] = {
Packit Service 97d2fb
  [BPF_LD]    = "ld",
Packit Service 97d2fb
  [BPF_LDX]   = "ldx",
Packit Service 97d2fb
  [BPF_ST]    = "st",
Packit Service 97d2fb
  [BPF_STX]   = "stx",
Packit Service 97d2fb
  [BPF_ALU]   = "alu",
Packit Service 97d2fb
  [BPF_JMP]   = "jmp",
Packit Service 97d2fb
  [BPF_RET]   = "6",		/* completely unused in ebpf */
Packit Service 97d2fb
  [BPF_ALU64] = "alu64",
Packit Service 97d2fb
};
Packit Service 97d2fb
Packit Service 97d2fb
Packit Service 97d2fb
#define REG(N)		"r%" #N "$d"
Packit Service 97d2fb
#define REGU(N)		"(u32)" REG(N)
Packit Service 97d2fb
#define REGS(N)		"(s64)" REG(N)
Packit Service 97d2fb
Packit Service 97d2fb
#define IMMS(N)		"%" #N "$d"
Packit Service 97d2fb
#define IMMX(N)		"%" #N "$#x"
Packit Service 97d2fb
Packit Service 97d2fb
#define OFF(N)		"%" #N "$+d"
Packit Service 97d2fb
#define JMP(N)		"%" #N "$#x"
Packit Service 97d2fb
Packit Service 97d2fb
#define A32(O, S)	REG(1) " = " REGU(1) " " #O " " S
Packit Service 97d2fb
#define A64(O, S)	REG(1) " " #O "= " S
Packit Service 97d2fb
#define J64(D, O, S)	"if " D " " #O " " S " goto " JMP(3)
Packit Service 97d2fb
#define LOAD(T)		REG(1) " = *(" #T " *)(" REG(2) OFF(3) ")"
Packit Service 97d2fb
#define STORE(T, S)	"*(" #T " *)(" REG(1) OFF(3) ") = " S
Packit Service 97d2fb
#define XADD(T, S)	"lock *(" #T " *)(" REG(1) OFF(3) ") += " S
Packit Service 97d2fb
#define LDSKB(T, S)	"r0 = *(" #T " *)skb[" S "]"
Packit Service 97d2fb
Packit Service 97d2fb
static void
Packit Service 97d2fb
bswap_bpf_insn (struct bpf_insn *p)
Packit Service 97d2fb
{
Packit Service 97d2fb
  /* Note that the dst_reg and src_reg fields are 4-bit bitfields.
Packit Service 97d2fb
     That means these two nibbles are (typically) layed out in the
Packit Service 97d2fb
     opposite order between big- and little-endian hosts.  This is
Packit Service 97d2fb
     not required by any standard, but does happen to be true for
Packit Service 97d2fb
     at least ppc, s390, arm and mips as big-endian hosts.  */
Packit Service 97d2fb
  int t = p->dst_reg;
Packit Service 97d2fb
  p->dst_reg = p->src_reg;
Packit Service 97d2fb
  p->src_reg = t;
Packit Service 97d2fb
Packit Service 97d2fb
  /* The other 2 and 4 byte fields are trivially converted.  */
Packit Service 97d2fb
  CONVERT (p->off);
Packit Service 97d2fb
  CONVERT (p->imm);
Packit Service 97d2fb
}
Packit Service 97d2fb
Packit Service 97d2fb
int
Packit Service 97d2fb
bpf_disasm (Ebl *ebl, const uint8_t **startp, const uint8_t *end,
Packit Service 97d2fb
	    GElf_Addr addr, const char *fmt __attribute__((unused)),
Packit Service 97d2fb
	    DisasmOutputCB_t outcb,
Packit Service 97d2fb
	    DisasmGetSymCB_t symcb __attribute__((unused)),
Packit Service 97d2fb
	    void *outcbarg,
Packit Service 97d2fb
	    void *symcbarg __attribute__((unused)))
Packit Service 97d2fb
{
Packit Service 97d2fb
  const bool need_bswap = MY_ELFDATA != ebl->data;
Packit Service 97d2fb
  const uint8_t *start = *startp;
Packit Service 97d2fb
  char buf[128];
Packit Service 97d2fb
  int len, retval = 0;
Packit Service 97d2fb
Packit Service 97d2fb
  while (start + sizeof(struct bpf_insn) <= end)
Packit Service 97d2fb
    {
Packit Service 97d2fb
      struct bpf_insn i;
Packit Service 97d2fb
      unsigned code, class, jmp;
Packit Service 97d2fb
      const char *code_fmt;
Packit Service 97d2fb
Packit Service 97d2fb
      memcpy(&i, start, sizeof(struct bpf_insn));
Packit Service 97d2fb
      if (need_bswap)
Packit Service 97d2fb
	bswap_bpf_insn (&i);
Packit Service 97d2fb
Packit Service 97d2fb
      start += sizeof(struct bpf_insn);
Packit Service 97d2fb
      addr += sizeof(struct bpf_insn);
Packit Service 97d2fb
      jmp = addr + i.off * sizeof(struct bpf_insn);
Packit Service 97d2fb
Packit Service 97d2fb
      code = i.code;
Packit Service 97d2fb
      switch (code)
Packit Service 97d2fb
	{
Packit Service 97d2fb
	case BPF_LD | BPF_IMM | BPF_DW:
Packit Service 97d2fb
	  {
Packit Service 97d2fb
	    struct bpf_insn i2;
Packit Service 97d2fb
	    uint64_t imm64;
Packit Service 97d2fb
Packit Service 97d2fb
	    if (start + sizeof(struct bpf_insn) > end)
Packit Service 97d2fb
	      {
Packit Service 97d2fb
		start -= sizeof(struct bpf_insn);
Packit Service 97d2fb
		*startp = start;
Packit Service 97d2fb
		goto done;
Packit Service 97d2fb
	      }
Packit Service 97d2fb
	    memcpy(&i2, start, sizeof(struct bpf_insn));
Packit Service 97d2fb
	    if (need_bswap)
Packit Service 97d2fb
	      bswap_bpf_insn (&i2;;
Packit Service 97d2fb
	    start += sizeof(struct bpf_insn);
Packit Service 97d2fb
	    addr += sizeof(struct bpf_insn);
Packit Service 97d2fb
Packit Service 97d2fb
	    imm64 = (uint32_t)i.imm | ((uint64_t)i2.imm << 32);
Packit Service 97d2fb
	    switch (i.src_reg)
Packit Service 97d2fb
	      {
Packit Service 97d2fb
	      case 0:
Packit Service 97d2fb
		code_fmt = REG(1) " = %2$#" PRIx64;
Packit Service 97d2fb
		break;
Packit Service 97d2fb
	      case BPF_PSEUDO_MAP_FD:
Packit Service 97d2fb
		code_fmt = REG(1) " = map_fd(%2$#" PRIx64 ")";
Packit Service 97d2fb
		break;
Packit Service 97d2fb
	      default:
Packit Service 97d2fb
		code_fmt = REG(1) " = ld_pseudo(%3$d, %2$#" PRIx64 ")";
Packit Service 97d2fb
		break;
Packit Service 97d2fb
	      }
Packit Service 97d2fb
	    len = snprintf(buf, sizeof(buf), code_fmt,
Packit Service 97d2fb
			   i.dst_reg, imm64, i.src_reg);
Packit Service 97d2fb
	  }
Packit Service 97d2fb
	  break;
Packit Service 97d2fb
Packit Service 97d2fb
	case BPF_JMP | BPF_EXIT:
Packit Service 97d2fb
	  len = snprintf(buf, sizeof(buf), "exit");
Packit Service 97d2fb
	  break;
Packit Service 97d2fb
	case BPF_JMP | BPF_JA:
Packit Service 97d2fb
	  len = snprintf(buf, sizeof(buf), "goto " JMP(1), jmp);
Packit Service 97d2fb
	  break;
Packit Service 97d2fb
	case BPF_JMP | BPF_CALL:
Packit Service 97d2fb
	  code_fmt = "call " IMMS(1);
Packit Service 97d2fb
	  goto do_imm;
Packit Service 97d2fb
Packit Service 97d2fb
	case BPF_ALU | BPF_END | BPF_TO_LE:
Packit Service 97d2fb
	  /* The imm field contains {16,32,64}.  */
Packit Service 97d2fb
	  code_fmt = REG(1) " = le" IMMS(2) "(" REG(1) ")";
Packit Service 97d2fb
	  goto do_dst_imm;
Packit Service 97d2fb
	case BPF_ALU | BPF_END | BPF_TO_BE:
Packit Service 97d2fb
	  code_fmt = REG(1) " = be" IMMS(2) "(" REG(1) ")";
Packit Service 97d2fb
	  goto do_dst_imm;
Packit Service 97d2fb
Packit Service 97d2fb
	case BPF_ALU | BPF_ADD | BPF_K:
Packit Service 97d2fb
	  code_fmt = A32(+, IMMS(2));
Packit Service 97d2fb
	  goto do_dst_imm;
Packit Service 97d2fb
	case BPF_ALU | BPF_SUB | BPF_K:
Packit Service 97d2fb
	  code_fmt = A32(-, IMMS(2));
Packit Service 97d2fb
	  goto do_dst_imm;
Packit Service 97d2fb
	case BPF_ALU | BPF_MUL | BPF_K:
Packit Service 97d2fb
	  code_fmt = A32(*, IMMS(2));
Packit Service 97d2fb
	  goto do_dst_imm;
Packit Service 97d2fb
	case BPF_ALU | BPF_DIV | BPF_K:
Packit Service 97d2fb
	  code_fmt = A32(/, IMMS(2));
Packit Service 97d2fb
	  goto do_dst_imm;
Packit Service 97d2fb
	case BPF_ALU | BPF_OR | BPF_K:
Packit Service 97d2fb
	  code_fmt = A32(|, IMMX(2));
Packit Service 97d2fb
	  goto do_dst_imm;
Packit Service 97d2fb
	case BPF_ALU | BPF_AND | BPF_K:
Packit Service 97d2fb
	  code_fmt = A32(&, IMMX(2));
Packit Service 97d2fb
	  goto do_dst_imm;
Packit Service 97d2fb
	case BPF_ALU | BPF_LSH | BPF_K:
Packit Service 97d2fb
	  code_fmt = A32(<<, IMMS(2));
Packit Service 97d2fb
	  goto do_dst_imm;
Packit Service 97d2fb
	case BPF_ALU | BPF_RSH | BPF_K:
Packit Service 97d2fb
	  code_fmt = A32(>>, IMMS(2));
Packit Service 97d2fb
	  goto do_dst_imm;
Packit Service 97d2fb
	case BPF_ALU | BPF_MOD | BPF_K:
Packit Service 97d2fb
	  code_fmt = A32(%%, IMMS(2));
Packit Service 97d2fb
	  goto do_dst_imm;
Packit Service 97d2fb
	case BPF_ALU | BPF_XOR | BPF_K:
Packit Service 97d2fb
	  code_fmt = A32(^, IMMX(2));
Packit Service 97d2fb
	  goto do_dst_imm;
Packit Service 97d2fb
	case BPF_ALU | BPF_MOV | BPF_K:
Packit Service 97d2fb
	  code_fmt = REG(1) " = " IMMX(2);
Packit Service 97d2fb
	  goto do_dst_imm;
Packit Service 97d2fb
	case BPF_ALU | BPF_ARSH | BPF_K:
Packit Service 97d2fb
	  code_fmt = REG(1) " = (u32)((s32)" REG(1) " >> " IMMS(2) ")";
Packit Service 97d2fb
	  goto do_dst_imm;
Packit Service 97d2fb
Packit Service 97d2fb
	case BPF_ALU | BPF_ADD | BPF_X:
Packit Service 97d2fb
	  code_fmt = A32(+, REGU(2));
Packit Service 97d2fb
	  goto do_dst_src;
Packit Service 97d2fb
	case BPF_ALU | BPF_SUB | BPF_X:
Packit Service 97d2fb
	  code_fmt = A32(-, REGU(2));
Packit Service 97d2fb
	  goto do_dst_src;
Packit Service 97d2fb
	case BPF_ALU | BPF_MUL | BPF_X:
Packit Service 97d2fb
	  code_fmt = A32(*, REGU(2));
Packit Service 97d2fb
	  goto do_dst_src;
Packit Service 97d2fb
	case BPF_ALU | BPF_DIV | BPF_X:
Packit Service 97d2fb
	  code_fmt = A32(/, REGU(2));
Packit Service 97d2fb
	  goto do_dst_src;
Packit Service 97d2fb
	case BPF_ALU | BPF_OR | BPF_X:
Packit Service 97d2fb
	  code_fmt = A32(|, REGU(2));
Packit Service 97d2fb
	  goto do_dst_src;
Packit Service 97d2fb
	case BPF_ALU | BPF_AND | BPF_X:
Packit Service 97d2fb
	  code_fmt = A32(&, REGU(2));
Packit Service 97d2fb
	  goto do_dst_src;
Packit Service 97d2fb
	case BPF_ALU | BPF_LSH | BPF_X:
Packit Service 97d2fb
	  code_fmt = A32(<<, REGU(2));
Packit Service 97d2fb
	  goto do_dst_src;
Packit Service 97d2fb
	case BPF_ALU | BPF_RSH | BPF_X:
Packit Service 97d2fb
	  code_fmt = A32(>>, REGU(2));
Packit Service 97d2fb
	  goto do_dst_src;
Packit Service 97d2fb
	case BPF_ALU | BPF_MOD | BPF_X:
Packit Service 97d2fb
	  code_fmt = A32(%%, REGU(2));
Packit Service 97d2fb
	  goto do_dst_src;
Packit Service 97d2fb
	case BPF_ALU | BPF_XOR | BPF_X:
Packit Service 97d2fb
	  code_fmt = A32(^, REGU(2));
Packit Service 97d2fb
	  goto do_dst_src;
Packit Service 97d2fb
	case BPF_ALU | BPF_MOV | BPF_X:
Packit Service 97d2fb
	  code_fmt = REG(1) " = " REGU(2);
Packit Service 97d2fb
	  goto do_dst_src;
Packit Service 97d2fb
	case BPF_ALU | BPF_ARSH | BPF_X:
Packit Service 97d2fb
	  code_fmt = REG(1) " = (u32)((s32)" REG(1) " >> " REG(2) ")";
Packit Service 97d2fb
	  goto do_dst_src;
Packit Service 97d2fb
Packit Service 97d2fb
	case BPF_ALU64 | BPF_ADD | BPF_K:
Packit Service 97d2fb
	  code_fmt = A64(+, IMMS(2));
Packit Service 97d2fb
	  goto do_dst_imm;
Packit Service 97d2fb
	case BPF_ALU64 | BPF_SUB | BPF_K:
Packit Service 97d2fb
	  code_fmt = A64(-, IMMS(2));
Packit Service 97d2fb
	  goto do_dst_imm;
Packit Service 97d2fb
	case BPF_ALU64 | BPF_MUL | BPF_K:
Packit Service 97d2fb
	  code_fmt = A64(*, IMMS(2));
Packit Service 97d2fb
	  goto do_dst_imm;
Packit Service 97d2fb
	case BPF_ALU64 | BPF_DIV | BPF_K:
Packit Service 97d2fb
	  code_fmt = A64(/, IMMS(2));
Packit Service 97d2fb
	  goto do_dst_imm;
Packit Service 97d2fb
	case BPF_ALU64 | BPF_OR | BPF_K:
Packit Service 97d2fb
	  code_fmt = A64(|, IMMS(2));
Packit Service 97d2fb
	  goto do_dst_imm;
Packit Service 97d2fb
	case BPF_ALU64 | BPF_AND | BPF_K:
Packit Service 97d2fb
	  code_fmt = A64(&, IMMS(2));
Packit Service 97d2fb
	  goto do_dst_imm;
Packit Service 97d2fb
	case BPF_ALU64 | BPF_LSH | BPF_K:
Packit Service 97d2fb
	  code_fmt = A64(<<, IMMS(2));
Packit Service 97d2fb
	  goto do_dst_imm;
Packit Service 97d2fb
	case BPF_ALU64 | BPF_RSH | BPF_K:
Packit Service 97d2fb
	  code_fmt = A64(>>, IMMS(2));
Packit Service 97d2fb
	  goto do_dst_imm;
Packit Service 97d2fb
	case BPF_ALU64 | BPF_MOD | BPF_K:
Packit Service 97d2fb
	  code_fmt = A64(%%, IMMS(2));
Packit Service 97d2fb
	  goto do_dst_imm;
Packit Service 97d2fb
	case BPF_ALU64 | BPF_XOR | BPF_K:
Packit Service 97d2fb
	  code_fmt = A64(^, IMMS(2));
Packit Service 97d2fb
	  goto do_dst_imm;
Packit Service 97d2fb
	case BPF_ALU64 | BPF_MOV | BPF_K:
Packit Service 97d2fb
	  code_fmt = REG(1) " = " IMMS(2);
Packit Service 97d2fb
	  goto do_dst_imm;
Packit Service 97d2fb
	case BPF_ALU64 | BPF_ARSH | BPF_K:
Packit Service 97d2fb
	  code_fmt = REG(1) " = (s64)" REG(1) " >> " IMMS(2);
Packit Service 97d2fb
	  goto do_dst_imm;
Packit Service 97d2fb
Packit Service 97d2fb
	case BPF_ALU64 | BPF_ADD | BPF_X:
Packit Service 97d2fb
	  code_fmt = A64(+, REG(2));
Packit Service 97d2fb
	  goto do_dst_src;
Packit Service 97d2fb
	case BPF_ALU64 | BPF_SUB | BPF_X:
Packit Service 97d2fb
	  code_fmt = A64(-, REG(2));
Packit Service 97d2fb
	  goto do_dst_src;
Packit Service 97d2fb
	case BPF_ALU64 | BPF_MUL | BPF_X:
Packit Service 97d2fb
	  code_fmt = A64(*, REG(2));
Packit Service 97d2fb
	  goto do_dst_src;
Packit Service 97d2fb
	case BPF_ALU64 | BPF_DIV | BPF_X:
Packit Service 97d2fb
	  code_fmt = A64(/, REG(2));
Packit Service 97d2fb
	  goto do_dst_src;
Packit Service 97d2fb
	case BPF_ALU64 | BPF_OR | BPF_X:
Packit Service 97d2fb
	  code_fmt = A64(|, REG(2));
Packit Service 97d2fb
	  goto do_dst_src;
Packit Service 97d2fb
	case BPF_ALU64 | BPF_AND | BPF_X:
Packit Service 97d2fb
	  code_fmt = A64(&, REG(2));
Packit Service 97d2fb
	  goto do_dst_src;
Packit Service 97d2fb
	case BPF_ALU64 | BPF_LSH | BPF_X:
Packit Service 97d2fb
	  code_fmt = A64(<<, REG(2));
Packit Service 97d2fb
	  goto do_dst_src;
Packit Service 97d2fb
	case BPF_ALU64 | BPF_RSH | BPF_X:
Packit Service 97d2fb
	  code_fmt = A64(>>, REG(2));
Packit Service 97d2fb
	  goto do_dst_src;
Packit Service 97d2fb
	case BPF_ALU64 | BPF_MOD | BPF_X:
Packit Service 97d2fb
	  code_fmt = A64(%%, REG(2));
Packit Service 97d2fb
	  goto do_dst_src;
Packit Service 97d2fb
	case BPF_ALU64 | BPF_XOR | BPF_X:
Packit Service 97d2fb
	  code_fmt = A64(^, REG(2));
Packit Service 97d2fb
	  goto do_dst_src;
Packit Service 97d2fb
	case BPF_ALU64 | BPF_MOV | BPF_X:
Packit Service 97d2fb
	  code_fmt = REG(1) " = " REG(2);
Packit Service 97d2fb
	  goto do_dst_src;
Packit Service 97d2fb
	case BPF_ALU64 | BPF_ARSH | BPF_X:
Packit Service 97d2fb
	  code_fmt = REG(1) " = (s64)" REG(1) " >> " REG(2);
Packit Service 97d2fb
	  goto do_dst_src;
Packit Service 97d2fb
Packit Service 97d2fb
	case BPF_ALU | BPF_NEG:
Packit Service 97d2fb
	  code_fmt = REG(1) " = (u32)-" REG(1);
Packit Service 97d2fb
	  goto do_dst_src;
Packit Service 97d2fb
	case BPF_ALU64 | BPF_NEG:
Packit Service 97d2fb
	  code_fmt = REG(1) " = -" REG(1);
Packit Service 97d2fb
	  goto do_dst_src;
Packit Service 97d2fb
Packit Service 97d2fb
	case BPF_JMP | BPF_JEQ | BPF_K:
Packit Service 97d2fb
	  code_fmt = J64(REG(1), ==, IMMS(2));
Packit Service 97d2fb
	  goto do_dst_imm_jmp;
Packit Service 97d2fb
	case BPF_JMP | BPF_JGT | BPF_K:
Packit Service 97d2fb
	  code_fmt = J64(REG(1), >, IMMS(2));
Packit Service 97d2fb
	  goto do_dst_imm_jmp;
Packit Service 97d2fb
	case BPF_JMP | BPF_JGE | BPF_K:
Packit Service 97d2fb
	  code_fmt = J64(REG(1), >=, IMMS(2));
Packit Service 97d2fb
	  goto do_dst_imm_jmp;
Packit Service 97d2fb
	case BPF_JMP | BPF_JSET | BPF_K:
Packit Service 97d2fb
	  code_fmt = J64(REG(1), &, IMMS(2));
Packit Service 97d2fb
	  goto do_dst_imm_jmp;
Packit Service 97d2fb
	case BPF_JMP | BPF_JNE | BPF_K:
Packit Service 97d2fb
	  code_fmt = J64(REG(1), !=, IMMS(2));
Packit Service 97d2fb
	  goto do_dst_imm_jmp;
Packit Service 97d2fb
	case BPF_JMP | BPF_JSGT | BPF_K:
Packit Service 97d2fb
	  code_fmt = J64(REGS(1), >, IMMS(2));
Packit Service 97d2fb
	  goto do_dst_imm_jmp;
Packit Service 97d2fb
	case BPF_JMP | BPF_JSGE | BPF_K:
Packit Service 97d2fb
	  code_fmt = J64(REGS(1), >=, IMMS(2));
Packit Service 97d2fb
	  goto do_dst_imm_jmp;
Packit Service 97d2fb
	case BPF_JMP | BPF_JLT | BPF_K:
Packit Service 97d2fb
	  code_fmt = J64(REG(1), <, IMMS(2));
Packit Service 97d2fb
	  goto do_dst_imm_jmp;
Packit Service 97d2fb
	case BPF_JMP | BPF_JLE | BPF_K:
Packit Service 97d2fb
	  code_fmt = J64(REG(1), <=, IMMS(2));
Packit Service 97d2fb
	  goto do_dst_imm_jmp;
Packit Service 97d2fb
	case BPF_JMP | BPF_JSLT | BPF_K:
Packit Service 97d2fb
	  code_fmt = J64(REGS(1), <, IMMS(2));
Packit Service 97d2fb
	  goto do_dst_imm_jmp;
Packit Service 97d2fb
	case BPF_JMP | BPF_JSLE | BPF_K:
Packit Service 97d2fb
	  code_fmt = J64(REGS(1), <=, IMMS(2));
Packit Service 97d2fb
	  goto do_dst_imm_jmp;
Packit Service 97d2fb
Packit Service 97d2fb
	case BPF_JMP | BPF_JEQ | BPF_X:
Packit Service 97d2fb
	  code_fmt = J64(REG(1), ==, REG(2));
Packit Service 97d2fb
	  goto do_dst_src_jmp;
Packit Service 97d2fb
	case BPF_JMP | BPF_JGT | BPF_X:
Packit Service 97d2fb
	  code_fmt = J64(REG(1), >, REG(2));
Packit Service 97d2fb
	  goto do_dst_src_jmp;
Packit Service 97d2fb
	case BPF_JMP | BPF_JGE | BPF_X:
Packit Service 97d2fb
	  code_fmt = J64(REG(1), >=, REG(2));
Packit Service 97d2fb
	  goto do_dst_src_jmp;
Packit Service 97d2fb
	case BPF_JMP | BPF_JSET | BPF_X:
Packit Service 97d2fb
	  code_fmt = J64(REG(1), &, REG(2));
Packit Service 97d2fb
	  goto do_dst_src_jmp;
Packit Service 97d2fb
	case BPF_JMP | BPF_JNE | BPF_X:
Packit Service 97d2fb
	  code_fmt = J64(REG(1), !=, REG(2));
Packit Service 97d2fb
	  goto do_dst_src_jmp;
Packit Service 97d2fb
	case BPF_JMP | BPF_JSGT | BPF_X:
Packit Service 97d2fb
	  code_fmt = J64(REGS(1), >, REGS(2));
Packit Service 97d2fb
	  goto do_dst_src_jmp;
Packit Service 97d2fb
	case BPF_JMP | BPF_JSGE | BPF_X:
Packit Service 97d2fb
	  code_fmt = J64(REGS(1), >=, REGS(2));
Packit Service 97d2fb
	  goto do_dst_src_jmp;
Packit Service 97d2fb
	case BPF_JMP | BPF_JLT | BPF_X:
Packit Service 97d2fb
	  code_fmt = J64(REG(1), <, REG(2));
Packit Service 97d2fb
	  goto do_dst_src_jmp;
Packit Service 97d2fb
	case BPF_JMP | BPF_JLE | BPF_X:
Packit Service 97d2fb
	  code_fmt = J64(REG(1), <=, REG(2));
Packit Service 97d2fb
	  goto do_dst_src_jmp;
Packit Service 97d2fb
	case BPF_JMP | BPF_JSLT | BPF_X:
Packit Service 97d2fb
	  code_fmt = J64(REGS(1), <, REGS(2));
Packit Service 97d2fb
	  goto do_dst_src_jmp;
Packit Service 97d2fb
	case BPF_JMP | BPF_JSLE | BPF_X:
Packit Service 97d2fb
	  code_fmt = J64(REGS(1), <=, REGS(2));
Packit Service 97d2fb
	  goto do_dst_src_jmp;
Packit Service 97d2fb
Packit Service 97d2fb
	case BPF_LDX | BPF_MEM | BPF_B:
Packit Service 97d2fb
	  code_fmt = LOAD(u8);
Packit Service 97d2fb
	  goto do_dst_src_off;
Packit Service 97d2fb
	case BPF_LDX | BPF_MEM | BPF_H:
Packit Service 97d2fb
	  code_fmt = LOAD(u16);
Packit Service 97d2fb
	  goto do_dst_src_off;
Packit Service 97d2fb
	case BPF_LDX | BPF_MEM | BPF_W:
Packit Service 97d2fb
	  code_fmt = LOAD(u32);
Packit Service 97d2fb
	  goto do_dst_src_off;
Packit Service 97d2fb
	case BPF_LDX | BPF_MEM | BPF_DW:
Packit Service 97d2fb
	  code_fmt = LOAD(u64);
Packit Service 97d2fb
	  goto do_dst_src_off;
Packit Service 97d2fb
Packit Service 97d2fb
	case BPF_STX | BPF_MEM | BPF_B:
Packit Service 97d2fb
	  code_fmt = STORE(u8, REG(2));
Packit Service 97d2fb
	  goto do_dst_src_off;
Packit Service 97d2fb
	case BPF_STX | BPF_MEM | BPF_H:
Packit Service 97d2fb
	  code_fmt = STORE(u16, REG(2));
Packit Service 97d2fb
	  goto do_dst_src_off;
Packit Service 97d2fb
	case BPF_STX | BPF_MEM | BPF_W:
Packit Service 97d2fb
	  code_fmt = STORE(u32, REG(2));
Packit Service 97d2fb
	  goto do_dst_src_off;
Packit Service 97d2fb
	case BPF_STX | BPF_MEM | BPF_DW:
Packit Service 97d2fb
	  code_fmt = STORE(u64, REG(2));
Packit Service 97d2fb
	  goto do_dst_src_off;
Packit Service 97d2fb
Packit Service 97d2fb
	case BPF_STX | BPF_XADD | BPF_W:
Packit Service 97d2fb
	  code_fmt = XADD(u32, REG(2));
Packit Service 97d2fb
	  goto do_dst_src_off;
Packit Service 97d2fb
	case BPF_STX | BPF_XADD | BPF_DW:
Packit Service 97d2fb
	  code_fmt = XADD(u64, REG(2));
Packit Service 97d2fb
	  goto do_dst_src_off;
Packit Service 97d2fb
Packit Service 97d2fb
	case BPF_ST | BPF_MEM | BPF_B:
Packit Service 97d2fb
	  code_fmt = STORE(u8, IMMS(2));
Packit Service 97d2fb
	  goto do_dst_imm_off;
Packit Service 97d2fb
	case BPF_ST | BPF_MEM | BPF_H:
Packit Service 97d2fb
	  code_fmt = STORE(u16, IMMS(2));
Packit Service 97d2fb
	  goto do_dst_imm_off;
Packit Service 97d2fb
	case BPF_ST | BPF_MEM | BPF_W:
Packit Service 97d2fb
	  code_fmt = STORE(u32, IMMS(2));
Packit Service 97d2fb
	  goto do_dst_imm_off;
Packit Service 97d2fb
	case BPF_ST | BPF_MEM | BPF_DW:
Packit Service 97d2fb
	  code_fmt = STORE(u64, IMMS(2));
Packit Service 97d2fb
	  goto do_dst_imm_off;
Packit Service 97d2fb
Packit Service 97d2fb
	case BPF_LD | BPF_ABS | BPF_B:
Packit Service 97d2fb
	  code_fmt = LDSKB(u8, IMMS(1));
Packit Service 97d2fb
	  goto do_imm;
Packit Service 97d2fb
	case BPF_LD | BPF_ABS | BPF_H:
Packit Service 97d2fb
	  code_fmt = LDSKB(u16, IMMS(1));
Packit Service 97d2fb
	  goto do_imm;
Packit Service 97d2fb
	case BPF_LD | BPF_ABS | BPF_W:
Packit Service 97d2fb
	  code_fmt = LDSKB(u32, IMMS(1));
Packit Service 97d2fb
	  goto do_imm;
Packit Service 97d2fb
Packit Service 97d2fb
	case BPF_LD | BPF_IND | BPF_B:
Packit Service 97d2fb
	  code_fmt = LDSKB(u8, REG(1) "+" IMMS(2));
Packit Service 97d2fb
	  goto do_src_imm;
Packit Service 97d2fb
	case BPF_LD | BPF_IND | BPF_H:
Packit Service 97d2fb
	  code_fmt = LDSKB(u16, REG(1) "+" IMMS(2));
Packit Service 97d2fb
	  goto do_src_imm;
Packit Service 97d2fb
	case BPF_LD | BPF_IND | BPF_W:
Packit Service 97d2fb
	  code_fmt = LDSKB(u32, REG(1) "+" IMMS(2));
Packit Service 97d2fb
	  goto do_src_imm;
Packit Service 97d2fb
Packit Service 97d2fb
	do_imm:
Packit Service 97d2fb
	  len = snprintf(buf, sizeof(buf), code_fmt, i.imm);
Packit Service 97d2fb
	  break;
Packit Service 97d2fb
	do_dst_imm:
Packit Service 97d2fb
	  len = snprintf(buf, sizeof(buf), code_fmt, i.dst_reg, i.imm);
Packit Service 97d2fb
	  break;
Packit Service 97d2fb
	do_src_imm:
Packit Service 97d2fb
	  len = snprintf(buf, sizeof(buf), code_fmt, i.src_reg, i.imm);
Packit Service 97d2fb
	  break;
Packit Service 97d2fb
	do_dst_src:
Packit Service 97d2fb
	  len = snprintf(buf, sizeof(buf), code_fmt, i.dst_reg, i.src_reg);
Packit Service 97d2fb
	  break;
Packit Service 97d2fb
	do_dst_imm_jmp:
Packit Service 97d2fb
	  len = snprintf(buf, sizeof(buf), code_fmt, i.dst_reg, i.imm, jmp);
Packit Service 97d2fb
	  break;
Packit Service 97d2fb
	do_dst_src_jmp:
Packit Service 97d2fb
	  len = snprintf(buf, sizeof(buf), code_fmt,
Packit Service 97d2fb
			 i.dst_reg, i.src_reg, jmp);
Packit Service 97d2fb
	  break;
Packit Service 97d2fb
	do_dst_imm_off:
Packit Service 97d2fb
	  len = snprintf(buf, sizeof(buf), code_fmt, i.dst_reg, i.imm, i.off);
Packit Service 97d2fb
	  break;
Packit Service 97d2fb
	do_dst_src_off:
Packit Service 97d2fb
	  len = snprintf(buf, sizeof(buf), code_fmt,
Packit Service 97d2fb
			 i.dst_reg, i.src_reg, i.off);
Packit Service 97d2fb
	  break;
Packit Service 97d2fb
Packit Service 97d2fb
	default:
Packit Service 97d2fb
	  class = BPF_CLASS(code);
Packit Service 97d2fb
	  len = snprintf(buf, sizeof(buf), "invalid class %s",
Packit Service 97d2fb
			 class_string[class]);
Packit Service 97d2fb
	  break;
Packit Service 97d2fb
        }
Packit Service 97d2fb
Packit Service 97d2fb
      *startp = start;
Packit Service 97d2fb
      retval = outcb (buf, len, outcbarg);
Packit Service 97d2fb
      if (retval != 0)
Packit Service 97d2fb
	goto done;
Packit Service 97d2fb
    }
Packit Service 97d2fb
Packit Service 97d2fb
 done:
Packit Service 97d2fb
  return retval;
Packit Service 97d2fb
}