]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - tools/perf/util/symbol.c
Merge tag 'armsoc-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
[karo-tx-linux.git] / tools / perf / util / symbol.c
index 2cb7665e99739932e6d9330754f6fb8c67aa0c24..e7a98dbd2aed9133d99f38b71b3cac9fb297e0d6 100644 (file)
@@ -90,6 +90,17 @@ static int prefix_underscores_count(const char *str)
        return tail - str;
 }
 
+int __weak arch__compare_symbol_names(const char *namea, const char *nameb)
+{
+       return strcmp(namea, nameb);
+}
+
+int __weak arch__compare_symbol_names_n(const char *namea, const char *nameb,
+                                       unsigned int n)
+{
+       return strncmp(namea, nameb, n);
+}
+
 int __weak arch__choose_best_symbol(struct symbol *syma,
                                    struct symbol *symb __maybe_unused)
 {
@@ -399,8 +410,26 @@ static void symbols__sort_by_name(struct rb_root *symbols,
        }
 }
 
+int symbol__match_symbol_name(const char *name, const char *str,
+                             enum symbol_tag_include includes)
+{
+       const char *versioning;
+
+       if (includes == SYMBOL_TAG_INCLUDE__DEFAULT_ONLY &&
+           (versioning = strstr(name, "@@"))) {
+               int len = strlen(str);
+
+               if (len < versioning - name)
+                       len = versioning - name;
+
+               return arch__compare_symbol_names_n(name, str, len);
+       } else
+               return arch__compare_symbol_names(name, str);
+}
+
 static struct symbol *symbols__find_by_name(struct rb_root *symbols,
-                                           const char *name)
+                                           const char *name,
+                                           enum symbol_tag_include includes)
 {
        struct rb_node *n;
        struct symbol_name_rb_node *s = NULL;
@@ -414,11 +443,11 @@ static struct symbol *symbols__find_by_name(struct rb_root *symbols,
                int cmp;
 
                s = rb_entry(n, struct symbol_name_rb_node, rb_node);
-               cmp = arch__compare_symbol_names(name, s->sym.name);
+               cmp = symbol__match_symbol_name(s->sym.name, name, includes);
 
-               if (cmp < 0)
+               if (cmp > 0)
                        n = n->rb_left;
-               else if (cmp > 0)
+               else if (cmp < 0)
                        n = n->rb_right;
                else
                        break;
@@ -427,16 +456,17 @@ static struct symbol *symbols__find_by_name(struct rb_root *symbols,
        if (n == NULL)
                return NULL;
 
-       /* return first symbol that has same name (if any) */
-       for (n = rb_prev(n); n; n = rb_prev(n)) {
-               struct symbol_name_rb_node *tmp;
+       if (includes != SYMBOL_TAG_INCLUDE__DEFAULT_ONLY)
+               /* return first symbol that has same name (if any) */
+               for (n = rb_prev(n); n; n = rb_prev(n)) {
+                       struct symbol_name_rb_node *tmp;
 
-               tmp = rb_entry(n, struct symbol_name_rb_node, rb_node);
-               if (arch__compare_symbol_names(tmp->sym.name, s->sym.name))
-                       break;
+                       tmp = rb_entry(n, struct symbol_name_rb_node, rb_node);
+                       if (arch__compare_symbol_names(tmp->sym.name, s->sym.name))
+                               break;
 
-               s = tmp;
-       }
+                       s = tmp;
+               }
 
        return &s->sym;
 }
@@ -466,7 +496,7 @@ void dso__insert_symbol(struct dso *dso, enum map_type type, struct symbol *sym)
 struct symbol *dso__find_symbol(struct dso *dso,
                                enum map_type type, u64 addr)
 {
-       if (dso->last_find_result[type].addr != addr) {
+       if (dso->last_find_result[type].addr != addr || dso->last_find_result[type].symbol == NULL) {
                dso->last_find_result[type].addr   = addr;
                dso->last_find_result[type].symbol = symbols__find(&dso->symbols[type], addr);
        }
@@ -503,7 +533,12 @@ struct symbol *symbol__next_by_name(struct symbol *sym)
 struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type,
                                        const char *name)
 {
-       return symbols__find_by_name(&dso->symbol_names[type], name);
+       struct symbol *s = symbols__find_by_name(&dso->symbol_names[type], name,
+                                                SYMBOL_TAG_INCLUDE__NONE);
+       if (!s)
+               s = symbols__find_by_name(&dso->symbol_names[type], name,
+                                         SYMBOL_TAG_INCLUDE__DEFAULT_ONLY);
+       return s;
 }
 
 void dso__sort_by_name(struct dso *dso, enum map_type type)
@@ -1075,8 +1110,9 @@ static int validate_kcore_addresses(const char *kallsyms_filename,
        if (kmap->ref_reloc_sym && kmap->ref_reloc_sym->name) {
                u64 start;
 
-               start = kallsyms__get_function_start(kallsyms_filename,
-                                                    kmap->ref_reloc_sym->name);
+               if (kallsyms__get_function_start(kallsyms_filename,
+                                                kmap->ref_reloc_sym->name, &start))
+                       return -ENOENT;
                if (start != kmap->ref_reloc_sym->addr)
                        return -EINVAL;
        }
@@ -1248,9 +1284,7 @@ static int kallsyms__delta(struct map *map, const char *filename, u64 *delta)
        if (!kmap->ref_reloc_sym || !kmap->ref_reloc_sym->name)
                return 0;
 
-       addr = kallsyms__get_function_start(filename,
-                                           kmap->ref_reloc_sym->name);
-       if (!addr)
+       if (kallsyms__get_function_start(filename, kmap->ref_reloc_sym->name, &addr))
                return -1;
 
        *delta = addr - kmap->ref_reloc_sym->addr;
@@ -1528,10 +1562,6 @@ int dso__load(struct dso *dso, struct map *map)
        if (!runtime_ss && syms_ss)
                runtime_ss = syms_ss;
 
-       if (syms_ss && syms_ss->type == DSO_BINARY_TYPE__BUILD_ID_CACHE)
-               if (dso__build_id_is_kmod(dso, name, PATH_MAX))
-                       kmod = true;
-
        if (syms_ss)
                ret = dso__load_sym(dso, map, syms_ss, runtime_ss, kmod);
        else