LCOV - code coverage report
Current view: top level - bpfilter/cgen - dump.c (source / functions) Coverage Total Hit
Test: coverage.lcov Lines: 0.0 % 46 0
Test Date: 2025-11-24 12:34:34 Functions: 0.0 % 4 0
Branches: 0.0 % 18 0

             Branch data     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 "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/btf.h>
      17                 :             : #include <bpfilter/dump.h>
      18                 :             : #include <bpfilter/helper.h>
      19                 :             : #include <bpfilter/logger.h>
      20                 :             : 
      21                 :             : #include "cgen/program.h"
      22                 :             : #include "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                 :             :     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