summaryrefslogtreecommitdiff
path: root/dev-util/perf/files/perf-6.10-bpf-capstone.patch
diff options
context:
space:
mode:
Diffstat (limited to 'dev-util/perf/files/perf-6.10-bpf-capstone.patch')
-rw-r--r--dev-util/perf/files/perf-6.10-bpf-capstone.patch456
1 files changed, 456 insertions, 0 deletions
diff --git a/dev-util/perf/files/perf-6.10-bpf-capstone.patch b/dev-util/perf/files/perf-6.10-bpf-capstone.patch
new file mode 100644
index 000000000000..ebae9a3ad080
--- /dev/null
+++ b/dev-util/perf/files/perf-6.10-bpf-capstone.patch
@@ -0,0 +1,456 @@
+From a7728af2f25fe99ee72d211bb4ddec17a8601f5f Mon Sep 17 00:00:00 2001
+From: Guilherme Amadio <amadio@gentoo.org>
+Date: Tue, 6 Aug 2024 11:34:05 +0200
+Subject: [PATCH] Fix bug #936439. Replay of upstream commit onto v6.10.
+
+Signed-off-by: Guilherme Amadio <amadio@gentoo.org>
+---
+ tools/perf/util/Build | 1 +
+ tools/perf/util/disasm.c | 187 +--------------------------------
+ tools/perf/util/disasm_bpf.c | 197 +++++++++++++++++++++++++++++++++++
+ tools/perf/util/disasm_bpf.h | 12 +++
+ 4 files changed, 211 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 72aec8f61b94..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_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.env,
+- dso->bpf_prog.id);
+- if (!info_node) {
+- ret = SYMBOL_ANNOTATE_ERRNO__BPF_MISSING_BTF;
+- goto out;
+- }
+- info_linear = info_node->info_linear;
+- sub_id = dso->bpf_prog.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.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..010b961c4ae9
+--- /dev/null
++++ b/tools/perf/util/disasm_bpf.c
+@@ -0,0 +1,197 @@
++// 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_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.env,
++ dso->bpf_prog.id);
++ if (!info_node) {
++ ret = SYMBOL_ANNOTATE_ERRNO__BPF_MISSING_BTF;
++ goto out;
++ }
++ info_linear = info_node->info_linear;
++ sub_id = dso->bpf_prog.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.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
+