30 #include <linux/bitops.h> 31 #include <linux/kernel.h> 40 #define LARROW_CHAR ((unsigned char)',') 41 #define RARROW_CHAR ((unsigned char)'+') 42 #define DARROW_CHAR ((unsigned char)'.') 43 #define UARROW_CHAR ((unsigned char)'-') 90 struct ins *new_instructions;
91 size_t new_nr_allocated;
94 goto grow_from_non_allocated_table;
97 new_instructions = realloc(arch->
instructions, new_nr_allocated *
sizeof(
struct ins));
98 if (new_instructions == NULL)
101 out_update_instructions:
106 grow_from_non_allocated_table:
108 new_instructions = calloc(new_nr_allocated,
sizeof(
struct ins));
109 if (new_instructions == NULL)
113 goto out_update_instructions;
125 ins->
name = strdup(name);
187 return scnprintf(bf, size,
"%-6s %s", ins->
name, ops->
raw);
209 char *endptr, *tok, *
name;
217 name = strchr(endptr,
'<');
227 tok = strchr(name,
'>');
247 tok = strchr(endptr,
'*');
249 ops->
target.
addr = strtoull(tok + 1, NULL, 16);
263 return scnprintf(bf, size,
"%-6s %s", ins->
name, ops->
target.
name);
265 return scnprintf(bf, size,
"%-6s *%" PRIx64, ins->
name, ops->
target.
addr);
268 static struct ins_ops call_ops = {
285 const char *c = strchr(ops->
raw,
',');
362 c = strchr(ops->
raw,
',');
364 const char *c2 = strchr(c + 1,
',');
376 return scnprintf(bf, size,
"%-6s %.*s%" PRIx64,
381 static struct ins_ops jump_ops = {
393 char *endptr, *
name, *t;
395 if (strstr(raw,
"(%rip)") == NULL)
398 *addrp = strtoull(comment, &endptr, 16);
399 if (endptr == comment)
401 name = strchr(endptr,
'<');
407 t = strchr(name,
'>');
412 *namep = strdup(name);
421 if (ops->
locked.ops == NULL)
429 if (ops->
locked.ins.ops == NULL)
432 if (ops->
locked.ins.ops->parse &&
433 ops->
locked.ins.ops->parse(arch, ops->
locked.ops, ms) < 0)
448 if (ops->
locked.ins.ops == NULL)
453 size - printed, ops->
locked.ops);
470 static struct ins_ops lock_ops = {
478 char *s = strchr(ops->
raw,
','), *
target, *comment, prev;
487 if (ops->
source.raw == NULL)
496 s = strchr(s,
'\0') - 1;
508 goto out_free_source;
513 comment =
ltrim(comment);
532 static struct ins_ops mov_ops = {
539 char *
target, *comment, *s, prev;
541 target = s = ops->
raw;
543 while (s[0] !=
'\0' && !
isspace(s[0]))
558 comment =
ltrim(comment);
571 static struct ins_ops dec_ops = {
579 return scnprintf(bf, size,
"%-6s",
"nop");
582 static struct ins_ops nop_ops = {
586 static struct ins_ops ret_ops = {
602 const struct ins *
ins = insp;
604 return strcmp(name, ins->
name);
609 const struct ins *ia = a;
610 const struct ins *ib = b;
633 return ins ? ins->
ops : NULL;
650 return strcmp(name, arch->
name);
655 const struct arch *aa = a;
656 const struct arch *ab = b;
663 const int nmemb = ARRAY_SIZE(architectures);
670 const int nmemb = ARRAY_SIZE(architectures);
686 INIT_LIST_HEAD(&src->
source);
701 size_t size,
int nr_hists)
722 if (sizeof_sym_hist > SIZE_MAX / nr_hists)
727 src->
histograms = calloc(nr_hists, sizeof_sym_hist) ;
747 pthread_mutex_lock(¬es->
lock);
748 if (notes->
src != NULL) {
755 pthread_mutex_unlock(¬es->
lock);
760 unsigned offset,
unsigned cycles,
774 if (cycles > ch[offset].cycles_max)
777 if (ch[offset].cycles_min) {
778 if (cycles && cycles < ch[offset].cycles_min)
783 if (!have_start && ch[offset].have_start)
785 if (ch[offset].num) {
786 if (have_start && (!ch[offset].have_start ||
787 ch[offset].start > start)) {
791 if (ch[offset].reset < 0xffff)
793 }
else if (have_start &&
794 ch[offset].start < start)
799 ch[offset].
cycles += cycles;
813 if ((addr < sym->
start || addr >= sym->
end) &&
815 pr_debug(
"%s(%d): ERANGE! sym->name=%s, start=%#" PRIx64
", addr=%#" PRIx64
", end=%#" PRIx64
"\n",
816 __func__, __LINE__, sym->
name, sym->
start, addr, sym->
end);
820 offset = addr - sym->
start;
823 pr_debug(
"%s(%d): ENOMEM! sym->name=%s, start=%#" PRIx64
", addr=%#" PRIx64
", end=%#" PRIx64
", func: %d\n",
824 __func__, __LINE__, sym->
name, sym->
start, addr, sym->
end, sym->
type == STT_FUNC);
832 pr_debug3(
"%#" PRIx64
" %s: period++ [addr: %#" PRIx64
", %#" PRIx64
833 ", evidx=%d] => nr_samples: %" PRIu64
", period: %" PRIu64
"\n",
843 if (notes->
src == NULL) {
845 if (notes->
src == NULL)
847 goto alloc_cycles_hist;
862 if (notes->
src == NULL) {
864 if (notes->
src == NULL)
866 goto alloc_histograms;
901 if (cycles_hist == NULL)
903 if (addr < sym->start || addr >= sym->
end)
907 if (start < sym->start || start >= sym->
end)
912 offset = addr - sym->
start;
914 start ? start - sym->
start : 0,
937 (start->
sym == ams->
sym ||
942 pr_debug2(
"BB with bad start: addr %"PRIx64
" start %"PRIx64
" sym %"PRIx64
" saddr %"PRIx64
"\n",
944 start ? start->
addr : 0,
949 pr_debug2(
"account_cycles failed %d\n", err);
958 for (offset = start; offset <= end; offset++) {
972 float ipc = n_insn / ((double)ch->
cycles / (
double)ch->
num);
978 for (offset = start; offset <= end; offset++) {
994 pthread_mutex_lock(¬es->
lock);
1013 pthread_mutex_unlock(¬es->
lock);
1043 if (name[0] ==
'\0')
1048 while ((*rawp)[0] !=
'\0' && !
isspace((*rawp)[0]))
1053 *namep = strdup(name);
1059 *rawp =
ltrim(*rawp);
1064 free((
void *)namep);
1082 void *ptr = (
void *) al - al->
privsize;
1105 size_t size = privsize +
sizeof(*al);
1111 size +=
sizeof(al->samples[0]) * nr;
1115 al = (
void *) al + privsize;
1116 al->privsize = privsize;
1117 al->offset = args->
offset;
1118 al->line = strdup(args->
line);
1120 al->samples_nr = nr;
1151 if (args->
offset != -1) {
1182 return scnprintf(bf, size,
"%-6s %s", dl->
ins.
name, dl->
ops.
raw);
1189 list_add_tail(&al->
node, head);
1195 list_for_each_entry_continue(pos, head,
node)
1234 bool emit_comment =
true;
1254 emit_comment =
false;
1262 printf(
" +%.2f%%", p);
1271 emit_comment =
false;
1279 printf(
" -%.2f%% (p:%.2f%%)", p, 100*(
double)br->
pred / br->
taken);
1287 const u64 addr = start + offset;
1299 struct perf_evsel *evsel, u64 len,
int min_pcnt,
int printed,
1303 static const char *prev_line;
1304 static const char *prev_color;
1307 double max_percent = 0.0;
1308 int i, nr_percent = 1;
1315 if (sample->
percent > max_percent)
1316 max_percent = sample->
percent;
1322 if (max_percent < min_pcnt)
1325 if (max_lines && printed >= max_lines)
1328 if (queue != NULL) {
1329 list_for_each_entry_from(queue, ¬es->
src->
source,
node) {
1333 0, 0, 1, NULL, addr_fmt_width);
1345 if (!prev_line || strcmp(prev_line, al->
path)
1346 || color != prev_color) {
1348 prev_line = al->
path;
1353 for (i = 0; i < nr_percent; i++) {
1372 }
else if (max_lines && printed >= max_lines)
1384 printf(
" %*s:\n", width,
" ");
1386 printf(
" %*s: %*s %s\n", width,
" ", addr_fmt_width,
" ", al->
line);
1419 char *line = NULL, *parsed_line, *tmp, *tmp2;
1421 s64 line_ip, offset = -1;
1422 regmatch_t match[2];
1424 if (getline(&line, &line_len, file) < 0)
1431 parsed_line =
rtrim(line);
1434 if (regexec(&
file_lineno, parsed_line, 2, match, 0) == 0) {
1435 *line_nr = atoi(parsed_line + match[1].rm_so);
1439 tmp =
ltrim(parsed_line);
1444 line_ip = strtoull(tmp, &tmp2, 16);
1445 if (*tmp2 !=
':' || tmp == tmp2 || tmp2[1] ==
'\0')
1449 if (line_ip != -1) {
1453 offset = line_ip -
start;
1454 if ((u64)line_ip < start || (u64)line_ip >= end)
1457 parsed_line = tmp2 + 1;
1461 args->
line = parsed_line;
1497 regcomp(&
file_lineno,
"^/[^:]+:([0-9]+)", REG_EXTENDED);
1503 struct list_head *list = ¬es->
src->
source;
1506 while (!list_empty(list)) {
1510 if (dl->
ins.
ops != &nop_ops)
1513 if (!strstr(dl->
al.
line,
" nop ") &&
1514 !strstr(dl->
al.
line,
" nopl ") &&
1515 !strstr(dl->
al.
line,
" nopw "))
1525 int errnum,
char *buf,
size_t buflen)
1529 BUG_ON(buflen == 0);
1532 str_error_r(errnum, buf, buflen);
1539 char *build_id_msg = NULL;
1546 scnprintf(buf, buflen,
1547 "No vmlinux file%s\nwas found in the path.\n\n" 1548 "Note that annotation using /proc/kcore requires CAP_SYS_RAWIO capability.\n\n" 1550 " perf buildid-cache -vu vmlinux\n\n" 1552 " --vmlinux vmlinux\n", build_id_msg ?:
"");
1556 scnprintf(buf, buflen,
"Internal error: Invalid %d error code\n", errnum);
1566 char *build_id_filename;
1567 char *build_id_path = NULL;
1575 if (build_id_filename) {
1577 free(build_id_filename);
1584 build_id_path = strdup(filename);
1593 pos = strrchr(build_id_path,
'/');
1595 dirname(build_id_path);
1598 readlink(build_id_path, linkname,
sizeof(linkname)) < 0 ||
1600 access(filename, R_OK)) {
1610 free(build_id_path);
1623 bool delete_extract =
false;
1633 pr_debug(
"%s: filename=%s, sym=%s, start=%#" PRIx64
", end=%#" PRIx64
"\n", __func__,
1637 pr_debug(
"annotating [%p] %30s : [%p] %30s\n",
1646 delete_extract =
true;
1648 sizeof(symfs_filename));
1654 tmp,
sizeof(tmp)) < 0)
1657 strcpy(symfs_filename, tmp);
1660 err = asprintf(&command,
1661 "%s %s%s --start-address=0x%016" PRIx64
1662 " --stop-address=0x%016" PRIx64
1663 " -l -d %s %s -C \"%s\" 2>/dev/null|grep -v \"%s:\"|expand",
1671 symfs_filename, symfs_filename);
1674 pr_err(
"Failure allocating memory for the command to run\n");
1675 goto out_remove_tmp;
1678 pr_debug(
"Executing: %s\n", command);
1681 if (pipe(stdout_fd) < 0) {
1682 pr_err(
"Failure creating the pipe to run %s\n", command);
1683 goto out_free_command;
1688 pr_err(
"Failure forking to run %s\n", command);
1689 goto out_close_stdout;
1693 close(stdout_fd[0]);
1694 dup2(stdout_fd[1], 1);
1695 close(stdout_fd[1]);
1696 execl(
"/bin/sh",
"sh",
"-c", command, NULL);
1701 close(stdout_fd[1]);
1703 file = fdopen(stdout_fd[0],
"r");
1705 pr_err(
"Failure creating FILE stream for %s\n", command);
1710 goto out_free_command;
1714 while (!feof(file)) {
1727 pr_err(
"No output from %s\n", command);
1741 close(stdout_fd[0]);
1744 unlink(symfs_filename);
1752 close(stdout_fd[1]);
1753 goto out_free_command;
1758 s64 offset, s64 end)
1760 unsigned int hits = 0;
1763 while (offset < end) {
1789 end = next ? next->
offset : len;
1813 struct arch **parch)
1836 err = arch->
init(arch, env ? env->
cpuid : NULL);
1838 pr_err(
"%s: failed to initialize %s arch priv area\n", __func__, arch->
name);
1852 struct rb_node **p = &root->
rb_node;
1853 struct rb_node *parent = NULL;
1856 while (*p != NULL) {
1860 ret = strcmp(iter->
path, al->
path);
1870 p = &(*p)->rb_right;
1876 rb_link_node(&al->
rb_node, parent, p);
1877 rb_insert_color(&al->
rb_node, root);
1896 struct rb_node **p = &root->
rb_node;
1897 struct rb_node *parent = NULL;
1899 while (*p != NULL) {
1906 p = &(*p)->rb_right;
1909 rb_link_node(&al->
rb_node, parent, p);
1910 rb_insert_color(&al->
rb_node, root);
1916 struct rb_node *
node;
1918 node = rb_first(src_root);
1920 struct rb_node *next;
1923 next = rb_next(node);
1924 rb_erase(node, src_root);
1934 struct rb_node *
node;
1936 printf(
"\nSorted summary for file %s\n", filename);
1937 printf(
"----------------------------------------------\n\n");
1939 if (RB_EMPTY_ROOT(root)) {
1940 printf(
" Nothing higher than %1.1f%%\n",
MIN_GREEN);
1944 node = rb_first(root);
1946 double percent, percent_max = 0.0;
1957 if (percent > percent_max)
1965 node = rb_next(node);
1975 for (offset = 0; offset < len; ++offset)
1977 printf(
"%*" PRIx64
": %" PRIu64
"\n", BITS_PER_LONG / 2,
1979 printf(
"%*s: %" PRIu64
"\n", BITS_PER_LONG / 2,
"h->nr_samples", h->
nr_samples);
1987 list_for_each_entry_reverse(line, lines,
node) {
1989 return scnprintf(bf,
sizeof(bf),
"%" PRIx64, start + line->
offset);
2001 const char *d_filename;
2007 int printed = 2, queue_len = 0, addr_fmt_width;
2012 int graph_dotted_len;
2022 d_filename = basename(filename);
2032 graph_dotted_len = printf(
" %-*.*s| Source code & Disassembly of %s for %s (%" PRIu64
" samples)\n",
2037 printf(
"%-*.*s----\n",
2048 if (context && queue == NULL) {
2055 queue, addr_fmt_width);
2061 printed += queue_len;
2078 if (queue_len == context)
2079 queue = list_entry(queue->
node.next, typeof(*queue),
node);
2092 double percent __maybe_unused,
2093 bool current __maybe_unused)
2098 int nr __maybe_unused,
bool current __maybe_unused)
2112 va_start(args, fmt);
2113 vfprintf(fp, fmt, args);
2126 default: s =
"?";
break;
2165 if (asprintf(&filename,
"%s.annotation", ms->
sym->
name) < 0)
2168 fp = fopen(filename,
"w");
2170 goto out_free_filename;
2177 fprintf(fp,
"%s() %s\nEvent: %s\n\n",
2203 for (offset = 0; offset < len; ++offset) {
2213 list_for_each_entry_safe(al, n, &as->
source,
node) {
2214 list_del(&al->
node);
2224 return fprintf(fp,
"%s\n", dl->
al.
line);
2226 printed = fprintf(fp,
"%#" PRIx64
" %s", dl->
al.
offset, dl->
ins.
name);
2228 if (dl->
ops.
raw[0] !=
'\0') {
2229 printed += fprintf(fp,
"%.*s %s\n", 6 - (
int)printed,
" ",
2233 return printed + fprintf(fp,
"\n");
2241 list_for_each_entry(pos, head,
al.
node)
2262 if (strstr(sym->
name,
"@plt"))
2265 for (offset = 0; offset <
size; ++offset) {
2297 size_t line_len = strlen(al->
line);
2349 struct rb_root *
root)
2352 struct rb_root tmp_root = RB_ROOT;
2355 double percent_max = 0.0;
2363 if (sample->
percent > percent_max)
2364 percent_max = sample->
percent;
2367 if (percent_max <= 0.5)
2379 struct rb_root *
root)
2391 struct rb_root source_line = RB_ROOT;
2405 fprintf(stdout,
"%s\n%s() %s\n", buf, sym->
name, dso->
long_name);
2418 struct rb_root source_line = RB_ROOT;
2446 double percent_max = 0.0;
2449 for (i = 0; i < notes->
nr_events; i++) {
2458 void *obj,
char *bf,
size_t size,
2459 void (*obj__printf)(
void *obj,
const char *
fmt, ...),
2460 void (*obj__write_graph)(
void *obj,
int graph))
2470 obj__printf(obj,
" ");
2474 obj__printf(obj,
" ");
2477 obj__printf(obj,
" ");
2479 obj__printf(obj,
" ");
2482 obj__printf(obj,
" ");
2489 bool first_line,
bool current_entry,
bool change_color,
int width,
2491 int (*obj__set_color)(
void *obj,
int color),
2492 void (*obj__set_percent_color)(
void *obj,
double percent,
bool current),
2493 int (*obj__set_jumps_percent_color)(
void *obj,
int nr,
bool current),
2494 void (*obj__printf)(
void *obj,
const char *fmt, ...),
2495 void (*obj__write_graph)(
void *obj,
int graph))
2501 bool show_title =
false;
2505 if (first_line && (al->
offset == -1 || percent_max == 0.0)) {
2513 if (al->
offset != -1 && percent_max != 0.0) {
2516 for (i = 0; i < notes->
nr_events; i++) {
2517 obj__set_percent_color(obj, al->
samples[i].
percent, current_entry);
2521 obj__printf(obj,
"%6" PRIu64
" ",
2524 obj__printf(obj,
"%6.2f ",
2529 obj__set_percent_color(obj, 0, current_entry);
2532 obj__printf(obj,
"%-*s", pcnt_width,
" ");
2534 obj__printf(obj,
"%-*s", pcnt_width,
2543 else if (!show_title)
2550 obj__printf(obj,
"%*" PRIu64
" ",
2552 else if (!show_title)
2553 obj__printf(obj,
"%*s",
2556 obj__printf(obj,
"%*s ",
2563 scnprintf(str,
sizeof(str),
2564 "%" PRIu64
"(%" PRIu64
"/%" PRIu64
")",
2568 obj__printf(obj,
"%*s ",
2571 }
else if (!show_title)
2572 obj__printf(obj,
"%*s",
2576 obj__printf(obj,
"%*s ",
2582 obj__printf(obj,
" ");
2585 obj__printf(obj,
"%-*s", width - pcnt_width - cycles_width,
" ");
2586 else if (al->
offset == -1) {
2588 printed = scnprintf(bf,
sizeof(bf),
"%-*d ", notes->
widths.
addr + 1, al->
line_nr);
2590 printed = scnprintf(bf,
sizeof(bf),
"%-*s ", notes->
widths.
addr,
" ");
2591 obj__printf(obj, bf);
2592 obj__printf(obj,
"%-*s", width - printed - pcnt_width - cycles_width + 1, al->
line);
2598 addr += notes->
start;
2601 printed = scnprintf(bf,
sizeof(bf),
"%" PRIx64
": ", addr);
2607 printed = scnprintf(bf,
sizeof(bf),
"%*d ",
2610 prev = obj__set_jumps_percent_color(obj, al->
jump_sources,
2612 obj__printf(obj, bf);
2613 obj__set_color(obj, prev);
2616 printed = scnprintf(bf,
sizeof(bf),
"%*" PRIx64
": ",
2624 printed = scnprintf(bf,
sizeof(bf),
"%-*s ",
2631 obj__printf(obj, bf);
2633 obj__set_color(obj, color);
2637 obj__printf(obj,
"%-*s", width - pcnt_width - cycles_width - 3 - printed, bf);
2657 int nr_pcnt = 1,
err;
2668 goto out_free_offsets;
2692 char *bf,
size_t size,
2697 char buf[1024], ref[30] =
" show reference callgraph, ";
2698 char sample_freq_str[64] =
"";
2699 unsigned long nr_samples = 0;
2701 bool enable_ref =
false;
2712 for (i = 0; i < nr_members; i++) {
2723 scnprintf(sample_freq_str,
sizeof(sample_freq_str),
" %d Hz,", evsel->
attr.sample_freq);
2726 return scnprintf(bf, size,
"Samples: %lu%c of event%s '%s',%s%sEvent count (approx.): %" PRIu64,
2727 nr_samples, unit, evsel->
nr_members > 1 ?
"s" :
"",
2728 ev_name, sample_freq_str, enable_ref ? ref :
" ", nr_events);
2731 #define ANNOTATION__CFG(n) \ 2732 { .name = #n, .value = &annotation__default_options.n, } 2751 #undef ANNOTATION__CFG 2757 return strcmp(name, cfg->
name);
2761 void *
data __maybe_unused)
2766 if (!strstarts(var,
"annotate."))
2774 pr_debug(
"%s variable unknown, ignoring...", var);
2775 else if (strcmp(var,
"annotate.offset_level") == 0) {
const char * get_percent_color(double percent)
static int annotation__pcnt_width(struct annotation *notes)
static int symbol__disassemble(struct symbol *sym, struct annotate_args *args)
int color_fprintf(FILE *fp, const char *color, const char *fmt,...)
u64(* map_ip)(struct map *, u64)
static struct annotated_source * annotated_source__new(void)
struct annotation::@40 widths
void symbol__calc_percent(struct symbol *sym, struct perf_evsel *evsel)
static int jump__scnprintf(struct ins *ins, char *bf, size_t size, struct ins_operands *ops)
static void annotate__branch_printf(struct block_range *br, u64 addr)
static struct ins_ops jump_ops
static void lock__delete(struct ins_operands *ops)
static int annotation__scnprintf_samples_period(struct annotation *notes, char *bf, size_t size, struct perf_evsel *evsel)
static struct arch architectures[]
static size_t disasm_line__fprintf(struct disasm_line *dl, FILE *fp)
void annotation__update_column_widths(struct annotation *notes)
static int arch__cmp(const void *a, const void *b)
void symbol__annotate_zero_histograms(struct symbol *sym)
static struct ins x86__instructions[]
void symbol__annotate_zero_histogram(struct symbol *sym, int evidx)
static int mov__parse(struct arch *arch, struct ins_operands *ops, struct map_symbol *ms __maybe_unused)
int hist_entry__inc_addr_samples(struct hist_entry *he, struct perf_sample *sample, struct perf_evsel *evsel, u64 ip)
char * get_srcline(struct dso *dso, u64 addr, struct symbol *sym, bool show_sym, bool show_addr, u64 ip)
static void FILE__set_percent_color(void *fp __maybe_unused, double percent __maybe_unused, bool current __maybe_unused)
double block_range__coverage(struct block_range *br)
static int ins__raw_scnprintf(struct ins *ins, char *bf, size_t size, struct ins_operands *ops)
struct cyc_hist * cycles_hist
const char * graph_dotted_line
int perf_config_int(int *dest, const char *name, const char *value)
static void __annotation_line__write(struct annotation_line *al, struct annotation *notes, bool first_line, bool current_entry, bool change_color, int width, void *obj, int(*obj__set_color)(void *obj, int color), void(*obj__set_percent_color)(void *obj, double percent, bool current), int(*obj__set_jumps_percent_color)(void *obj, int nr, bool current), void(*obj__printf)(void *obj, const char *fmt,...), void(*obj__write_graph)(void *obj, int graph))
static int mov__scnprintf(struct ins *ins, char *bf, size_t size, struct ins_operands *ops)
static int __symbol__join_symfs(char *bf, size_t size, const char *path)
static int arm__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
#define PERF_COLOR_MAGENTA
static void annotation__count_and_fill(struct annotation *notes, u64 start, u64 end, struct cyc_hist *ch)
static int __symbol__inc_addr_samples(struct symbol *sym, struct map *map, struct annotated_source *src, int evidx, u64 addr, struct perf_sample *sample)
void kcore_extract__delete(struct kcore_extract *kce)
static void symbol__annotate_hits(struct symbol *sym, struct perf_evsel *evsel)
static int annotation__cycles_width(struct annotation *notes)
static int s390__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, bool raw)
struct annotation_line al
void annotation__compute_ipc(struct annotation *notes, size_t size)
int perf_config_bool(const char *name, const char *value)
static struct ins_ops * ins__find(struct arch *arch, const char *name)
static int annotated_source__alloc_histograms(struct annotated_source *src, size_t size, int nr_hists)
static int FILE__set_jumps_percent_color(void *fp __maybe_unused, int nr __maybe_unused, bool current __maybe_unused)
static int cmp_source_line(struct annotation_line *a, struct annotation_line *b)
#define pr_debug2(fmt,...)
static int arm64__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
static int dec__parse(struct arch *arch __maybe_unused, struct ins_operands *ops, struct map_symbol *ms __maybe_unused)
static void delete_last_nop(struct symbol *sym)
bool ins__is_fused(struct arch *arch, const char *ins1, const char *ins2)
static regex_t file_lineno
static int dec__scnprintf(struct ins *ins, char *bf, size_t size, struct ins_operands *ops)
static int powerpc__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *ops, struct map_symbol *ms)
static void symbol__calc_lines(struct symbol *sym, struct map *map, struct rb_root *root)
int symbol__annotate_fprintf2(struct symbol *sym, FILE *fp)
bool ins__is_jump(const struct ins *ins)
#define ANNOTATION__CYCLES_WIDTH
struct annotation_data samples[0]
static void resort_source_line(struct rb_root *dest_root, struct rb_root *src_root)
int dso__decompress_kmodule_path(struct dso *dso, const char *name, char *pathname, size_t len)
bool srcline_full_filename
int __annotation__scnprintf_samples_period(struct annotation *notes, char *bf, size_t size, struct perf_evsel *evsel, bool show_freq)
static int dso__disassemble_filename(struct dso *dso, char *filename, size_t filename_size)
x86 movsq based memset() in arch/x86/lib/memset_64.S") MEMSET_FN(memset_erms
int symbol__strerror_disassemble(struct symbol *sym __maybe_unused, struct map *map, int errnum, char *buf, size_t buflen)
int(* scnprintf)(struct ins *ins, char *bf, size_t size, struct ins_operands *ops)
static int symbol__parse_objdump_line(struct symbol *sym, FILE *file, struct annotate_args *args, int *line_nr)
void(* set_percent_color)(void *obj, double percent, bool current)
static int symbol__inc_addr_samples(struct symbol *sym, struct map *map, struct perf_evsel *evsel, u64 addr, struct perf_sample *sample)
static int x86__annotate_init(struct arch *arch, char *cpuid)
#define PERF_COLOR_NORMAL
struct ins_operands::@36::@39 locked
static void FILE__printf(void *fp, const char *fmt,...)
static int annotation__config(const char *var, const char *value, void *data __maybe_unused)
struct perf_evsel * evsel
int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size)
#define ANNOTATION__IPC_WIDTH
static int disasm_line__parse(char *line, const char **namep, char **rawp)
static struct sym_hist * annotation__histogram(struct annotation *notes, int idx)
struct annotation_line * annotation_line__next(struct annotation_line *pos, struct list_head *head)
const char * objdump_path
bool(* ins_is_fused)(struct arch *arch, const char *ins1, const char *ins2)
struct perf_evlist * evlist
struct annotation_options * options
#define pr_debug(fmt,...)
static void ins__sort(struct arch *arch)
static struct arch * arch__find(const char *name)
static struct ins_ops lock_ops
int kcore_extract__create(struct kcore_extract *kce)
void annotation__mark_jump_targets(struct annotation *notes, struct symbol *sym)
static bool annotation_line__filter(struct annotation_line *al, struct annotation *notes)
static int FILE__set_color(void *fp __maybe_unused, int color __maybe_unused)
bool dso__needs_decompress(struct dso *dso)
static struct disasm_line * disasm_line(struct annotation_line *al)
void annotation__set_offsets(struct annotation *notes, s64 size)
int addr_map_symbol__account_cycles(struct addr_map_symbol *ams, struct addr_map_symbol *start, unsigned cycles)
int(* set_color)(void *obj, int color)
static void disasm_line__write(struct disasm_line *dl, struct annotation *notes, void *obj, char *bf, size_t size, void(*obj__printf)(void *obj, const char *fmt,...), void(*obj__write_graph)(void *obj, int graph))
static int nop__scnprintf(struct ins *ins __maybe_unused, char *bf, size_t size, struct ins_operands *ops __maybe_unused)
static unsigned annotation__count_insn(struct annotation *notes, u64 start, u64 end)
static void annotation__calc_lines(struct annotation *notes, struct map *map, struct rb_root *root)
struct ins_ops *(* associate_instruction_ops)(struct arch *arch, const char *name)
#define ANNOTATION__CFG(n)
static struct annotation_line * annotation_line__new(struct annotate_args *args, size_t privsize)
static __attribute__((constructor))
void free_srcline(char *srcline)
static int ins__cmp(const void *a, const void *b)
struct annotated_source * symbol__hists(struct symbol *sym, int nr_hists)
static struct cyc_hist * symbol__cycles_hist(struct symbol *sym)
static void FILE__write_graph(void *fp, int graph)
static const char * annotate__address_color(struct block_range *br)
unsigned long convert_unit(unsigned long value, char *unit)
double annotation_line__max_percent(struct annotation_line *al, struct annotation *notes)
struct ins_operands::@35 target
static int str(yyscan_t scanner, int token)
static struct ins_ops s390_call_ops
static int arch__grow_instructions(struct arch *arch)
void symbol__annotate_decay_histogram(struct symbol *sym, int evidx)
static int call__scnprintf(struct ins *ins, char *bf, size_t size, struct ins_operands *ops)
struct block_range * block_range__find(u64 addr)
int symbol__annotate_printf(struct symbol *sym, struct map *map, struct perf_evsel *evsel, struct annotation_options *opts)
static struct ins_ops mov_ops
static int annotation_config__cmp(const void *name, const void *cfgp)
int symbol__tty_annotate2(struct symbol *sym, struct map *map, struct perf_evsel *evsel, struct annotation_options *opts)
struct sym_hist_entry addr[0]
struct ins * instructions
static struct annotation * symbol__annotation(struct symbol *sym)
static int call__parse(struct arch *arch, struct ins_operands *ops, struct map_symbol *ms)
static bool dso__is_kcore(struct dso *dso)
static struct block_range * block_range__next(struct block_range *br)
static int annotated_source__addr_fmt_width(struct list_head *lines, u64 start)
int symbol__tty_annotate(struct symbol *sym, struct map *map, struct perf_evsel *evsel, struct annotation_options *opts)
u64 map__objdump_2mem(struct map *map, u64 ip)
bool ins__is_lock(const struct ins *ins)
#define DSO__NAME_KALLSYMS
x86 movsq based memcpy() in arch/x86/lib/memcpy_64.S") MEMCPY_FN(memcpy_erms
u64 map__rip_2objdump(struct map *map, u64 rip)
const char * disassembler_style
const char * perf_env__arch(struct perf_env *env)
struct perf_env * perf_evsel__env(struct perf_evsel *evsel)
size_t disasm__fprintf(struct list_head *head, FILE *fp)
static int raw(yyscan_t scanner)
static int lock__scnprintf(struct ins *ins, char *bf, size_t size, struct ins_operands *ops)
bool ins__is_call(const struct ins *ins)
const char * perf_evsel__name(struct perf_evsel *evsel)
static const char * annotate__asm_color(struct block_range *br)
bool ui__has_annotation(void)
struct annotation_options * options
static bool x86__ins_is_fused(struct arch *arch, const char *ins1, const char *ins2)
void annotation__init_column_widths(struct annotation *notes, struct symbol *sym)
static void annotation_line__delete(struct annotation_line *al)
static struct ins_ops * __ins__find(struct arch *arch, const char *name)
static struct sym_hist * annotated_source__histogram(struct annotated_source *src, int idx)
int(* init)(struct arch *arch, char *cpuid)
struct annotation_options annotation__default_options
bool disasm_line__is_valid_local_jump(struct disasm_line *dl, struct symbol *sym)
static void calc_percent(struct sym_hist *hist, struct annotation_data *sample, s64 offset, s64 end)
int perf_config(config_fn_t fn, void *data)
u8 build_id[BUILD_ID_SIZE]
int symbol__annotate2(struct symbol *sym, struct map *map, struct perf_evsel *evsel, struct annotation_options *options, struct arch **parch)
static void ins__delete(struct ins_operands *ops)
struct annotated_source * src
int(* parse)(struct arch *arch, struct ins_operands *ops, struct map_symbol *ms)
static struct ins_ops nop_ops
static void __resort_source_line(struct rb_root *root, struct annotation_line *al)
static struct ins_ops ret_ops
static int disasm_line__print(struct disasm_line *dl, u64 start, int addr_fmt_width)
static int sym(yyscan_t scanner, int type, int config)
static struct disasm_line * disasm_line__new(struct annotate_args *args)
struct sym_hist * histograms
int build_id__sprintf(const u8 *build_id, int len, char *bf)
static void annotation_line__add(struct annotation_line *al, struct list_head *head)
int map_groups__find_ams(struct addr_map_symbol *ams)
static struct annotation_config annotation__configs[]
void annotated_source__purge(struct annotated_source *as)
static double percent(int st, int tot)
enum dso_binary_type symtab_type
static void disasm_line__init_ins(struct disasm_line *dl, struct arch *arch, struct map_symbol *ms)
static void insert_source_line(struct rb_root *root, struct annotation_line *al)
static int symbol__account_cycles(u64 addr, u64 start, struct symbol *sym, unsigned cycles)
int map_symbol__annotation_dump(struct map_symbol *ms, struct perf_evsel *evsel)
void(* write_graph)(void *obj, int graph)
static void arch__sort(void)
static bool perf_evsel__is_group_event(struct perf_evsel *evsel)
static int symbol__alloc_hist_cycles(struct symbol *sym)
static int arch__associate_ins_ops(struct arch *arch, const char *name, struct ins_ops *ops)
#define ANNOTATION__MINMAX_CYCLES_WIDTH
struct ins_operands::@36::@38 source
static void print_summary(struct rb_root *root, const char *filename)
u64(* unmap_ip)(struct map *, u64)
void annotation_config__init(void)
int ins__scnprintf(struct ins *ins, char *bf, size_t size, struct ins_operands *ops)
static void annotation__calc_percent(struct annotation *notes, struct perf_evsel *evsel, s64 len)
static int ins__key_cmp(const void *name, const void *insp)
char * dso__build_id_filename(const struct dso *dso, char *bf, size_t size, bool is_debug)
static size_t symbol__size(const struct symbol *sym)
static int lock__parse(struct arch *arch, struct ins_operands *ops, struct map_symbol *ms)
#define ANNOTATION__MIN_OFFSET_LEVEL
void(* printf)(void *obj, const char *fmt,...)
static int arch__key_cmp(const void *name, const void *archp)
void disasm_line__free(struct disasm_line *dl)
int(* set_jumps_percent_color)(void *obj, int nr, bool current)
bool ins__is_ret(const struct ins *ins)
static struct ins_ops call_ops
void annotation_line__write(struct annotation_line *al, struct annotation *notes, struct annotation_write_ops *ops)
int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, struct perf_sample *sample, struct perf_evsel *evsel)
#define pr_debug3(fmt,...)
struct annotation_line ** offsets
int symbol__annotate(struct symbol *sym, struct map *map, struct perf_evsel *evsel, size_t privsize, struct annotation_options *options, struct arch **parch)
struct perf_event_attr attr
void(* free)(struct ins_operands *ops)
static int annotation_line__print(struct annotation_line *al, struct symbol *sym, u64 start, struct perf_evsel *evsel, u64 len, int min_pcnt, int printed, int max_lines, struct annotation_line *queue, int addr_fmt_width)
static int width_jumps(int n)
size_t nr_instructions_allocated
static struct ins_ops dec_ops
static int __symbol__account_cycles(struct cyc_hist *ch, u64 start, unsigned offset, unsigned cycles, unsigned have_start)
static __maybe_unused void annotated_source__delete(struct annotated_source *src)
void static void * zalloc(size_t size)
static bool disasm_line__has_local_offset(const struct disasm_line *dl)
static int comment__symbol(char *raw, char *comment, u64 *addrp, char **namep)