^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* Copyright (c) 2011-2014 PLUMgrid, http://plumgrid.com
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2016 Facebook
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/bpf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "disasm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #define __BPF_FUNC_STR_FN(x) [BPF_FUNC_ ## x] = __stringify(bpf_ ## x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) static const char * const func_id_str[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) __BPF_FUNC_MAPPER(__BPF_FUNC_STR_FN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #undef __BPF_FUNC_STR_FN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) static const char *__func_get_name(const struct bpf_insn_cbs *cbs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) const struct bpf_insn *insn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) char *buff, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) BUILD_BUG_ON(ARRAY_SIZE(func_id_str) != __BPF_FUNC_MAX_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) if (insn->src_reg != BPF_PSEUDO_CALL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) insn->imm >= 0 && insn->imm < __BPF_FUNC_MAX_ID &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) func_id_str[insn->imm])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) return func_id_str[insn->imm];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) if (cbs && cbs->cb_call)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) return cbs->cb_call(cbs->private_data, insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) if (insn->src_reg == BPF_PSEUDO_CALL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) snprintf(buff, len, "%+d", insn->imm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) return buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static const char *__func_imm_name(const struct bpf_insn_cbs *cbs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) const struct bpf_insn *insn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) u64 full_imm, char *buff, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) if (cbs && cbs->cb_imm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) return cbs->cb_imm(cbs->private_data, insn, full_imm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) snprintf(buff, len, "0x%llx", (unsigned long long)full_imm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) return buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) const char *func_id_name(int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) if (id >= 0 && id < __BPF_FUNC_MAX_ID && func_id_str[id])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) return func_id_str[id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) return "unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) const char *const bpf_class_string[8] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) [BPF_LD] = "ld",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) [BPF_LDX] = "ldx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) [BPF_ST] = "st",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) [BPF_STX] = "stx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) [BPF_ALU] = "alu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) [BPF_JMP] = "jmp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) [BPF_JMP32] = "jmp32",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) [BPF_ALU64] = "alu64",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) const char *const bpf_alu_string[16] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) [BPF_ADD >> 4] = "+=",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) [BPF_SUB >> 4] = "-=",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) [BPF_MUL >> 4] = "*=",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) [BPF_DIV >> 4] = "/=",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) [BPF_OR >> 4] = "|=",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) [BPF_AND >> 4] = "&=",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) [BPF_LSH >> 4] = "<<=",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) [BPF_RSH >> 4] = ">>=",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) [BPF_NEG >> 4] = "neg",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) [BPF_MOD >> 4] = "%=",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) [BPF_XOR >> 4] = "^=",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) [BPF_MOV >> 4] = "=",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) [BPF_ARSH >> 4] = "s>>=",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) [BPF_END >> 4] = "endian",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static const char *const bpf_ldst_string[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) [BPF_W >> 3] = "u32",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) [BPF_H >> 3] = "u16",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) [BPF_B >> 3] = "u8",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) [BPF_DW >> 3] = "u64",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) static const char *const bpf_jmp_string[16] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) [BPF_JA >> 4] = "jmp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) [BPF_JEQ >> 4] = "==",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) [BPF_JGT >> 4] = ">",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) [BPF_JLT >> 4] = "<",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) [BPF_JGE >> 4] = ">=",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) [BPF_JLE >> 4] = "<=",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) [BPF_JSET >> 4] = "&",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) [BPF_JNE >> 4] = "!=",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) [BPF_JSGT >> 4] = "s>",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) [BPF_JSLT >> 4] = "s<",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) [BPF_JSGE >> 4] = "s>=",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) [BPF_JSLE >> 4] = "s<=",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) [BPF_CALL >> 4] = "call",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) [BPF_EXIT >> 4] = "exit",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static void print_bpf_end_insn(bpf_insn_print_t verbose,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) void *private_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) const struct bpf_insn *insn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) verbose(private_data, "(%02x) r%d = %s%d r%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) insn->code, insn->dst_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) BPF_SRC(insn->code) == BPF_TO_BE ? "be" : "le",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) insn->imm, insn->dst_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) void print_bpf_insn(const struct bpf_insn_cbs *cbs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) const struct bpf_insn *insn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) bool allow_ptr_leaks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) const bpf_insn_print_t verbose = cbs->cb_print;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) u8 class = BPF_CLASS(insn->code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (class == BPF_ALU || class == BPF_ALU64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (BPF_OP(insn->code) == BPF_END) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (class == BPF_ALU64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) verbose(cbs->private_data, "BUG_alu64_%02x\n", insn->code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) print_bpf_end_insn(verbose, cbs->private_data, insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) } else if (BPF_OP(insn->code) == BPF_NEG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) verbose(cbs->private_data, "(%02x) %c%d = -%c%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) insn->code, class == BPF_ALU ? 'w' : 'r',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) insn->dst_reg, class == BPF_ALU ? 'w' : 'r',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) insn->dst_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) } else if (BPF_SRC(insn->code) == BPF_X) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) verbose(cbs->private_data, "(%02x) %c%d %s %c%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) insn->code, class == BPF_ALU ? 'w' : 'r',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) insn->dst_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) bpf_alu_string[BPF_OP(insn->code) >> 4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) class == BPF_ALU ? 'w' : 'r',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) insn->src_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) verbose(cbs->private_data, "(%02x) %c%d %s %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) insn->code, class == BPF_ALU ? 'w' : 'r',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) insn->dst_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) bpf_alu_string[BPF_OP(insn->code) >> 4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) insn->imm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) } else if (class == BPF_STX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (BPF_MODE(insn->code) == BPF_MEM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) verbose(cbs->private_data, "(%02x) *(%s *)(r%d %+d) = r%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) insn->code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) bpf_ldst_string[BPF_SIZE(insn->code) >> 3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) insn->dst_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) insn->off, insn->src_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) else if (BPF_MODE(insn->code) == BPF_XADD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) verbose(cbs->private_data, "(%02x) lock *(%s *)(r%d %+d) += r%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) insn->code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) bpf_ldst_string[BPF_SIZE(insn->code) >> 3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) insn->dst_reg, insn->off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) insn->src_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) verbose(cbs->private_data, "BUG_%02x\n", insn->code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) } else if (class == BPF_ST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (BPF_MODE(insn->code) == BPF_MEM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) verbose(cbs->private_data, "(%02x) *(%s *)(r%d %+d) = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) insn->code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) bpf_ldst_string[BPF_SIZE(insn->code) >> 3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) insn->dst_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) insn->off, insn->imm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) } else if (BPF_MODE(insn->code) == 0xc0 /* BPF_NOSPEC, no UAPI */) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) verbose(cbs->private_data, "(%02x) nospec\n", insn->code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) verbose(cbs->private_data, "BUG_st_%02x\n", insn->code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) } else if (class == BPF_LDX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (BPF_MODE(insn->code) != BPF_MEM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) verbose(cbs->private_data, "BUG_ldx_%02x\n", insn->code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) verbose(cbs->private_data, "(%02x) r%d = *(%s *)(r%d %+d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) insn->code, insn->dst_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) bpf_ldst_string[BPF_SIZE(insn->code) >> 3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) insn->src_reg, insn->off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) } else if (class == BPF_LD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (BPF_MODE(insn->code) == BPF_ABS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) verbose(cbs->private_data, "(%02x) r0 = *(%s *)skb[%d]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) insn->code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) bpf_ldst_string[BPF_SIZE(insn->code) >> 3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) insn->imm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) } else if (BPF_MODE(insn->code) == BPF_IND) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) verbose(cbs->private_data, "(%02x) r0 = *(%s *)skb[r%d + %d]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) insn->code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) bpf_ldst_string[BPF_SIZE(insn->code) >> 3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) insn->src_reg, insn->imm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) } else if (BPF_MODE(insn->code) == BPF_IMM &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) BPF_SIZE(insn->code) == BPF_DW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) /* At this point, we already made sure that the second
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * part of the ldimm64 insn is accessible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) u64 imm = ((u64)(insn + 1)->imm << 32) | (u32)insn->imm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) bool is_ptr = insn->src_reg == BPF_PSEUDO_MAP_FD ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) insn->src_reg == BPF_PSEUDO_MAP_VALUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) char tmp[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if (is_ptr && !allow_ptr_leaks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) imm = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) verbose(cbs->private_data, "(%02x) r%d = %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) insn->code, insn->dst_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) __func_imm_name(cbs, insn, imm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) tmp, sizeof(tmp)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) verbose(cbs->private_data, "BUG_ld_%02x\n", insn->code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) } else if (class == BPF_JMP32 || class == BPF_JMP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) u8 opcode = BPF_OP(insn->code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if (opcode == BPF_CALL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) char tmp[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (insn->src_reg == BPF_PSEUDO_CALL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) verbose(cbs->private_data, "(%02x) call pc%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) insn->code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) __func_get_name(cbs, insn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) tmp, sizeof(tmp)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) strcpy(tmp, "unknown");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) verbose(cbs->private_data, "(%02x) call %s#%d\n", insn->code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) __func_get_name(cbs, insn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) tmp, sizeof(tmp)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) insn->imm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) } else if (insn->code == (BPF_JMP | BPF_JA)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) verbose(cbs->private_data, "(%02x) goto pc%+d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) insn->code, insn->off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) } else if (insn->code == (BPF_JMP | BPF_EXIT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) verbose(cbs->private_data, "(%02x) exit\n", insn->code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) } else if (BPF_SRC(insn->code) == BPF_X) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) verbose(cbs->private_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) "(%02x) if %c%d %s %c%d goto pc%+d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) insn->code, class == BPF_JMP32 ? 'w' : 'r',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) insn->dst_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) bpf_jmp_string[BPF_OP(insn->code) >> 4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) class == BPF_JMP32 ? 'w' : 'r',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) insn->src_reg, insn->off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) verbose(cbs->private_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) "(%02x) if %c%d %s 0x%x goto pc%+d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) insn->code, class == BPF_JMP32 ? 'w' : 'r',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) insn->dst_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) bpf_jmp_string[BPF_OP(insn->code) >> 4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) insn->imm, insn->off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) verbose(cbs->private_data, "(%02x) %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) insn->code, bpf_class_string[class]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }