lkml.org 
[lkml]   [2017]   [Jan]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH perf/core] perf-probe: Fix to get correct modname from elf header
Date
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 <mhiramat@kernel.org>
---
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);
\
 
 \ /
  Last update: 2017-01-02 16:22    [W:0.043 / U:0.176 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site