From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756127AbdABPVs (ORCPT ); Mon, 2 Jan 2017 10:21:48 -0500 Received: from mail.kernel.org ([198.145.29.136]:47694 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755969AbdABPVr (ORCPT ); Mon, 2 Jan 2017 10:21:47 -0500 From: Masami Hiramatsu To: Arnaldo Carvalho de Melo Cc: Masami Hiramatsu , linux-kernel@vger.kernel.org, Jiri Olsa , Peter Zijlstra , Ingo Molnar , Namhyung Kim Subject: [PATCH perf/core] perf-probe: Fix to get correct modname from elf header Date: Tue, 3 Jan 2017 00:20:49 +0900 Message-Id: <148337043836.6752.383495516397005695.stgit@devbox> X-Mailer: git-send-email 2.9.3 User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Since perf-probe supports cross-arch probe, it is possible to analyze different arch kernel image which has different bits-per-long. In that case, it fails to get module name because perf probe uses MOD_NAME_OFFSET macro based on host machines bits-per-long, instead of the target archs bits-per-long. This fixes above issue by changing modname-offset based on the target archs bitwidth. 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 --- 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);