commit:     c9e99b12374290bce0b623136ea017c694ee1b31
Author:     Guilherme Amadio <amadio <AT> gentoo <DOT> org>
AuthorDate: Tue Aug  6 11:56:07 2024 +0000
Commit:     Guilherme Amadio <amadio <AT> gentoo <DOT> org>
CommitDate: Tue Aug  6 11:56:07 2024 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=c9e99b12

dev-util/perf: fix bug #936439

Closes: https://bugs.gentoo.org/936439
Link: https://lore.kernel.org/linux-kernel/ZqpUSKPxMwaQKORr@x1/

Signed-off-by: Guilherme Amadio <amadio <AT> gentoo.org>

 dev-util/perf/files/perf-6.10.3-bpf-capstone.patch | 455 +++++++++++++++++++++
 dev-util/perf/perf-6.10.3.ebuild                   |   1 +
 2 files changed, 456 insertions(+)

diff --git a/dev-util/perf/files/perf-6.10.3-bpf-capstone.patch 
b/dev-util/perf/files/perf-6.10.3-bpf-capstone.patch
new file mode 100644
index 000000000000..57b298d8ccd7
--- /dev/null
+++ b/dev-util/perf/files/perf-6.10.3-bpf-capstone.patch
@@ -0,0 +1,455 @@
+From b382a433e0178d3840a8fb4b05ba3dbecba075fa Mon Sep 17 00:00:00 2001
+From: Guilherme Amadio <[email protected]>
+Date: Tue, 6 Aug 2024 11:34:05 +0200
+Subject: [PATCH]  Fix bug #936439. Replay of upstream commit onto v6.10.3.
+
+Signed-off-by: Guilherme Amadio <[email protected]>
+---
+ tools/perf/util/Build        |   1 +
+ tools/perf/util/disasm.c     | 187 +--------------------------------
+ tools/perf/util/disasm_bpf.c | 196 +++++++++++++++++++++++++++++++++++
+ tools/perf/util/disasm_bpf.h |  12 +++
+ 4 files changed, 210 insertions(+), 186 deletions(-)
+ create mode 100644 tools/perf/util/disasm_bpf.c
+ create mode 100644 tools/perf/util/disasm_bpf.h
+
+diff --git a/tools/perf/util/Build b/tools/perf/util/Build
+index da64efd8718f..384c4e06b838 100644
+--- a/tools/perf/util/Build
++++ b/tools/perf/util/Build
+@@ -13,6 +13,7 @@ perf-y += copyfile.o
+ perf-y += ctype.o
+ perf-y += db-export.o
+ perf-y += disasm.o
++perf-y += disasm_bpf.o
+ perf-y += env.o
+ perf-y += event.o
+ perf-y += evlist.o
+diff --git a/tools/perf/util/disasm.c b/tools/perf/util/disasm.c
+index e10558b79504..766cbd005f32 100644
+--- a/tools/perf/util/disasm.c
++++ b/tools/perf/util/disasm.c
+@@ -15,6 +15,7 @@
+ #include "build-id.h"
+ #include "debug.h"
+ #include "disasm.h"
++#include "disasm_bpf.h"
+ #include "dso.h"
+ #include "env.h"
+ #include "evsel.h"
+@@ -1164,192 +1165,6 @@ static int dso__disassemble_filename(struct dso *dso, 
char *filename, size_t fil
+       return 0;
+ }
+ 
+-#if defined(HAVE_LIBBFD_SUPPORT) && defined(HAVE_LIBBPF_SUPPORT)
+-#define PACKAGE "perf"
+-#include <bfd.h>
+-#include <dis-asm.h>
+-#include <bpf/bpf.h>
+-#include <bpf/btf.h>
+-#include <bpf/libbpf.h>
+-#include <linux/btf.h>
+-#include <tools/dis-asm-compat.h>
+-
+-#include "bpf-event.h"
+-#include "bpf-utils.h"
+-
+-static 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,
+-                                                   &notes->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, &notes->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)
+-static 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)
+-
+-static 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, &notes->src->source);
+-
+-      zfree(&args->line);
+-      return 0;
+-}
+-
+ #ifdef HAVE_LIBCAPSTONE_SUPPORT
+ #include <capstone/capstone.h>
+ 
+diff --git a/tools/perf/util/disasm_bpf.c b/tools/perf/util/disasm_bpf.c
+new file mode 100644
+index 000000000000..c76a7d2be1a7
+--- /dev/null
++++ b/tools/perf/util/disasm_bpf.c
+@@ -0,0 +1,196 @@
++// 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,
++                                                   &notes->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, &notes->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, &notes->src->source);
++
++      zfree(&args->line);
++      return 0;
++}
+diff --git a/tools/perf/util/disasm_bpf.h b/tools/perf/util/disasm_bpf.h
+new file mode 100644
+index 000000000000..2ecb19545388
+--- /dev/null
++++ b/tools/perf/util/disasm_bpf.h
+@@ -0,0 +1,12 @@
++// SPDX-License-Identifier: GPL-2.0-only
++
++#ifndef __PERF_DISASM_BPF_H
++#define __PERF_DISASM_BPF_H
++
++struct symbol;
++struct annotate_args;
++
++int symbol__disassemble_bpf(struct symbol *sym, struct annotate_args *args);
++int symbol__disassemble_bpf_image(struct symbol *sym, struct annotate_args 
*args);
++
++#endif /* __PERF_DISASM_BPF_H */
+-- 
+2.45.2
+

diff --git a/dev-util/perf/perf-6.10.3.ebuild b/dev-util/perf/perf-6.10.3.ebuild
index 0f0e90117809..4c50de412173 100644
--- a/dev-util/perf/perf-6.10.3.ebuild
+++ b/dev-util/perf/perf-6.10.3.ebuild
@@ -180,6 +180,7 @@ src_prepare() {
        pushd "${S_K}" >/dev/null || die
        eapply "${FILESDIR}"/perf-6.4-libtracefs.patch
        eapply "${FILESDIR}"/perf-6.10-expr.patch
+       eapply "${FILESDIR}"/perf-6.10.3-bpf-capstone.patch
        popd || die
 
        # Drop some upstream too-developer-oriented flags and fix the

Reply via email to