LCOV - code coverage report
Current view: top level - bpfilter/cgen - dump.c (source / functions) Coverage Total Hit
Test: lcov.out Lines: 0.0 % 47 0
Test Date: 2025-02-26 17:59:59 Functions: 0.0 % 4 0

            Line data    Source code
       1              : // SPDX-License-Identifier: GPL-2.0-only
       2              : /*
       3              :  * Copyright (c) 2023 Meta Platforms, Inc. and affiliates.
       4              :  */
       5              : 
       6              : #include "bpfilter/cgen/dump.h"
       7              : 
       8              : #include <linux/bpf.h>
       9              : #include <linux/bpf_common.h>
      10              : 
      11              : #include <stdarg.h>
      12              : #include <stdbool.h>
      13              : #include <stdint.h>
      14              : #include <stdio.h>
      15              : 
      16              : #include "bpfilter/cgen/program.h"
      17              : #include "core/btf.h"
      18              : #include "core/dump.h"
      19              : #include "core/helper.h"
      20              : #include "core/logger.h"
      21              : 
      22              : #include "external/disasm.h"
      23              : 
      24              : #define SYM_MAX_NAME 256
      25              : 
      26              : struct bf_dump_data
      27              : {
      28              :     prefix_t *prefix;
      29              :     char scratch_buff[SYM_MAX_NAME + 8];
      30              :     unsigned long address_call_base;
      31              :     size_t idx;
      32              : };
      33              : 
      34            0 : static void _bf_print_insn(void *private_data, const char *fmt, ...)
      35              : {
      36              :     va_list args;
      37              :     struct bf_dump_data *bfdd = private_data;
      38              : 
      39            0 :     va_start(args, fmt);
      40            0 :     (void)fprintf(stderr, "%s%-7s%s: %s %4ld: ",
      41              :                   bf_logger_get_color(BF_COLOR_BLUE, BF_STYLE_BOLD), "debug",
      42              :                   bf_logger_get_color(BF_COLOR_RESET, BF_STYLE_RESET),
      43            0 :                   *(bfdd->prefix), bfdd->idx);
      44            0 :     (void)vfprintf(stderr, fmt, args);
      45            0 :     va_end(args);
      46            0 : }
      47              : 
      48            0 : static const char *_bf_print_call(void *private_data,
      49              :                                   const struct bpf_insn *insn)
      50              : {
      51              :     struct bf_dump_data *bfdd = private_data;
      52              : 
      53            0 :     if (insn->src_reg == BPF_PSEUDO_CALL) {
      54            0 :         (void)snprintf(bfdd->scratch_buff, sizeof(bfdd->scratch_buff), "%+d",
      55            0 :                        insn->imm);
      56              :     } else {
      57            0 :         (void)snprintf(bfdd->scratch_buff, sizeof(bfdd->scratch_buff), "%s",
      58            0 :                        bf_btf_get_name(insn->imm));
      59              :     }
      60              : 
      61            0 :     return bfdd->scratch_buff;
      62              : }
      63              : 
      64            0 : static const char *_bf_print_imm(void *private_data,
      65              :                                  const struct bpf_insn *insn, uint64_t full_imm)
      66              : {
      67              :     struct bf_dump_data *bfdd = private_data;
      68              : 
      69            0 :     if (insn->src_reg == BPF_PSEUDO_MAP_FD) {
      70            0 :         (void)snprintf(bfdd->scratch_buff, sizeof(bfdd->scratch_buff),
      71            0 :                        "map[id:%u]", insn->imm);
      72            0 :     } else if (insn->src_reg == BPF_PSEUDO_MAP_VALUE) {
      73            0 :         (void)snprintf(bfdd->scratch_buff, sizeof(bfdd->scratch_buff),
      74            0 :                        "map[id:%u][0]+%u", insn->imm, (insn + 1)->imm);
      75            0 :     } else if (insn->src_reg == BPF_PSEUDO_MAP_IDX_VALUE) {
      76            0 :         (void)snprintf(bfdd->scratch_buff, sizeof(bfdd->scratch_buff),
      77            0 :                        "map[idx:%u]+%u", insn->imm, (insn + 1)->imm);
      78            0 :     } else if (insn->src_reg == BPF_PSEUDO_FUNC) {
      79            0 :         (void)snprintf(bfdd->scratch_buff, sizeof(bfdd->scratch_buff),
      80            0 :                        "subprog[%+d]", insn->imm);
      81              :     } else {
      82            0 :         (void)snprintf(bfdd->scratch_buff, sizeof(bfdd->scratch_buff), "0x%llx",
      83              :                        (unsigned long long)full_imm);
      84              :     }
      85              : 
      86            0 :     return bfdd->scratch_buff;
      87              : }
      88              : 
      89            0 : void bf_program_dump_bytecode(const struct bf_program *program)
      90              : {
      91            0 :     prefix_t prefix = {};
      92            0 :     struct bf_dump_data bfdd = {
      93              :         .prefix = &prefix,
      94              :     };
      95            0 :     struct bpf_insn_cbs callbacks = {
      96              :         .cb_print = _bf_print_insn,
      97              :         .cb_call = _bf_print_call,
      98              :         .cb_imm = _bf_print_imm,
      99              :         .private_data = &bfdd,
     100              :     };
     101              :     bool double_insn = false;
     102              : 
     103            0 :     bf_assert(program);
     104              : 
     105            0 :     bf_dump_prefix_push(&prefix);
     106              : 
     107            0 :     bf_dbg("Bytecode for program at %p, %lu insn:", program, program->img_size);
     108              : 
     109            0 :     for (size_t i = 0; i < program->img_size; ++i) {
     110            0 :         if (i == program->img_size - 1)
     111            0 :             bf_dump_prefix_last(&prefix);
     112              : 
     113            0 :         if (double_insn) {
     114              :             double_insn = false;
     115            0 :             ++bfdd.idx;
     116            0 :             continue;
     117              :         }
     118              : 
     119            0 :         print_bpf_insn(&callbacks, &program->img[i], true);
     120            0 :         ++bfdd.idx;
     121              : 
     122            0 :         double_insn = program->img[i].code == (BPF_LD | BPF_IMM | BPF_DW);
     123              :     }
     124              : 
     125              :     // Force flush, otherwise output on stderr might appear.
     126            0 :     (void)fflush(stdout);
     127            0 : }
        

Generated by: LCOV version 2.0-1