perf tools: Make it possible to read object code from kernel modules
The new "object code reading" test shows that it is not possible to read object code from kernel modules. That is because the mappings do not map to the dsos. This patch fixes that. This involves identifying and flagging relocatable (ELF type ET_REL) files (e.g. kernel modules) for symbol adjustment and updating map__rip_2objdump() accordingly. The kmodule parameter of dso__load_sym() is taken into use and the module map altered to map to the dso. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/1375875537-4509-7-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:

committed by
Arnaldo Carvalho de Melo

parent
d380b34830
commit
0131c4ec79
@@ -599,11 +599,13 @@ int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name,
|
||||
if (dso->kernel == DSO_TYPE_USER) {
|
||||
GElf_Shdr shdr;
|
||||
ss->adjust_symbols = (ehdr.e_type == ET_EXEC ||
|
||||
ehdr.e_type == ET_REL ||
|
||||
elf_section_by_name(elf, &ehdr, &shdr,
|
||||
".gnu.prelink_undo",
|
||||
NULL) != NULL);
|
||||
} else {
|
||||
ss->adjust_symbols = ehdr.e_type == ET_EXEC;
|
||||
ss->adjust_symbols = ehdr.e_type == ET_EXEC ||
|
||||
ehdr.e_type == ET_REL;
|
||||
}
|
||||
|
||||
ss->name = strdup(name);
|
||||
@@ -676,6 +678,14 @@ int dso__load_sym(struct dso *dso, struct map *map,
|
||||
bool remap_kernel = false, adjust_kernel_syms = false;
|
||||
|
||||
dso->symtab_type = syms_ss->type;
|
||||
dso->rel = syms_ss->ehdr.e_type == ET_REL;
|
||||
|
||||
/*
|
||||
* Modules may already have symbols from kallsyms, but those symbols
|
||||
* have the wrong values for the dso maps, so remove them.
|
||||
*/
|
||||
if (kmodule && syms_ss->symtab)
|
||||
symbols__delete(&dso->symbols[map->type]);
|
||||
|
||||
if (!syms_ss->symtab) {
|
||||
syms_ss->symtab = syms_ss->dynsym;
|
||||
@@ -828,11 +838,24 @@ int dso__load_sym(struct dso *dso, struct map *map,
|
||||
map_groups__insert(kmap->kmaps, map);
|
||||
}
|
||||
|
||||
/*
|
||||
* The initial module mapping is based on
|
||||
* /proc/modules mapped to offset zero.
|
||||
* Overwrite it to map to the module dso.
|
||||
*/
|
||||
if (remap_kernel && kmodule) {
|
||||
remap_kernel = false;
|
||||
map->pgoff = shdr.sh_offset;
|
||||
}
|
||||
|
||||
curr_map = map;
|
||||
curr_dso = dso;
|
||||
goto new_symbol;
|
||||
}
|
||||
|
||||
if (!kmap)
|
||||
goto new_symbol;
|
||||
|
||||
snprintf(dso_name, sizeof(dso_name),
|
||||
"%s%s", dso->short_name, section_name);
|
||||
|
||||
|
Reference in New Issue
Block a user