From: Jiri Olsa <jo...@kernel.org>

Add BPF related code into DSO reading paths to return size (bpf_size)
and read the BPF code (bpf_read).

Signed-off-by: Jiri Olsa <jo...@kernel.org>
Acked-by: Song Liu <songliubrav...@fb.com>
Cc: Adrian Hunter <adrian.hun...@intel.com>
Cc: Alexander Shishkin <alexander.shish...@linux.intel.com>
Cc: Andi Kleen <a...@linux.intel.com>
Cc: Namhyung Kim <namhy...@kernel.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Stanislav Fomichev <s...@google.com>
Link: http://lkml.kernel.org/r/20190508132010.14512-5-jo...@kernel.org
[ Use uintptr_t when casting from u64 to u8 pointers ]
Signed-off-by: Arnaldo Carvalho de Melo <a...@redhat.com>
---
 tools/perf/util/dso.c | 49 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 48 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index 1e6a045adb8c..1fb18292c2d3 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -9,6 +9,8 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <libgen.h>
+#include <bpf/libbpf.h>
+#include "bpf-event.h"
 #include "compress.h"
 #include "namespaces.h"
 #include "path.h"
@@ -706,6 +708,44 @@ bool dso__data_status_seen(struct dso *dso, enum 
dso_data_status_seen by)
        return false;
 }
 
+static ssize_t bpf_read(struct dso *dso, u64 offset, char *data)
+{
+       struct bpf_prog_info_node *node;
+       ssize_t size = DSO__DATA_CACHE_SIZE;
+       u64 len;
+       u8 *buf;
+
+       node = perf_env__find_bpf_prog_info(dso->bpf_prog.env, 
dso->bpf_prog.id);
+       if (!node || !node->info_linear) {
+               dso->data.status = DSO_DATA_STATUS_ERROR;
+               return -1;
+       }
+
+       len = node->info_linear->info.jited_prog_len;
+       buf = (u8 *)(uintptr_t)node->info_linear->info.jited_prog_insns;
+
+       if (offset >= len)
+               return -1;
+
+       size = (ssize_t)min(len - offset, (u64)size);
+       memcpy(data, buf + offset, size);
+       return size;
+}
+
+static int bpf_size(struct dso *dso)
+{
+       struct bpf_prog_info_node *node;
+
+       node = perf_env__find_bpf_prog_info(dso->bpf_prog.env, 
dso->bpf_prog.id);
+       if (!node || !node->info_linear) {
+               dso->data.status = DSO_DATA_STATUS_ERROR;
+               return -1;
+       }
+
+       dso->data.file_size = node->info_linear->info.jited_prog_len;
+       return 0;
+}
+
 static void
 dso_cache__free(struct dso *dso)
 {
@@ -832,7 +872,11 @@ dso_cache__read(struct dso *dso, struct machine *machine,
        if (!cache)
                return -ENOMEM;
 
-       ret = file_read(dso, machine, cache_offset, cache->data);
+       if (dso->binary_type == DSO_BINARY_TYPE__BPF_PROG_INFO)
+               ret = bpf_read(dso, cache_offset, cache->data);
+       else
+               ret = file_read(dso, machine, cache_offset, cache->data);
+
        if (ret > 0) {
                cache->offset = cache_offset;
                cache->size   = ret;
@@ -941,6 +985,9 @@ int dso__data_file_size(struct dso *dso, struct machine 
*machine)
        if (dso->data.status == DSO_DATA_STATUS_ERROR)
                return -1;
 
+       if (dso->binary_type == DSO_BINARY_TYPE__BPF_PROG_INFO)
+               return bpf_size(dso);
+
        return file_size(dso, machine);
 }
 
-- 
2.20.1

Reply via email to