From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750974AbdAEHxt (ORCPT ); Thu, 5 Jan 2017 02:53:49 -0500 Received: from terminus.zytor.com ([198.137.202.10]:57150 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751079AbdAEHx3 (ORCPT ); Thu, 5 Jan 2017 02:53:29 -0500 Date: Wed, 4 Jan 2017 23:50:45 -0800 From: tip-bot for Masami Hiramatsu Message-ID: Cc: linux-kernel@vger.kernel.org, mingo@kernel.org, mhiramat@kernel.org, peterz@infradead.org, jolsa@redhat.com, acme@redhat.com, tglx@linutronix.de, namhyung@kernel.org, hpa@zytor.com Reply-To: hpa@zytor.com, namhyung@kernel.org, tglx@linutronix.de, mhiramat@kernel.org, mingo@kernel.org, linux-kernel@vger.kernel.org, acme@redhat.com, jolsa@redhat.com, peterz@infradead.org In-Reply-To: <148337043836.6752.383495516397005695.stgit@devbox> References: <148337043836.6752.383495516397005695.stgit@devbox> To: linux-tip-commits@vger.kernel.org Subject: [tip:perf/urgent] perf probe: Fix to get correct modname from elf header Git-Commit-ID: 1f2ed153b916c95a49a1ca9d7107738664224b7f X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit-ID: 1f2ed153b916c95a49a1ca9d7107738664224b7f Gitweb: http://git.kernel.org/tip/1f2ed153b916c95a49a1ca9d7107738664224b7f Author: Masami Hiramatsu AuthorDate: Tue, 3 Jan 2017 00:20:49 +0900 Committer: Arnaldo Carvalho de Melo CommitDate: Mon, 2 Jan 2017 14:09:17 -0300 perf probe: Fix to get correct modname from elf header Since 'perf probe' supports cross-arch probes, it is possible to analyze different arch kernel image which has different bits-per-long. In that case, it fails to get the module name because it uses the MOD_NAME_OFFSET macro based on the host machine bits-per-long, instead of the target arch bits-per-long. This fixes above issue by changing modname-offset based on the target archs bit width. This is ok because linux kernel uses LP64 model on 64bit arch. E.g. without this (on x86_64, and target module is arm32): $ perf probe -m build-arm/fs/configfs/configfs.ko -D configfs_lookup p:probe/configfs_lookup :configfs_lookup+0 ^-Here is an empty module name. With this fix, you can see correct module name: $ perf probe -m build-arm/fs/configfs/configfs.ko -D configfs_lookup p:probe/configfs_lookup configfs:configfs_lookup+0 Signed-off-by: Masami Hiramatsu Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/148337043836.6752.383495516397005695.stgit@devbox Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/probe-event.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index d281ae2..8f81096 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -268,21 +268,6 @@ static bool kprobe_warn_out_range(const char *symbol, unsigned long address) } /* - * NOTE: - * '.gnu.linkonce.this_module' section of kernel module elf directly - * maps to 'struct module' from linux/module.h. This section contains - * actual module name which will be used by kernel after loading it. - * But, we cannot use 'struct module' here since linux/module.h is not - * exposed to user-space. Offset of 'name' has remained same from long - * time, so hardcoding it here. - */ -#ifdef __LP64__ -#define MOD_NAME_OFFSET 24 -#else -#define MOD_NAME_OFFSET 12 -#endif - -/* * @module can be module name of module file path. In case of path, * inspect elf and find out what is actual module name. * Caller has to free mod_name after using it. @@ -296,6 +281,7 @@ static char *find_module_name(const char *module) Elf_Data *data; Elf_Scn *sec; char *mod_name = NULL; + int name_offset; fd = open(module, O_RDONLY); if (fd < 0) @@ -317,7 +303,21 @@ static char *find_module_name(const char *module) if (!data || !data->d_buf) goto ret_err; - mod_name = strdup((char *)data->d_buf + MOD_NAME_OFFSET); + /* + * NOTE: + * '.gnu.linkonce.this_module' section of kernel module elf directly + * maps to 'struct module' from linux/module.h. This section contains + * actual module name which will be used by kernel after loading it. + * But, we cannot use 'struct module' here since linux/module.h is not + * exposed to user-space. Offset of 'name' has remained same from long + * time, so hardcoding it here. + */ + if (ehdr.e_ident[EI_CLASS] == ELFCLASS32) + name_offset = 12; + else /* expect ELFCLASS64 by default */ + name_offset = 24; + + mod_name = strdup((char *)data->d_buf + name_offset); ret_err: elf_end(elf);