Added patch to Linux perf to allow it to work with Akaros
authorDavide Libenzi <dlibenzi@google.com>
Wed, 28 Oct 2015 17:45:45 +0000 (10:45 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Wed, 18 Nov 2015 17:56:34 +0000 (09:56 -0800)
Added patch to Linux perf to allow it to work with Akaros.

Signed-off-by: Davide Libenzi <dlibenzi@google.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
tools/profile/kprof2perf/perf_patches/perf_patch.diff [new file with mode: 0644]

diff --git a/tools/profile/kprof2perf/perf_patches/perf_patch.diff b/tools/profile/kprof2perf/perf_patches/perf_patch.diff
new file mode 100644 (file)
index 0000000..6d0d6da
--- /dev/null
@@ -0,0 +1,201 @@
+diff --git a/tools/perf/perf.c b/tools/perf/perf.c
+index 85e1aed..ecf04c1 100644
+--- a/tools/perf/perf.c
++++ b/tools/perf/perf.c
+@@ -15,9 +15,14 @@
+ #include "util/parse-events.h"
+ #include <lk/debugfs.h>
+ #include <pthread.h>
++#include <fcntl.h>
++#include <stdio.h>
++#include <errno.h>
++#include <string.h>
++#include <unistd.h>
+ const char perf_usage_string[] =
+-      "perf [--version] [--help] COMMAND [ARGS]";
++      "perf [--version] [--help] [--root-dir DIR] COMMAND [ARGS]";
+ const char perf_more_info_string[] =
+       "See 'perf help COMMAND' for more information on a specific command.";
+@@ -25,6 +30,7 @@ const char perf_more_info_string[] =
+ int use_browser = -1;
+ static int use_pager = -1;
+ const char *input_name;
++static const char *perf_root_dir;
+ struct cmd_struct {
+       const char *cmd;
+@@ -76,6 +82,28 @@ static int pager_command_config(const char *var, const char *value, void *data)
+       return 0;
+ }
++const char *perf_resolve_binary(const char *path, char *rpath, size_t max_size)
++{
++      snprintf(rpath, max_size, "%s/%s", perf_root_dir, path);
++
++      return access(rpath, F_OK) == 0 ? rpath: path;
++}
++
++int perf_open_binary(const char *path, int flags, int mode)
++{
++      if (perf_root_dir) {
++              int fd;
++              char rpath[4096];
++
++              snprintf(rpath, sizeof(rpath), "%s/%s", perf_root_dir, path);
++              fd = open(rpath, flags, mode);
++              if (fd >= 0)
++                      return fd;
++      }
++
++      return open(path, flags, mode);
++}
++
+ /* returns 0 for "no pager", 1 for "use pager", and -1 for "not specified" */
+ int check_pager_config(const char *cmd)
+ {
+@@ -199,6 +227,14 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
+                               *envchanged = 1;
+                       (*argv)++;
+                       (*argc)--;
++              } else if (!strcmp(cmd, "--root-dir")) {
++                      if (*argc < 2) {
++                              fprintf(stderr, "No directory given for --root-dir.\n");
++                              usage(perf_usage_string);
++                      }
++                      perf_root_dir = (*argv)[1];
++                      (*argv)++;
++                      (*argc)--;
+               } else if (!prefixcmp(cmd, CMD_DEBUGFS_DIR)) {
+                       perf_debugfs_set_path(cmd + strlen(CMD_DEBUGFS_DIR));
+                       fprintf(stderr, "dir: %s\n", debugfs_mountpoint);
+diff --git a/tools/perf/perf.h b/tools/perf/perf.h
+index 32bd102..36c34f3 100644
+--- a/tools/perf/perf.h
++++ b/tools/perf/perf.h
+@@ -198,6 +198,8 @@ extern bool perf_host, perf_guest;
+ extern const char perf_version_string[];
+ void pthread__unblock_sigwinch(void);
++const char *perf_resolve_binary(const char *path, char *rpath, size_t max_size);
++int perf_open_binary(const char *path, int flags, int mode);
+ #include "util/target.h"
+diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
+index d102716..65260ba 100644
+--- a/tools/perf/util/annotate.c
++++ b/tools/perf/util/annotate.c
+@@ -15,6 +15,7 @@
+ #include "debug.h"
+ #include "annotate.h"
+ #include "evsel.h"
++#include "perf.h"
+ #include <pthread.h>
+ #include <linux/bitops.h>
+@@ -831,10 +832,12 @@ int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize)
+       struct dso *dso = map->dso;
+       char *filename = dso__build_id_filename(dso, NULL, 0);
+       bool free_filename = true;
++      const char *dso_name;
+       char command[PATH_MAX * 2];
+       FILE *file;
+       int err = 0;
+       char symfs_filename[PATH_MAX];
++      char dso_namebuf[PATH_MAX];
+       if (filename) {
+               snprintf(symfs_filename, sizeof(symfs_filename), "%s%s",
+@@ -864,6 +867,11 @@ fallback:
+               free_filename = false;
+       }
++      dso_name = perf_resolve_binary(filename, dso_namebuf, sizeof(dso_namebuf));
++      if (dso_name == dso_namebuf)
++              snprintf(symfs_filename, sizeof(symfs_filename), "%s%s",
++                       symbol_conf.symfs, dso_name);
++
+       if (dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS) {
+               char bf[BUILD_ID_SIZE * 2 + 16] = " with build id ";
+               char *build_id_msg = NULL;
+@@ -889,7 +897,7 @@ fallback:
+       }
+       pr_debug("%s: filename=%s, sym=%s, start=%#" PRIx64 ", end=%#" PRIx64 "\n", __func__,
+-               filename, sym->name, map->unmap_ip(map, sym->start),
++               dso_name, sym->name, map->unmap_ip(map, sym->start),
+                map->unmap_ip(map, sym->end));
+       pr_debug("annotating [%p] %30s : [%p] %30s\n",
+@@ -899,14 +907,14 @@ fallback:
+                "%s %s%s --start-address=0x%016" PRIx64
+                " --stop-address=0x%016" PRIx64
+                " -d %s %s -C %s|grep -v %s|expand",
+-               objdump_path ? objdump_path : "objdump",
++               objdump_path ? objdump_path : "x86_64-ucb-akaros-objdump",
+                disassembler_style ? "-M " : "",
+                disassembler_style ? disassembler_style : "",
+                map__rip_2objdump(map, sym->start),
+                map__rip_2objdump(map, sym->end+1),
+                symbol_conf.annotate_asm_raw ? "" : "--no-show-raw",
+                symbol_conf.annotate_src ? "-S" : "",
+-               symfs_filename, filename);
++               symfs_filename, dso_name);
+       pr_debug("Executing: %s\n", command);
+diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
+index 4b12bf8..211972b 100644
+--- a/tools/perf/util/symbol-elf.c
++++ b/tools/perf/util/symbol-elf.c
+@@ -7,6 +7,7 @@
+ #include "symbol.h"
+ #include "debug.h"
++#include "perf.h"
+ #ifndef NT_GNU_BUILD_ID
+ #define NT_GNU_BUILD_ID 3
+@@ -550,7 +551,7 @@ int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name,
+       Elf *elf;
+       int fd;
+-      fd = open(name, O_RDONLY);
++      fd = perf_open_binary(name, O_RDONLY, 0);
+       if (fd < 0)
+               return -1;
+@@ -624,6 +625,11 @@ out_close:
+       return err;
+ }
++static int dso__is_kernel_mmap(struct map *map)
++{
++      return map->start >= 0xffffffffc0000000;
++}
++
+ int dso__load_sym(struct dso *dso, struct map *map,
+                 struct symsrc *syms_ss, struct symsrc *runtime_ss,
+                 symbol_filter_t filter, int kmodule)
+@@ -633,6 +639,7 @@ int dso__load_sym(struct dso *dso, struct map *map,
+       struct dso *curr_dso = dso;
+       Elf_Data *symstrs, *secstrs;
+       uint32_t nr_syms;
++      int is_kernel_map = dso__is_kernel_mmap(map);
+       int err = -1;
+       uint32_t idx;
+       GElf_Ehdr ehdr;
+@@ -793,8 +800,9 @@ int dso__load_sym(struct dso *dso, struct map *map,
+                       goto new_symbol;
+               }
+-              if ((used_opd && runtime_ss->adjust_symbols)
+-                              || (!used_opd && syms_ss->adjust_symbols)) {
++              if (!is_kernel_map &&
++                  ((used_opd && runtime_ss->adjust_symbols)
++                   || (!used_opd && syms_ss->adjust_symbols))) {
+                       pr_debug4("%s: adjusting symbol: st_value: %#" PRIx64 " "
+                                 "sh_addr: %#" PRIx64 " sh_offset: %#" PRIx64 "\n", __func__,
+                                 (u64)sym.st_value, (u64)shdr.sh_addr,