linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: tip-bot for Namhyung Kim <tipbot@zytor.com>
To: linux-tip-commits@vger.kernel.org
Cc: namhyung.kim@lge.com, paulus@samba.org,
	linux-kernel@vger.kernel.org, jolsa@kernel.org, hpa@zytor.com,
	acme@redhat.com, adrian.hunter@intel.com, tglx@linutronix.de,
	mingo@kernel.org, a.p.zijlstra@chello.nl, dsahern@gmail.com,
	eranian@google.com, jolsa@redhat.com, namhyung@kernel.org
Subject: [tip:perf/core] perf symbols: Preparation for compressed kernel module support
Date: Thu, 6 Nov 2014 21:29:52 -0800	[thread overview]
Message-ID: <tip-c00c48fc6e6ef63d83a7417923a06b08089bb34b@git.kernel.org> (raw)
In-Reply-To: <1415063674-17206-2-git-send-email-namhyung@kernel.org>

Commit-ID:  c00c48fc6e6ef63d83a7417923a06b08089bb34b
Gitweb:     http://git.kernel.org/tip/c00c48fc6e6ef63d83a7417923a06b08089bb34b
Author:     Namhyung Kim <namhyung@kernel.org>
AuthorDate: Tue, 4 Nov 2014 10:14:27 +0900
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Tue, 4 Nov 2014 10:15:53 -0300

perf symbols: Preparation for compressed kernel module support

This patch adds basic support to handle compressed kernel module as some
distro (such as Archlinux) carries on it now.  The actual work using
compression library will be added later.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung.kim@lge.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1415063674-17206-2-git-send-email-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/dso.c        | 75 ++++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/dso.h        |  7 +++++
 tools/perf/util/machine.c    | 19 ++++++++++-
 tools/perf/util/symbol-elf.c | 35 ++++++++++++++++++++-
 tools/perf/util/symbol.c     |  8 ++++-
 5 files changed, 141 insertions(+), 3 deletions(-)

diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index 0247acf..36a607c 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -21,8 +21,10 @@ char dso__symtab_origin(const struct dso *dso)
 		[DSO_BINARY_TYPE__BUILDID_DEBUGINFO]		= 'b',
 		[DSO_BINARY_TYPE__SYSTEM_PATH_DSO]		= 'd',
 		[DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE]		= 'K',
+		[DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP]	= 'm',
 		[DSO_BINARY_TYPE__GUEST_KALLSYMS]		= 'g',
 		[DSO_BINARY_TYPE__GUEST_KMODULE]		= 'G',
+		[DSO_BINARY_TYPE__GUEST_KMODULE_COMP]		= 'M',
 		[DSO_BINARY_TYPE__GUEST_VMLINUX]		= 'V',
 	};
 
@@ -112,11 +114,13 @@ int dso__read_binary_type_filename(const struct dso *dso,
 		break;
 
 	case DSO_BINARY_TYPE__GUEST_KMODULE:
+	case DSO_BINARY_TYPE__GUEST_KMODULE_COMP:
 		path__join3(filename, size, symbol_conf.symfs,
 			    root_dir, dso->long_name);
 		break;
 
 	case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE:
+	case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP:
 		__symbol__join_symfs(filename, size, dso->long_name);
 		break;
 
@@ -137,6 +141,77 @@ int dso__read_binary_type_filename(const struct dso *dso,
 	return ret;
 }
 
+static int decompress_dummy(const char *input __maybe_unused,
+			    int output __maybe_unused)
+{
+	return -1;
+}
+
+static const struct {
+	const char *fmt;
+	int (*decompress)(const char *input, int output);
+} compressions[] = {
+	{ "gz", decompress_dummy },
+	{ NULL, },
+};
+
+bool is_supported_compression(const char *ext)
+{
+	unsigned i;
+
+	for (i = 0; compressions[i].fmt; i++) {
+		if (!strcmp(ext, compressions[i].fmt))
+			return true;
+	}
+	return false;
+}
+
+bool is_kmodule_extension(const char *ext)
+{
+	if (strncmp(ext, "ko", 2))
+		return false;
+
+	if (ext[2] == '\0' || (ext[2] == '.' && is_supported_compression(ext+3)))
+		return true;
+
+	return false;
+}
+
+bool is_kernel_module(const char *pathname, bool *compressed)
+{
+	const char *ext = strrchr(pathname, '.');
+
+	if (ext == NULL)
+		return false;
+
+	if (is_supported_compression(ext + 1)) {
+		if (compressed)
+			*compressed = true;
+		ext -= 3;
+	} else if (compressed)
+		*compressed = false;
+
+	return is_kmodule_extension(ext + 1);
+}
+
+bool decompress_to_file(const char *ext, const char *filename, int output_fd)
+{
+	unsigned i;
+
+	for (i = 0; compressions[i].fmt; i++) {
+		if (!strcmp(ext, compressions[i].fmt))
+			return !compressions[i].decompress(filename,
+							   output_fd);
+	}
+	return false;
+}
+
+bool dso__needs_decompress(struct dso *dso)
+{
+	return dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP ||
+		dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE_COMP;
+}
+
 /*
  * Global list of open DSOs and the counter.
  */
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
index a316e4a..3782c82 100644
--- a/tools/perf/util/dso.h
+++ b/tools/perf/util/dso.h
@@ -22,7 +22,9 @@ enum dso_binary_type {
 	DSO_BINARY_TYPE__BUILDID_DEBUGINFO,
 	DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
 	DSO_BINARY_TYPE__GUEST_KMODULE,
+	DSO_BINARY_TYPE__GUEST_KMODULE_COMP,
 	DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE,
+	DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP,
 	DSO_BINARY_TYPE__KCORE,
 	DSO_BINARY_TYPE__GUEST_KCORE,
 	DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO,
@@ -185,6 +187,11 @@ int dso__kernel_module_get_build_id(struct dso *dso, const char *root_dir);
 char dso__symtab_origin(const struct dso *dso);
 int dso__read_binary_type_filename(const struct dso *dso, enum dso_binary_type type,
 				   char *root_dir, char *filename, size_t size);
+bool is_supported_compression(const char *ext);
+bool is_kmodule_extension(const char *ext);
+bool is_kernel_module(const char *pathname, bool *compressed);
+bool decompress_to_file(const char *ext, const char *filename, int output_fd);
+bool dso__needs_decompress(struct dso *dso);
 
 /*
  * The dso__data_* external interface provides following functions:
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 51a6303..946c7d6 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -464,6 +464,7 @@ struct map *machine__new_module(struct machine *machine, u64 start,
 {
 	struct map *map;
 	struct dso *dso = __dsos__findnew(&machine->kernel_dsos, filename);
+	bool compressed;
 
 	if (dso == NULL)
 		return NULL;
@@ -476,6 +477,11 @@ struct map *machine__new_module(struct machine *machine, u64 start,
 		dso->symtab_type = DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE;
 	else
 		dso->symtab_type = DSO_BINARY_TYPE__GUEST_KMODULE;
+
+	/* _KMODULE_COMP should be next to _KMODULE */
+	if (is_kernel_module(filename, &compressed) && compressed)
+		dso->symtab_type++;
+
 	map_groups__insert(&machine->kmaps, map);
 	return map;
 }
@@ -861,8 +867,14 @@ static int map_groups__set_modules_path_dir(struct map_groups *mg,
 			struct map *map;
 			char *long_name;
 
-			if (dot == NULL || strcmp(dot, ".ko"))
+			if (dot == NULL)
 				continue;
+
+			/* On some system, modules are compressed like .ko.gz */
+			if (is_supported_compression(dot + 1) &&
+			    is_kmodule_extension(dot - 2))
+				dot -= 3;
+
 			snprintf(dso_name, sizeof(dso_name), "[%.*s]",
 				 (int)(dot - dent->d_name), dent->d_name);
 
@@ -1044,6 +1056,11 @@ static int machine__process_kernel_mmap_event(struct machine *machine,
 			dot = strrchr(name, '.');
 			if (dot == NULL)
 				goto out_problem;
+			/* On some system, modules are compressed like .ko.gz */
+			if (is_supported_compression(dot + 1))
+				dot -= 3;
+			if (!is_kmodule_extension(dot + 1))
+				goto out_problem;
 			snprintf(short_module_name, sizeof(short_module_name),
 					"[%.*s]", (int)(dot - name), name);
 			strxfrchar(short_module_name, '-', '_');
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index 1e23a5b..efc7eb6 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -546,6 +546,35 @@ static int dso__swap_init(struct dso *dso, unsigned char eidata)
 	return 0;
 }
 
+static int decompress_kmodule(struct dso *dso, const char *name,
+			      enum dso_binary_type type)
+{
+	int fd;
+	const char *ext = strrchr(name, '.');
+	char tmpbuf[] = "/tmp/perf-kmod-XXXXXX";
+
+	if ((type != DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP &&
+	     type != DSO_BINARY_TYPE__GUEST_KMODULE_COMP) ||
+	    type != dso->symtab_type)
+		return -1;
+
+	if (!ext || !is_supported_compression(ext + 1))
+		return -1;
+
+	fd = mkstemp(tmpbuf);
+	if (fd < 0)
+		return -1;
+
+	if (!decompress_to_file(ext + 1, name, fd)) {
+		close(fd);
+		fd = -1;
+	}
+
+	unlink(tmpbuf);
+
+	return fd;
+}
+
 bool symsrc__possibly_runtime(struct symsrc *ss)
 {
 	return ss->dynsym || ss->opdsec;
@@ -571,7 +600,11 @@ int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name,
 	Elf *elf;
 	int fd;
 
-	fd = open(name, O_RDONLY);
+	if (dso__needs_decompress(dso))
+		fd = decompress_kmodule(dso, name, type);
+	else
+		fd = open(name, O_RDONLY);
+
 	if (fd < 0)
 		return -1;
 
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 0783311..c69915c 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -51,7 +51,9 @@ static enum dso_binary_type binary_type_symtab[] = {
 	DSO_BINARY_TYPE__BUILDID_DEBUGINFO,
 	DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
 	DSO_BINARY_TYPE__GUEST_KMODULE,
+	DSO_BINARY_TYPE__GUEST_KMODULE_COMP,
 	DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE,
+	DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP,
 	DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO,
 	DSO_BINARY_TYPE__NOT_FOUND,
 };
@@ -1300,7 +1302,9 @@ static bool dso__is_compatible_symtab_type(struct dso *dso, bool kmod,
 		return dso->kernel == DSO_TYPE_GUEST_KERNEL;
 
 	case DSO_BINARY_TYPE__GUEST_KMODULE:
+	case DSO_BINARY_TYPE__GUEST_KMODULE_COMP:
 	case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE:
+	case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP:
 		/*
 		 * kernel modules know their symtab type - it's set when
 		 * creating a module dso in machine__new_module().
@@ -1368,7 +1372,9 @@ int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter)
 		return -1;
 
 	kmod = dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE ||
-		dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE;
+		dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP ||
+		dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE ||
+		dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE_COMP;
 
 	/*
 	 * Iterate over candidate debug images.

  parent reply	other threads:[~2014-11-07  5:30 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-11-04  1:14 [PATCHSET 0/8] perf tools: Fix build-id matching on vmlinux (v6) Namhyung Kim
2014-11-04  1:14 ` [PATCH 1/8] perf tools: Preparation for compressed kernel module support Namhyung Kim
2014-11-04 10:58   ` Jiri Olsa
2014-11-07  5:29   ` tip-bot for Namhyung Kim [this message]
2014-11-04  1:14 ` [PATCH 2/8] perf tools: Add gzip decompression support for kernel module Namhyung Kim
2014-11-04 11:00   ` Jiri Olsa
2014-11-04 13:42     ` Arnaldo Carvalho de Melo
2014-11-05  2:59       ` Namhyung Kim
2014-11-07  5:30         ` [tip:perf/core] " tip-bot for Namhyung Kim
2014-11-04 14:15   ` [PATCH 2/8] " Arnaldo Carvalho de Melo
2014-11-05  3:04     ` Namhyung Kim
2014-11-04  1:14 ` [PATCH 3/8] perf tools: Rename dsos__write_buildid_table() Namhyung Kim
2014-11-07  5:30   ` [tip:perf/core] perf build-id: " tip-bot for Namhyung Kim
2014-11-04  1:14 ` [PATCH 4/8] perf build-id: Move build-id related functions to util/build-id.c Namhyung Kim
2014-11-07  5:30   ` [tip:perf/core] " tip-bot for Namhyung Kim
2014-11-04  1:14 ` [PATCH 5/8] perf tools: Move disable_buildid_cache() " Namhyung Kim
2014-11-04  1:14 ` [PATCH 6/8] perf record: Do not save pathname in ./debug/.build-id directory for vmlinux Namhyung Kim
2014-11-04 13:29   ` Arnaldo Carvalho de Melo
2014-11-05  2:54     ` Namhyung Kim
2014-11-07  5:30   ` [tip:perf/core] perf record: Do not save pathname in ./debug/ .build-id " tip-bot for Namhyung Kim
2014-11-04  1:14 ` [PATCH 7/8] perf tools: Fix build-id matching on vmlinux Namhyung Kim
2014-11-07  5:31   ` [tip:perf/core] " tip-bot for Namhyung Kim
2014-11-04  1:14 ` [PATCH 8/8] perf tools: Make vmlinux short name more like kallsyms short name Namhyung Kim
2014-11-07  5:31   ` [tip:perf/core] " tip-bot for Namhyung Kim
  -- strict thread matches above, loose matches on Subject: below --
2014-11-03  7:27 [PATCHSET 0/8] perf tools: Fix build-id matching on vmlinux (v5) Namhyung Kim
2014-11-03  7:27 ` [PATCH 1/8] perf tools: Preparation for compressed kernel module support Namhyung Kim
2014-11-03 13:51   ` Jiri Olsa
2014-11-03 15:01     ` Namhyung Kim
2014-11-03  7:27 ` [PATCH 2/8] perf tools: Add gzip decompression support for kernel module Namhyung Kim
2014-11-03 13:54   ` Jiri Olsa
2014-11-03 15:02     ` Namhyung Kim
2014-11-03  7:27 ` [PATCH 3/8] perf tools: Get rid of unused dsos__hit_all() Namhyung Kim
2014-11-03  7:35   ` Adrian Hunter
2014-11-03  7:39     ` Namhyung Kim
2014-11-03  7:51       ` Adrian Hunter
2014-11-03  7:27 ` [PATCH 4/8] perf tools: Rename dsos__write_buildid_table() Namhyung Kim
2014-11-03  7:27 ` [PATCH 5/8] perf build-id: Move build-id related functions to util/build-id.c Namhyung Kim
2014-11-03  7:27 ` [PATCH 6/8] perf record: Do not save pathname in ./debug/.build-id directory for vmlinux Namhyung Kim
2014-11-03  7:27 ` [PATCH 7/8] perf tools: Fix build-id matching on vmlinux Namhyung Kim
2014-11-03  7:27 ` [PATCH 8/8] perf tools: Make vmlinux short name more like kallsyms short name Namhyung Kim
2014-09-22  8:04 [PATCH v4] perf tools: Fix build-id matching on vmlinux Namhyung Kim
2014-09-24  7:33 ` Ingo Molnar
2014-09-29  4:45   ` Namhyung Kim

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=tip-c00c48fc6e6ef63d83a7417923a06b08089bb34b@git.kernel.org \
    --to=tipbot@zytor.com \
    --cc=a.p.zijlstra@chello.nl \
    --cc=acme@redhat.com \
    --cc=adrian.hunter@intel.com \
    --cc=dsahern@gmail.com \
    --cc=eranian@google.com \
    --cc=hpa@zytor.com \
    --cc=jolsa@kernel.org \
    --cc=jolsa@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tip-commits@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=namhyung.kim@lge.com \
    --cc=namhyung@kernel.org \
    --cc=paulus@samba.org \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).