Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/tools/perf/util/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 4 kB image not shown  

Quelle  disasm_bpf.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-only

#include "util/annotate.h"
#include "util/disasm_bpf.h"
#include "util/symbol.h"
#include <linux/zalloc.h>
#include <string.h>

#if defined(HAVE_LIBBFD_SUPPORT) && defined(HAVE_LIBBPF_SUPPORT)
#define PACKAGE "perf"
#include <bfd.h>
#include <bpf/bpf.h>
#include <bpf/btf.h>
#include <bpf/libbpf.h>
#include <dis-asm.h>
#include <errno.h>
#include <linux/btf.h>
#include <tools/dis-asm-compat.h>

#include "util/bpf-event.h"
#include "util/bpf-utils.h"
#include "util/debug.h"
#include "util/dso.h"
#include "util/map.h"
#include "util/env.h"
#include "util/util.h"

int symbol__disassemble_bpf(struct symbol *sym, struct annotate_args *args)
{
 struct annotation *notes = symbol__annotation(sym);
 struct bpf_prog_linfo *prog_linfo = NULL;
 struct bpf_prog_info_node *info_node;
 int len = sym->end - sym->start;
 disassembler_ftype disassemble;
 struct map *map = args->ms.map;
 struct perf_bpil *info_linear;
 struct disassemble_info info;
 struct dso *dso = map__dso(map);
 int pc = 0, count, sub_id;
 struct btf *btf = NULL;
 char tpath[PATH_MAX];
 size_t buf_size;
 int nr_skip = 0;
 char *buf;
 bfd *bfdf;
 int ret;
 FILE *s;

 if (dso__binary_type(dso) != DSO_BINARY_TYPE__BPF_PROG_INFO)
  return SYMBOL_ANNOTATE_ERRNO__BPF_INVALID_FILE;

 pr_debug("%s: handling sym %s addr %" PRIx64 " len %" PRIx64 "\n", __func__,
    sym->name, sym->start, sym->end - sym->start);

 memset(tpath, 0, sizeof(tpath));
 perf_exe(tpath, sizeof(tpath));

 bfdf = bfd_openr(tpath, NULL);
 if (bfdf == NULL)
  abort();

 if (!bfd_check_format(bfdf, bfd_object))
  abort();

 s = open_memstream(&buf, &buf_size);
 if (!s) {
  ret = errno;
  goto out;
 }
 init_disassemble_info_compat(&info, s,
         (fprintf_ftype) fprintf,
         fprintf_styled);
 info.arch = bfd_get_arch(bfdf);
 info.mach = bfd_get_mach(bfdf);

 info_node = perf_env__find_bpf_prog_info(dso__bpf_prog(dso)->env,
       dso__bpf_prog(dso)->id);
 if (!info_node) {
  ret = SYMBOL_ANNOTATE_ERRNO__BPF_MISSING_BTF;
  goto out;
 }
 info_linear = info_node->info_linear;
 sub_id = dso__bpf_prog(dso)->sub_id;

 info.buffer = (void *)(uintptr_t)(info_linear->info.jited_prog_insns);
 info.buffer_length = info_linear->info.jited_prog_len;

 if (info_linear->info.nr_line_info)
  prog_linfo = bpf_prog_linfo__new(&info_linear->info);

 if (info_linear->info.btf_id) {
  struct btf_node *node;

  node = perf_env__find_btf(dso__bpf_prog(dso)->env,
       info_linear->info.btf_id);
  if (node)
   btf = btf__new((__u8 *)(node->data),
           node->data_size);
 }

 disassemble_init_for_target(&info);

#ifdef DISASM_FOUR_ARGS_SIGNATURE
 disassemble = disassembler(info.arch,
       bfd_big_endian(bfdf),
       info.mach,
       bfdf);
#else
 disassemble = disassembler(bfdf);
#endif
 if (disassemble == NULL)
  abort();

 fflush(s);
 do {
  const struct bpf_line_info *linfo = NULL;
  struct disasm_line *dl;
  size_t prev_buf_size;
  const char *srcline;
  u64 addr;

  addr = pc + ((u64 *)(uintptr_t)(info_linear->info.jited_ksyms))[sub_id];
  count = disassemble(pc, &info);

  if (prog_linfo)
   linfo = bpf_prog_linfo__lfind_addr_func(prog_linfo,
        addr, sub_id,
        nr_skip);

  if (linfo && btf) {
   srcline = btf__name_by_offset(btf, linfo->line_off);
   nr_skip++;
  } else
   srcline = NULL;

  fprintf(s, "\n");
  prev_buf_size = buf_size;
  fflush(s);

  if (!annotate_opts.hide_src_code && srcline) {
   args->offset = -1;
   args->line = strdup(srcline);
   args->line_nr = 0;
   args->fileloc = NULL;
   args->ms.sym  = sym;
   dl = disasm_line__new(args);
   if (dl) {
    annotation_line__add(&dl->al,
           ¬es->src->source);
   }
  }

  args->offset = pc;
  args->line = buf + prev_buf_size;
  args->line_nr = 0;
  args->fileloc = NULL;
  args->ms.sym  = sym;
  dl = disasm_line__new(args);
  if (dl)
   annotation_line__add(&dl->al, ¬es->src->source);

  pc += count;
 } while (count > 0 && pc < len);

 ret = 0;
out:
 free(prog_linfo);
 btf__free(btf);
 fclose(s);
 bfd_close(bfdf);
 return ret;
}
#else // defined(HAVE_LIBBFD_SUPPORT) && defined(HAVE_LIBBPF_SUPPORT)
int symbol__disassemble_bpf(struct symbol *sym __maybe_unused, struct annotate_args *args __maybe_unused)
{
 return SYMBOL_ANNOTATE_ERRNO__NO_LIBOPCODES_FOR_BPF;
}
#endif // defined(HAVE_LIBBFD_SUPPORT) && defined(HAVE_LIBBPF_SUPPORT)

int symbol__disassemble_bpf_image(struct symbol *sym, struct annotate_args *args)
{
 struct annotation *notes = symbol__annotation(sym);
 struct disasm_line *dl;

 args->offset = -1;
 args->line = strdup("to be implemented");
 args->line_nr = 0;
 args->fileloc = NULL;
 dl = disasm_line__new(args);
 if (dl)
  annotation_line__add(&dl->al, ¬es->src->source);

 zfree(&args->line);
 return 0;
}

Messung V0.5
C=95 H=95 G=94

¤ Dauer der Verarbeitung: 0.3 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.