symbol.c (b30d7a77c53ec04a6d94683d7680ec406b7f3ac8) symbol.c (78a175c4623f66722709494295a0f6754b46f858)
1// SPDX-License-Identifier: GPL-2.0
2#include <dirent.h>
3#include <errno.h>
4#include <stdlib.h>
5#include <stdio.h>
6#include <string.h>
7#include <linux/capability.h>
8#include <linux/kernel.h>

--- 426 unchanged lines hidden (view full) ---

435 struct rb_node *n = rb_next(&sym->rb_node);
436
437 if (n)
438 return rb_entry(n, struct symbol, rb_node);
439
440 return NULL;
441}
442
1// SPDX-License-Identifier: GPL-2.0
2#include <dirent.h>
3#include <errno.h>
4#include <stdlib.h>
5#include <stdio.h>
6#include <string.h>
7#include <linux/capability.h>
8#include <linux/kernel.h>

--- 426 unchanged lines hidden (view full) ---

435 struct rb_node *n = rb_next(&sym->rb_node);
436
437 if (n)
438 return rb_entry(n, struct symbol, rb_node);
439
440 return NULL;
441}
442
443static void symbols__insert_by_name(struct rb_root_cached *symbols, struct symbol *sym)
443static int symbols__sort_name_cmp(const void *vlhs, const void *vrhs)
444{
444{
445 struct rb_node **p = &symbols->rb_root.rb_node;
446 struct rb_node *parent = NULL;
447 struct symbol_name_rb_node *symn, *s;
448 bool leftmost = true;
445 const struct symbol *lhs = *((const struct symbol **)vlhs);
446 const struct symbol *rhs = *((const struct symbol **)vrhs);
449
447
450 symn = container_of(sym, struct symbol_name_rb_node, sym);
451
452 while (*p != NULL) {
453 parent = *p;
454 s = rb_entry(parent, struct symbol_name_rb_node, rb_node);
455 if (strcmp(sym->name, s->sym.name) < 0)
456 p = &(*p)->rb_left;
457 else {
458 p = &(*p)->rb_right;
459 leftmost = false;
460 }
461 }
462 rb_link_node(&symn->rb_node, parent, p);
463 rb_insert_color_cached(&symn->rb_node, symbols, leftmost);
448 return strcmp(lhs->name, rhs->name);
464}
465
449}
450
466static void symbols__sort_by_name(struct rb_root_cached *symbols,
467 struct rb_root_cached *source)
451static struct symbol **symbols__sort_by_name(struct rb_root_cached *source, size_t *len)
468{
469 struct rb_node *nd;
452{
453 struct rb_node *nd;
454 struct symbol **result;
455 size_t i = 0, size = 0;
470
456
457 for (nd = rb_first_cached(source); nd; nd = rb_next(nd))
458 size++;
459
460 result = malloc(sizeof(*result) * size);
461 if (!result)
462 return NULL;
463
471 for (nd = rb_first_cached(source); nd; nd = rb_next(nd)) {
472 struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
464 for (nd = rb_first_cached(source); nd; nd = rb_next(nd)) {
465 struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
473 symbols__insert_by_name(symbols, pos);
466
467 result[i++] = pos;
474 }
468 }
469 qsort(result, size, sizeof(*result), symbols__sort_name_cmp);
470 *len = size;
471 return result;
475}
476
477int symbol__match_symbol_name(const char *name, const char *str,
478 enum symbol_tag_include includes)
479{
480 const char *versioning;
481
482 if (includes == SYMBOL_TAG_INCLUDE__DEFAULT_ONLY &&
483 (versioning = strstr(name, "@@"))) {
484 int len = strlen(str);
485
486 if (len < versioning - name)
487 len = versioning - name;
488
489 return arch__compare_symbol_names_n(name, str, len);
490 } else
491 return arch__compare_symbol_names(name, str);
492}
493
472}
473
474int symbol__match_symbol_name(const char *name, const char *str,
475 enum symbol_tag_include includes)
476{
477 const char *versioning;
478
479 if (includes == SYMBOL_TAG_INCLUDE__DEFAULT_ONLY &&
480 (versioning = strstr(name, "@@"))) {
481 int len = strlen(str);
482
483 if (len < versioning - name)
484 len = versioning - name;
485
486 return arch__compare_symbol_names_n(name, str, len);
487 } else
488 return arch__compare_symbol_names(name, str);
489}
490
494static struct symbol *symbols__find_by_name(struct rb_root_cached *symbols,
491static struct symbol *symbols__find_by_name(struct symbol *symbols[],
492 size_t symbols_len,
495 const char *name,
493 const char *name,
496 enum symbol_tag_include includes)
494 enum symbol_tag_include includes,
495 size_t *found_idx)
497{
496{
498 struct rb_node *n;
499 struct symbol_name_rb_node *s = NULL;
497 size_t i, lower = 0, upper = symbols_len;
498 struct symbol *s = NULL;
500
499
501 if (symbols == NULL)
500 if (found_idx)
501 *found_idx = SIZE_MAX;
502
503 if (!symbols_len)
502 return NULL;
503
504 return NULL;
505
504 n = symbols->rb_root.rb_node;
505
506 while (n) {
506 while (lower < upper) {
507 int cmp;
508
507 int cmp;
508
509 s = rb_entry(n, struct symbol_name_rb_node, rb_node);
510 cmp = symbol__match_symbol_name(s->sym.name, name, includes);
509 i = (lower + upper) / 2;
510 cmp = symbol__match_symbol_name(symbols[i]->name, name, includes);
511
512 if (cmp > 0)
511
512 if (cmp > 0)
513 n = n->rb_left;
513 upper = i;
514 else if (cmp < 0)
514 else if (cmp < 0)
515 n = n->rb_right;
516 else
515 lower = i + 1;
516 else {
517 if (found_idx)
518 *found_idx = i;
519 s = symbols[i];
517 break;
520 break;
521 }
518 }
522 }
519
520 if (n == NULL)
521 return NULL;
522
523 if (includes != SYMBOL_TAG_INCLUDE__DEFAULT_ONLY)
523 if (s && includes != SYMBOL_TAG_INCLUDE__DEFAULT_ONLY) {
524 /* return first symbol that has same name (if any) */
524 /* return first symbol that has same name (if any) */
525 for (n = rb_prev(n); n; n = rb_prev(n)) {
526 struct symbol_name_rb_node *tmp;
525 for (; i > 0; i--) {
526 struct symbol *tmp = symbols[i - 1];
527
527
528 tmp = rb_entry(n, struct symbol_name_rb_node, rb_node);
529 if (arch__compare_symbol_names(tmp->sym.name, s->sym.name))
528 if (!arch__compare_symbol_names(tmp->name, s->name)) {
529 if (found_idx)
530 *found_idx = i - 1;
531 s = tmp;
532 } else
530 break;
533 break;
531
532 s = tmp;
533 }
534 }
534
535 return &s->sym;
535 }
536 assert(!found_idx || !s || s == symbols[*found_idx]);
537 return s;
536}
537
538void dso__reset_find_symbol_cache(struct dso *dso)
539{
540 dso->last_find_result.addr = 0;
541 dso->last_find_result.symbol = NULL;
542}
543

--- 41 unchanged lines hidden (view full) ---

585 return symbols__last(&dso->symbols);
586}
587
588struct symbol *dso__next_symbol(struct symbol *sym)
589{
590 return symbols__next(sym);
591}
592
538}
539
540void dso__reset_find_symbol_cache(struct dso *dso)
541{
542 dso->last_find_result.addr = 0;
543 dso->last_find_result.symbol = NULL;
544}
545

--- 41 unchanged lines hidden (view full) ---

587 return symbols__last(&dso->symbols);
588}
589
590struct symbol *dso__next_symbol(struct symbol *sym)
591{
592 return symbols__next(sym);
593}
594
593struct symbol *symbol__next_by_name(struct symbol *sym)
595struct symbol *dso__next_symbol_by_name(struct dso *dso, size_t *idx)
594{
596{
595 struct symbol_name_rb_node *s = container_of(sym, struct symbol_name_rb_node, sym);
596 struct rb_node *n = rb_next(&s->rb_node);
597 if (*idx + 1 >= dso->symbol_names_len)
598 return NULL;
597
599
598 return n ? &rb_entry(n, struct symbol_name_rb_node, rb_node)->sym : NULL;
600 ++*idx;
601 return dso->symbol_names[*idx];
599}
600
601 /*
602 * Returns first symbol that matched with @name.
603 */
602}
603
604 /*
605 * Returns first symbol that matched with @name.
606 */
604struct symbol *dso__find_symbol_by_name(struct dso *dso, const char *name)
607struct symbol *dso__find_symbol_by_name(struct dso *dso, const char *name, size_t *idx)
605{
608{
606 struct symbol *s = symbols__find_by_name(&dso->symbol_names, name,
607 SYMBOL_TAG_INCLUDE__NONE);
609 struct symbol *s = symbols__find_by_name(dso->symbol_names, dso->symbol_names_len,
610 name, SYMBOL_TAG_INCLUDE__NONE, idx);
608 if (!s)
611 if (!s)
609 s = symbols__find_by_name(&dso->symbol_names, name,
610 SYMBOL_TAG_INCLUDE__DEFAULT_ONLY);
612 s = symbols__find_by_name(dso->symbol_names, dso->symbol_names_len,
613 name, SYMBOL_TAG_INCLUDE__DEFAULT_ONLY, idx);
611 return s;
612}
613
614void dso__sort_by_name(struct dso *dso)
615{
614 return s;
615}
616
617void dso__sort_by_name(struct dso *dso)
618{
616 dso__set_sorted_by_name(dso);
617 return symbols__sort_by_name(&dso->symbol_names, &dso->symbols);
619 mutex_lock(&dso->lock);
620 if (!dso__sorted_by_name(dso)) {
621 size_t len;
622
623 dso->symbol_names = symbols__sort_by_name(&dso->symbols, &len);
624 if (dso->symbol_names) {
625 dso->symbol_names_len = len;
626 dso__set_sorted_by_name(dso);
627 }
628 }
629 mutex_unlock(&dso->lock);
618}
619
620/*
621 * While we find nice hex chars, build a long_val.
622 * Return number of chars processed.
623 */
624static int hex2u64(const char *ptr, u64 *long_val)
625{

--- 2025 unchanged lines hidden (view full) ---

2651
2652 if (symbol_conf.initialized)
2653 return 0;
2654
2655 symbol_conf.priv_size = PERF_ALIGN(symbol_conf.priv_size, sizeof(u64));
2656
2657 symbol__elf_init();
2658
630}
631
632/*
633 * While we find nice hex chars, build a long_val.
634 * Return number of chars processed.
635 */
636static int hex2u64(const char *ptr, u64 *long_val)
637{

--- 2025 unchanged lines hidden (view full) ---

2663
2664 if (symbol_conf.initialized)
2665 return 0;
2666
2667 symbol_conf.priv_size = PERF_ALIGN(symbol_conf.priv_size, sizeof(u64));
2668
2669 symbol__elf_init();
2670
2659 if (symbol_conf.sort_by_name)
2660 symbol_conf.priv_size += (sizeof(struct symbol_name_rb_node) -
2661 sizeof(struct symbol));
2662
2663 if (symbol_conf.try_vmlinux_path && vmlinux_path__init(env) < 0)
2664 return -1;
2665
2666 if (symbol_conf.field_sep && *symbol_conf.field_sep == '.') {
2667 pr_err("'.' is the only non valid --field-separator argument\n");
2668 return -1;
2669 }
2670

--- 142 unchanged lines hidden ---
2671 if (symbol_conf.try_vmlinux_path && vmlinux_path__init(env) < 0)
2672 return -1;
2673
2674 if (symbol_conf.field_sep && *symbol_conf.field_sep == '.') {
2675 pr_err("'.' is the only non valid --field-separator argument\n");
2676 return -1;
2677 }
2678

--- 142 unchanged lines hidden ---