perf tools: Add support to read build id from compressed elf
authorJiri Olsa <jolsa@kernel.org>
Mon, 14 Dec 2020 10:54:48 +0000 (11:54 +0100)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Thu, 17 Dec 2020 17:36:17 +0000 (14:36 -0300)
Adding support to decompress file before reading build id.

Adding filename__read_build_id and change its current versions to
read_build_id.

Shutting down stderr output of perf list in the shell test:
  82: Check open filename arg using perf trace + vfs_getname          : Ok

because with decompression code in the place we the
filename__read_build_id function is more verbose in case
of error and the test did not account for that.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Alexei Budankov <abudankov@huawei.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Michael Petlan <mpetlan@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Song Liu <songliubraving@fb.com>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lore.kernel.org/lkml/20201214105457.543111-7-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/tests/shell/trace+probe_vfs_getname.sh
tools/perf/util/symbol-elf.c

index 11cc2af..3d31c1d 100755 (executable)
@@ -20,7 +20,7 @@ skip_if_no_perf_trace || exit 2
 file=$(mktemp /tmp/temporary_file.XXXXX)
 
 trace_open_vfs_getname() {
-       evts=$(echo $(perf list syscalls:sys_enter_open* 2>&1 | egrep 'open(at)? ' | sed -r 's/.*sys_enter_([a-z]+) +\[.*$/\1/') | sed 's/ /,/')
+       evts=$(echo $(perf list syscalls:sys_enter_open* 2>/dev/null | egrep 'open(at)? ' | sed -r 's/.*sys_enter_([a-z]+) +\[.*$/\1/') | sed 's/ /,/')
        perf trace -e $evts touch $file 2>&1 | \
        egrep " +[0-9]+\.[0-9]+ +\( +[0-9]+\.[0-9]+ ms\): +touch\/[0-9]+ open(at)?\((dfd: +CWD, +)?filename: +${file}, +flags: CREAT\|NOCTTY\|NONBLOCK\|WRONLY, +mode: +IRUGO\|IWUGO\) += +[0-9]+$"
 }
index 44dd86a..f3577f7 100644 (file)
@@ -534,7 +534,7 @@ out:
 
 #ifdef HAVE_LIBBFD_BUILDID_SUPPORT
 
-int filename__read_build_id(const char *filename, struct build_id *bid)
+static int read_build_id(const char *filename, struct build_id *bid)
 {
        size_t size = sizeof(bid->data);
        int err = -1;
@@ -563,7 +563,7 @@ out_close:
 
 #else // HAVE_LIBBFD_BUILDID_SUPPORT
 
-int filename__read_build_id(const char *filename, struct build_id *bid)
+static int read_build_id(const char *filename, struct build_id *bid)
 {
        size_t size = sizeof(bid->data);
        int fd, err = -1;
@@ -595,6 +595,39 @@ out:
 
 #endif // HAVE_LIBBFD_BUILDID_SUPPORT
 
+int filename__read_build_id(const char *filename, struct build_id *bid)
+{
+       struct kmod_path m = { .name = NULL, };
+       char path[PATH_MAX];
+       int err;
+
+       if (!filename)
+               return -EFAULT;
+
+       err = kmod_path__parse(&m, filename);
+       if (err)
+               return -1;
+
+       if (m.comp) {
+               int error = 0, fd;
+
+               fd = filename__decompress(filename, path, sizeof(path), m.comp, &error);
+               if (fd < 0) {
+                       pr_debug("Failed to decompress (error %d) %s\n",
+                                error, filename);
+                       return -1;
+               }
+               close(fd);
+               filename = path;
+       }
+
+       err = read_build_id(filename, bid);
+
+       if (m.comp)
+               unlink(filename);
+       return err;
+}
+
 int sysfs__read_build_id(const char *filename, struct build_id *bid)
 {
        size_t size = sizeof(bid->data);