When loading a dso it'll look for symbol tables of all possible types.
However it's just wasted of time to check incompatible types - like
trying kernel module when loading user library.

Cc: Stephane Eranian <eran...@google.com>
Cc: Adrian Hunter <adrian.hun...@intel.com>
Cc: Cody P Schafer <c...@linux.vnet.ibm.com>
Signed-off-by: Namhyung Kim <namhy...@kernel.org>
---
 tools/perf/util/symbol.c | 61 +++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 52 insertions(+), 9 deletions(-)

diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index c3b014712fce..95e249779931 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1251,6 +1251,46 @@ out_failure:
        return -1;
 }
 
+static bool dso__is_compatible_symtab_type(struct dso *dso, bool kmod,
+                                          enum dso_binary_type type)
+{
+       switch (type) {
+       case DSO_BINARY_TYPE__JAVA_JIT:
+       case DSO_BINARY_TYPE__DEBUGLINK:
+       case DSO_BINARY_TYPE__SYSTEM_PATH_DSO:
+       case DSO_BINARY_TYPE__FEDORA_DEBUGINFO:
+       case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO:
+       case DSO_BINARY_TYPE__BUILDID_DEBUGINFO:
+       case DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO:
+               return !kmod && dso->kernel == DSO_TYPE_USER;
+
+       case DSO_BINARY_TYPE__KALLSYMS:
+       case DSO_BINARY_TYPE__VMLINUX:
+       case DSO_BINARY_TYPE__KCORE:
+               return dso->kernel == DSO_TYPE_KERNEL;
+
+       case DSO_BINARY_TYPE__GUEST_KALLSYMS:
+       case DSO_BINARY_TYPE__GUEST_VMLINUX:
+       case DSO_BINARY_TYPE__GUEST_KCORE:
+               return dso->kernel == DSO_TYPE_GUEST_KERNEL;
+
+       case DSO_BINARY_TYPE__GUEST_KMODULE:
+       case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE:
+               /*
+                * kernel modules know their symtab type - it's set when
+                * creating a module dso in machine__new_module().
+                */
+               return kmod && dso->symtab_type == type;
+
+       case DSO_BINARY_TYPE__BUILD_ID_CACHE:
+               return true;
+
+       case DSO_BINARY_TYPE__NOT_FOUND:
+       default:
+               return false;
+       }
+}
+
 int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter)
 {
        char *name;
@@ -1261,6 +1301,7 @@ int dso__load(struct dso *dso, struct map *map, 
symbol_filter_t filter)
        int ss_pos = 0;
        struct symsrc ss_[2];
        struct symsrc *syms_ss = NULL, *runtime_ss = NULL;
+       bool kmod;
 
        dso__set_loaded(dso, map->type);
 
@@ -1301,7 +1342,11 @@ int dso__load(struct dso *dso, struct map *map, 
symbol_filter_t filter)
        if (!name)
                return -1;
 
-       /* Iterate over candidate debug images.
+       kmod = dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE ||
+               dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE;
+
+       /*
+        * Iterate over candidate debug images.
         * Keep track of "interesting" ones (those which have a symtab, dynsym,
         * and/or opd section) for processing.
         */
@@ -1311,6 +1356,9 @@ int dso__load(struct dso *dso, struct map *map, 
symbol_filter_t filter)
 
                enum dso_binary_type symtab_type = binary_type_symtab[i];
 
+               if (!dso__is_compatible_symtab_type(dso, kmod, symtab_type))
+                       continue;
+
                if (dso__read_binary_type_filename(dso, symtab_type,
                                                   root_dir, name, PATH_MAX))
                        continue;
@@ -1353,15 +1401,10 @@ int dso__load(struct dso *dso, struct map *map, 
symbol_filter_t filter)
        if (!runtime_ss && syms_ss)
                runtime_ss = syms_ss;
 
-       if (syms_ss) {
-               int km;
-
-               km = dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE ||
-                    dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE;
-               ret = dso__load_sym(dso, map, syms_ss, runtime_ss, filter, km);
-       } else {
+       if (syms_ss)
+               ret = dso__load_sym(dso, map, syms_ss, runtime_ss, filter, 
kmod);
+       else
                ret = -1;
-       }
 
        if (ret > 0) {
                int nr_plt;
-- 
1.7.11.7

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to