linux/tools/perf/util/annotate.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2011, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
   3 *
   4 * Parts came from builtin-annotate.c, see those files for further
   5 * copyright notes.
   6 *
   7 * Released under the GPL v2. (and only v2, not any later version)
   8 */
   9
  10#include <errno.h>
  11#include <inttypes.h>
  12#include "util.h"
  13#include "ui/ui.h"
  14#include "sort.h"
  15#include "build-id.h"
  16#include "color.h"
  17#include "config.h"
  18#include "cache.h"
  19#include "symbol.h"
  20#include "units.h"
  21#include "debug.h"
  22#include "annotate.h"
  23#include "evsel.h"
  24#include "evlist.h"
  25#include "block-range.h"
  26#include "string2.h"
  27#include "arch/common.h"
  28#include <regex.h>
  29#include <pthread.h>
  30#include <linux/bitops.h>
  31#include <linux/kernel.h>
  32
  33/* FIXME: For the HE_COLORSET */
  34#include "ui/browser.h"
  35
  36/*
  37 * FIXME: Using the same values as slang.h,
  38 * but that header may not be available everywhere
  39 */
  40#define LARROW_CHAR     ((unsigned char)',')
  41#define RARROW_CHAR     ((unsigned char)'+')
  42#define DARROW_CHAR     ((unsigned char)'.')
  43#define UARROW_CHAR     ((unsigned char)'-')
  44
  45#include "sane_ctype.h"
  46
  47struct annotation_options annotation__default_options = {
  48        .use_offset     = true,
  49        .jump_arrows    = true,
  50        .annotate_src   = true,
  51        .offset_level   = ANNOTATION__OFFSET_JUMP_TARGETS,
  52        .percent_type   = PERCENT_PERIOD_LOCAL,
  53};
  54
  55static regex_t   file_lineno;
  56
  57static struct ins_ops *ins__find(struct arch *arch, const char *name);
  58static void ins__sort(struct arch *arch);
  59static int disasm_line__parse(char *line, const char **namep, char **rawp);
  60
  61struct arch {
  62        const char      *name;
  63        struct ins      *instructions;
  64        size_t          nr_instructions;
  65        size_t          nr_instructions_allocated;
  66        struct ins_ops  *(*associate_instruction_ops)(struct arch *arch, const char *name);
  67        bool            sorted_instructions;
  68        bool            initialized;
  69        void            *priv;
  70        unsigned int    model;
  71        unsigned int    family;
  72        int             (*init)(struct arch *arch, char *cpuid);
  73        bool            (*ins_is_fused)(struct arch *arch, const char *ins1,
  74                                        const char *ins2);
  75        struct          {
  76                char comment_char;
  77                char skip_functions_char;
  78        } objdump;
  79};
  80
  81static struct ins_ops call_ops;
  82static struct ins_ops dec_ops;
  83static struct ins_ops jump_ops;
  84static struct ins_ops mov_ops;
  85static struct ins_ops nop_ops;
  86static struct ins_ops lock_ops;
  87static struct ins_ops ret_ops;
  88
  89static int arch__grow_instructions(struct arch *arch)
  90{
  91        struct ins *new_instructions;
  92        size_t new_nr_allocated;
  93
  94        if (arch->nr_instructions_allocated == 0 && arch->instructions)
  95                goto grow_from_non_allocated_table;
  96
  97        new_nr_allocated = arch->nr_instructions_allocated + 128;
  98        new_instructions = realloc(arch->instructions, new_nr_allocated * sizeof(struct ins));
  99        if (new_instructions == NULL)
 100                return -1;
 101
 102out_update_instructions:
 103        arch->instructions = new_instructions;
 104        arch->nr_instructions_allocated = new_nr_allocated;
 105        return 0;
 106
 107grow_from_non_allocated_table:
 108        new_nr_allocated = arch->nr_instructions + 128;
 109        new_instructions = calloc(new_nr_allocated, sizeof(struct ins));
 110        if (new_instructions == NULL)
 111                return -1;
 112
 113        memcpy(new_instructions, arch->instructions, arch->nr_instructions);
 114        goto out_update_instructions;
 115}
 116
 117static int arch__associate_ins_ops(struct arch* arch, const char *name, struct ins_ops *ops)
 118{
 119        struct ins *ins;
 120
 121        if (arch->nr_instructions == arch->nr_instructions_allocated &&
 122            arch__grow_instructions(arch))
 123                return -1;
 124
 125        ins = &arch->instructions[arch->nr_instructions];
 126        ins->name = strdup(name);
 127        if (!ins->name)
 128                return -1;
 129
 130        ins->ops  = ops;
 131        arch->nr_instructions++;
 132
 133        ins__sort(arch);
 134        return 0;
 135}
 136
 137#include "arch/arm/annotate/instructions.c"
 138#include "arch/arm64/annotate/instructions.c"
 139#include "arch/x86/annotate/instructions.c"
 140#include "arch/powerpc/annotate/instructions.c"
 141#include "arch/s390/annotate/instructions.c"
 142
 143static struct arch architectures[] = {
 144        {
 145                .name = "arm",
 146                .init = arm__annotate_init,
 147        },
 148        {
 149                .name = "arm64",
 150                .init = arm64__annotate_init,
 151        },
 152        {
 153                .name = "x86",
 154                .init = x86__annotate_init,
 155                .instructions = x86__instructions,
 156                .nr_instructions = ARRAY_SIZE(x86__instructions),
 157                .ins_is_fused = x86__ins_is_fused,
 158                .objdump =  {
 159                        .comment_char = '#',
 160                },
 161        },
 162        {
 163                .name = "powerpc",
 164                .init = powerpc__annotate_init,
 165        },
 166        {
 167                .name = "s390",
 168                .init = s390__annotate_init,
 169                .objdump =  {
 170                        .comment_char = '#',
 171                },
 172        },
 173};
 174
 175static void ins__delete(struct ins_operands *ops)
 176{
 177        if (ops == NULL)
 178                return;
 179        zfree(&ops->source.raw);
 180        zfree(&ops->source.name);
 181        zfree(&ops->target.raw);
 182        zfree(&ops->target.name);
 183}
 184
 185static int ins__raw_scnprintf(struct ins *ins, char *bf, size_t size,
 186                              struct ins_operands *ops)
 187{
 188        return scnprintf(bf, size, "%-6s %s", ins->name, ops->raw);
 189}
 190
 191int ins__scnprintf(struct ins *ins, char *bf, size_t size,
 192                  struct ins_operands *ops)
 193{
 194        if (ins->ops->scnprintf)
 195                return ins->ops->scnprintf(ins, bf, size, ops);
 196
 197        return ins__raw_scnprintf(ins, bf, size, ops);
 198}
 199
 200bool ins__is_fused(struct arch *arch, const char *ins1, const char *ins2)
 201{
 202        if (!arch || !arch->ins_is_fused)
 203                return false;
 204
 205        return arch->ins_is_fused(arch, ins1, ins2);
 206}
 207
 208static int call__parse(struct arch *arch, struct ins_operands *ops, struct map_symbol *ms)
 209{
 210        char *endptr, *tok, *name;
 211        struct map *map = ms->map;
 212        struct addr_map_symbol target = {
 213                .map = map,
 214        };
 215
 216        ops->target.addr = strtoull(ops->raw, &endptr, 16);
 217
 218        name = strchr(endptr, '<');
 219        if (name == NULL)
 220                goto indirect_call;
 221
 222        name++;
 223
 224        if (arch->objdump.skip_functions_char &&
 225            strchr(name, arch->objdump.skip_functions_char))
 226                return -1;
 227
 228        tok = strchr(name, '>');
 229        if (tok == NULL)
 230                return -1;
 231
 232        *tok = '\0';
 233        ops->target.name = strdup(name);
 234        *tok = '>';
 235
 236        if (ops->target.name == NULL)
 237                return -1;
 238find_target:
 239        target.addr = map__objdump_2mem(map, ops->target.addr);
 240
 241        if (map_groups__find_ams(&target) == 0 &&
 242            map__rip_2objdump(target.map, map->map_ip(target.map, target.addr)) == ops->target.addr)
 243                ops->target.sym = target.sym;
 244
 245        return 0;
 246
 247indirect_call:
 248        tok = strchr(endptr, '*');
 249        if (tok != NULL) {
 250                endptr++;
 251
 252                /* Indirect call can use a non-rip register and offset: callq  *0x8(%rbx).
 253                 * Do not parse such instruction.  */
 254                if (strstr(endptr, "(%r") == NULL)
 255                        ops->target.addr = strtoull(endptr, NULL, 16);
 256        }
 257        goto find_target;
 258}
 259
 260static int call__scnprintf(struct ins *ins, char *bf, size_t size,
 261                           struct ins_operands *ops)
 262{
 263        if (ops->target.sym)
 264                return scnprintf(bf, size, "%-6s %s", ins->name, ops->target.sym->name);
 265
 266        if (ops->target.addr == 0)
 267                return ins__raw_scnprintf(ins, bf, size, ops);
 268
 269        if (ops->target.name)
 270                return scnprintf(bf, size, "%-6s %s", ins->name, ops->target.name);
 271
 272        return scnprintf(bf, size, "%-6s *%" PRIx64, ins->name, ops->target.addr);
 273}
 274
 275static struct ins_ops call_ops = {
 276        .parse     = call__parse,
 277        .scnprintf = call__scnprintf,
 278};
 279
 280bool ins__is_call(const struct ins *ins)
 281{
 282        return ins->ops == &call_ops || ins->ops == &s390_call_ops;
 283}
 284
 285/*
 286 * Prevents from matching commas in the comment section, e.g.:
 287 * ffff200008446e70:       b.cs    ffff2000084470f4 <generic_exec_single+0x314>  // b.hs, b.nlast
 288 */
 289static inline const char *validate_comma(const char *c, struct ins_operands *ops)
 290{
 291        if (ops->raw_comment && c > ops->raw_comment)
 292                return NULL;
 293
 294        return c;
 295}
 296
 297static int jump__parse(struct arch *arch, struct ins_operands *ops, struct map_symbol *ms)
 298{
 299        struct map *map = ms->map;
 300        struct symbol *sym = ms->sym;
 301        struct addr_map_symbol target = {
 302                .map = map,
 303        };
 304        const char *c = strchr(ops->raw, ',');
 305        u64 start, end;
 306
 307        ops->raw_comment = strchr(ops->raw, arch->objdump.comment_char);
 308        c = validate_comma(c, ops);
 309
 310        /*
 311         * Examples of lines to parse for the _cpp_lex_token@@Base
 312         * function:
 313         *
 314         * 1159e6c: jne    115aa32 <_cpp_lex_token@@Base+0xf92>
 315         * 1159e8b: jne    c469be <cpp_named_operator2name@@Base+0xa72>
 316         *
 317         * The first is a jump to an offset inside the same function,
 318         * the second is to another function, i.e. that 0xa72 is an
 319         * offset in the cpp_named_operator2name@@base function.
 320         */
 321        /*
 322         * skip over possible up to 2 operands to get to address, e.g.:
 323         * tbnz  w0, #26, ffff0000083cd190 <security_file_permission+0xd0>
 324         */
 325        if (c++ != NULL) {
 326                ops->target.addr = strtoull(c, NULL, 16);
 327                if (!ops->target.addr) {
 328                        c = strchr(c, ',');
 329                        c = validate_comma(c, ops);
 330                        if (c++ != NULL)
 331                                ops->target.addr = strtoull(c, NULL, 16);
 332                }
 333        } else {
 334                ops->target.addr = strtoull(ops->raw, NULL, 16);
 335        }
 336
 337        target.addr = map__objdump_2mem(map, ops->target.addr);
 338        start = map->unmap_ip(map, sym->start),
 339        end = map->unmap_ip(map, sym->end);
 340
 341        ops->target.outside = target.addr < start || target.addr > end;
 342
 343        /*
 344         * FIXME: things like this in _cpp_lex_token (gcc's cc1 program):
 345
 346                cpp_named_operator2name@@Base+0xa72
 347
 348         * Point to a place that is after the cpp_named_operator2name
 349         * boundaries, i.e.  in the ELF symbol table for cc1
 350         * cpp_named_operator2name is marked as being 32-bytes long, but it in
 351         * fact is much larger than that, so we seem to need a symbols__find()
 352         * routine that looks for >= current->start and  < next_symbol->start,
 353         * possibly just for C++ objects?
 354         *
 355         * For now lets just make some progress by marking jumps to outside the
 356         * current function as call like.
 357         *
 358         * Actual navigation will come next, with further understanding of how
 359         * the symbol searching and disassembly should be done.
 360         */
 361        if (map_groups__find_ams(&target) == 0 &&
 362            map__rip_2objdump(target.map, map->map_ip(target.map, target.addr)) == ops->target.addr)
 363                ops->target.sym = target.sym;
 364
 365        if (!ops->target.outside) {
 366                ops->target.offset = target.addr - start;
 367                ops->target.offset_avail = true;
 368        } else {
 369                ops->target.offset_avail = false;
 370        }
 371
 372        return 0;
 373}
 374
 375static int jump__scnprintf(struct ins *ins, char *bf, size_t size,
 376                           struct ins_operands *ops)
 377{
 378        const char *c;
 379
 380        if (!ops->target.addr || ops->target.offset < 0)
 381                return ins__raw_scnprintf(ins, bf, size, ops);
 382
 383        if (ops->target.outside && ops->target.sym != NULL)
 384                return scnprintf(bf, size, "%-6s %s", ins->name, ops->target.sym->name);
 385
 386        c = strchr(ops->raw, ',');
 387        c = validate_comma(c, ops);
 388
 389        if (c != NULL) {
 390                const char *c2 = strchr(c + 1, ',');
 391
 392                c2 = validate_comma(c2, ops);
 393                /* check for 3-op insn */
 394                if (c2 != NULL)
 395                        c = c2;
 396                c++;
 397
 398                /* mirror arch objdump's space-after-comma style */
 399                if (*c == ' ')
 400                        c++;
 401        }
 402
 403        return scnprintf(bf, size, "%-6s %.*s%" PRIx64,
 404                         ins->name, c ? c - ops->raw : 0, ops->raw,
 405                         ops->target.offset);
 406}
 407
 408static struct ins_ops jump_ops = {
 409        .parse     = jump__parse,
 410        .scnprintf = jump__scnprintf,
 411};
 412
 413bool ins__is_jump(const struct ins *ins)
 414{
 415        return ins->ops == &jump_ops;
 416}
 417
 418static int comment__symbol(char *raw, char *comment, u64 *addrp, char **namep)
 419{
 420        char *endptr, *name, *t;
 421
 422        if (strstr(raw, "(%rip)") == NULL)
 423                return 0;
 424
 425        *addrp = strtoull(comment, &endptr, 16);
 426        if (endptr == comment)
 427                return 0;
 428        name = strchr(endptr, '<');
 429        if (name == NULL)
 430                return -1;
 431
 432        name++;
 433
 434        t = strchr(name, '>');
 435        if (t == NULL)
 436                return 0;
 437
 438        *t = '\0';
 439        *namep = strdup(name);
 440        *t = '>';
 441
 442        return 0;
 443}
 444
 445static int lock__parse(struct arch *arch, struct ins_operands *ops, struct map_symbol *ms)
 446{
 447        ops->locked.ops = zalloc(sizeof(*ops->locked.ops));
 448        if (ops->locked.ops == NULL)
 449                return 0;
 450
 451        if (disasm_line__parse(ops->raw, &ops->locked.ins.name, &ops->locked.ops->raw) < 0)
 452                goto out_free_ops;
 453
 454        ops->locked.ins.ops = ins__find(arch, ops->locked.ins.name);
 455
 456        if (ops->locked.ins.ops == NULL)
 457                goto out_free_ops;
 458
 459        if (ops->locked.ins.ops->parse &&
 460            ops->locked.ins.ops->parse(arch, ops->locked.ops, ms) < 0)
 461                goto out_free_ops;
 462
 463        return 0;
 464
 465out_free_ops:
 466        zfree(&ops->locked.ops);
 467        return 0;
 468}
 469
 470static int lock__scnprintf(struct ins *ins, char *bf, size_t size,
 471                           struct ins_operands *ops)
 472{
 473        int printed;
 474
 475        if (ops->locked.ins.ops == NULL)
 476                return ins__raw_scnprintf(ins, bf, size, ops);
 477
 478        printed = scnprintf(bf, size, "%-6s ", ins->name);
 479        return printed + ins__scnprintf(&ops->locked.ins, bf + printed,
 480                                        size - printed, ops->locked.ops);
 481}
 482
 483static void lock__delete(struct ins_operands *ops)
 484{
 485        struct ins *ins = &ops->locked.ins;
 486
 487        if (ins->ops && ins->ops->free)
 488                ins->ops->free(ops->locked.ops);
 489        else
 490                ins__delete(ops->locked.ops);
 491
 492        zfree(&ops->locked.ops);
 493        zfree(&ops->target.raw);
 494        zfree(&ops->target.name);
 495}
 496
 497static struct ins_ops lock_ops = {
 498        .free      = lock__delete,
 499        .parse     = lock__parse,
 500        .scnprintf = lock__scnprintf,
 501};
 502
 503static int mov__parse(struct arch *arch, struct ins_operands *ops, struct map_symbol *ms __maybe_unused)
 504{
 505        char *s = strchr(ops->raw, ','), *target, *comment, prev;
 506
 507        if (s == NULL)
 508                return -1;
 509
 510        *s = '\0';
 511        ops->source.raw = strdup(ops->raw);
 512        *s = ',';
 513
 514        if (ops->source.raw == NULL)
 515                return -1;
 516
 517        target = ++s;
 518        comment = strchr(s, arch->objdump.comment_char);
 519
 520        if (comment != NULL)
 521                s = comment - 1;
 522        else
 523                s = strchr(s, '\0') - 1;
 524
 525        while (s > target && isspace(s[0]))
 526                --s;
 527        s++;
 528        prev = *s;
 529        *s = '\0';
 530
 531        ops->target.raw = strdup(target);
 532        *s = prev;
 533
 534        if (ops->target.raw == NULL)
 535                goto out_free_source;
 536
 537        if (comment == NULL)
 538                return 0;
 539
 540        comment = ltrim(comment);
 541        comment__symbol(ops->source.raw, comment + 1, &ops->source.addr, &ops->source.name);
 542        comment__symbol(ops->target.raw, comment + 1, &ops->target.addr, &ops->target.name);
 543
 544        return 0;
 545
 546out_free_source:
 547        zfree(&ops->source.raw);
 548        return -1;
 549}
 550
 551static int mov__scnprintf(struct ins *ins, char *bf, size_t size,
 552                           struct ins_operands *ops)
 553{
 554        return scnprintf(bf, size, "%-6s %s,%s", ins->name,
 555                         ops->source.name ?: ops->source.raw,
 556                         ops->target.name ?: ops->target.raw);
 557}
 558
 559static struct ins_ops mov_ops = {
 560        .parse     = mov__parse,
 561        .scnprintf = mov__scnprintf,
 562};
 563
 564static int dec__parse(struct arch *arch __maybe_unused, struct ins_operands *ops, struct map_symbol *ms __maybe_unused)
 565{
 566        char *target, *comment, *s, prev;
 567
 568        target = s = ops->raw;
 569
 570        while (s[0] != '\0' && !isspace(s[0]))
 571                ++s;
 572        prev = *s;
 573        *s = '\0';
 574
 575        ops->target.raw = strdup(target);
 576        *s = prev;
 577
 578        if (ops->target.raw == NULL)
 579                return -1;
 580
 581        comment = strchr(s, arch->objdump.comment_char);
 582        if (comment == NULL)
 583                return 0;
 584
 585        comment = ltrim(comment);
 586        comment__symbol(ops->target.raw, comment + 1, &ops->target.addr, &ops->target.name);
 587
 588        return 0;
 589}
 590
 591static int dec__scnprintf(struct ins *ins, char *bf, size_t size,
 592                           struct ins_operands *ops)
 593{
 594        return scnprintf(bf, size, "%-6s %s", ins->name,
 595                         ops->target.name ?: ops->target.raw);
 596}
 597
 598static struct ins_ops dec_ops = {
 599        .parse     = dec__parse,
 600        .scnprintf = dec__scnprintf,
 601};
 602
 603static int nop__scnprintf(struct ins *ins __maybe_unused, char *bf, size_t size,
 604                          struct ins_operands *ops __maybe_unused)
 605{
 606        return scnprintf(bf, size, "%-6s", "nop");
 607}
 608
 609static struct ins_ops nop_ops = {
 610        .scnprintf = nop__scnprintf,
 611};
 612
 613static struct ins_ops ret_ops = {
 614        .scnprintf = ins__raw_scnprintf,
 615};
 616
 617bool ins__is_ret(const struct ins *ins)
 618{
 619        return ins->ops == &ret_ops;
 620}
 621
 622bool ins__is_lock(const struct ins *ins)
 623{
 624        return ins->ops == &lock_ops;
 625}
 626
 627static int ins__key_cmp(const void *name, const void *insp)
 628{
 629        const struct ins *ins = insp;
 630
 631        return strcmp(name, ins->name);
 632}
 633
 634static int ins__cmp(const void *a, const void *b)
 635{
 636        const struct ins *ia = a;
 637        const struct ins *ib = b;
 638
 639        return strcmp(ia->name, ib->name);
 640}
 641
 642static void ins__sort(struct arch *arch)
 643{
 644        const int nmemb = arch->nr_instructions;
 645
 646        qsort(arch->instructions, nmemb, sizeof(struct ins), ins__cmp);
 647}
 648
 649static struct ins_ops *__ins__find(struct arch *arch, const char *name)
 650{
 651        struct ins *ins;
 652        const int nmemb = arch->nr_instructions;
 653
 654        if (!arch->sorted_instructions) {
 655                ins__sort(arch);
 656                arch->sorted_instructions = true;
 657        }
 658
 659        ins = bsearch(name, arch->instructions, nmemb, sizeof(struct ins), ins__key_cmp);
 660        return ins ? ins->ops : NULL;
 661}
 662
 663static struct ins_ops *ins__find(struct arch *arch, const char *name)
 664{
 665        struct ins_ops *ops = __ins__find(arch, name);
 666
 667        if (!ops && arch->associate_instruction_ops)
 668                ops = arch->associate_instruction_ops(arch, name);
 669
 670        return ops;
 671}
 672
 673static int arch__key_cmp(const void *name, const void *archp)
 674{
 675        const struct arch *arch = archp;
 676
 677        return strcmp(name, arch->name);
 678}
 679
 680static int arch__cmp(const void *a, const void *b)
 681{
 682        const struct arch *aa = a;
 683        const struct arch *ab = b;
 684
 685        return strcmp(aa->name, ab->name);
 686}
 687
 688static void arch__sort(void)
 689{
 690        const int nmemb = ARRAY_SIZE(architectures);
 691
 692        qsort(architectures, nmemb, sizeof(struct arch), arch__cmp);
 693}
 694
 695static struct arch *arch__find(const char *name)
 696{
 697        const int nmemb = ARRAY_SIZE(architectures);
 698        static bool sorted;
 699
 700        if (!sorted) {
 701                arch__sort();
 702                sorted = true;
 703        }
 704
 705        return bsearch(name, architectures, nmemb, sizeof(struct arch), arch__key_cmp);
 706}
 707
 708static struct annotated_source *annotated_source__new(void)
 709{
 710        struct annotated_source *src = zalloc(sizeof(*src));
 711
 712        if (src != NULL)
 713                INIT_LIST_HEAD(&src->source);
 714
 715        return src;
 716}
 717
 718static __maybe_unused void annotated_source__delete(struct annotated_source *src)
 719{
 720        if (src == NULL)
 721                return;
 722        zfree(&src->histograms);
 723        zfree(&src->cycles_hist);
 724        free(src);
 725}
 726
 727static int annotated_source__alloc_histograms(struct annotated_source *src,
 728                                              size_t size, int nr_hists)
 729{
 730        size_t sizeof_sym_hist;
 731
 732        /*
 733         * Add buffer of one element for zero length symbol.
 734         * When sample is taken from first instruction of
 735         * zero length symbol, perf still resolves it and
 736         * shows symbol name in perf report and allows to
 737         * annotate it.
 738         */
 739        if (size == 0)
 740                size = 1;
 741
 742        /* Check for overflow when calculating sizeof_sym_hist */
 743        if (size > (SIZE_MAX - sizeof(struct sym_hist)) / sizeof(struct sym_hist_entry))
 744                return -1;
 745
 746        sizeof_sym_hist = (sizeof(struct sym_hist) + size * sizeof(struct sym_hist_entry));
 747
 748        /* Check for overflow in zalloc argument */
 749        if (sizeof_sym_hist > SIZE_MAX / nr_hists)
 750                return -1;
 751
 752        src->sizeof_sym_hist = sizeof_sym_hist;
 753        src->nr_histograms   = nr_hists;
 754        src->histograms      = calloc(nr_hists, sizeof_sym_hist) ;
 755        return src->histograms ? 0 : -1;
 756}
 757
 758/* The cycles histogram is lazily allocated. */
 759static int symbol__alloc_hist_cycles(struct symbol *sym)
 760{
 761        struct annotation *notes = symbol__annotation(sym);
 762        const size_t size = symbol__size(sym);
 763
 764        notes->src->cycles_hist = calloc(size, sizeof(struct cyc_hist));
 765        if (notes->src->cycles_hist == NULL)
 766                return -1;
 767        return 0;
 768}
 769
 770void symbol__annotate_zero_histograms(struct symbol *sym)
 771{
 772        struct annotation *notes = symbol__annotation(sym);
 773
 774        pthread_mutex_lock(&notes->lock);
 775        if (notes->src != NULL) {
 776                memset(notes->src->histograms, 0,
 777                       notes->src->nr_histograms * notes->src->sizeof_sym_hist);
 778                if (notes->src->cycles_hist)
 779                        memset(notes->src->cycles_hist, 0,
 780                                symbol__size(sym) * sizeof(struct cyc_hist));
 781        }
 782        pthread_mutex_unlock(&notes->lock);
 783}
 784
 785static int __symbol__account_cycles(struct cyc_hist *ch,
 786                                    u64 start,
 787                                    unsigned offset, unsigned cycles,
 788                                    unsigned have_start)
 789{
 790        /*
 791         * For now we can only account one basic block per
 792         * final jump. But multiple could be overlapping.
 793         * Always account the longest one. So when
 794         * a shorter one has been already seen throw it away.
 795         *
 796         * We separately always account the full cycles.
 797         */
 798        ch[offset].num_aggr++;
 799        ch[offset].cycles_aggr += cycles;
 800
 801        if (cycles > ch[offset].cycles_max)
 802                ch[offset].cycles_max = cycles;
 803
 804        if (ch[offset].cycles_min) {
 805                if (cycles && cycles < ch[offset].cycles_min)
 806                        ch[offset].cycles_min = cycles;
 807        } else
 808                ch[offset].cycles_min = cycles;
 809
 810        if (!have_start && ch[offset].have_start)
 811                return 0;
 812        if (ch[offset].num) {
 813                if (have_start && (!ch[offset].have_start ||
 814                                   ch[offset].start > start)) {
 815                        ch[offset].have_start = 0;
 816                        ch[offset].cycles = 0;
 817                        ch[offset].num = 0;
 818                        if (ch[offset].reset < 0xffff)
 819                                ch[offset].reset++;
 820                } else if (have_start &&
 821                           ch[offset].start < start)
 822                        return 0;
 823        }
 824        ch[offset].have_start = have_start;
 825        ch[offset].start = start;
 826        ch[offset].cycles += cycles;
 827        ch[offset].num++;
 828        return 0;
 829}
 830
 831static int __symbol__inc_addr_samples(struct symbol *sym, struct map *map,
 832                                      struct annotated_source *src, int evidx, u64 addr,
 833                                      struct perf_sample *sample)
 834{
 835        unsigned offset;
 836        struct sym_hist *h;
 837
 838        pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr));
 839
 840        if ((addr < sym->start || addr >= sym->end) &&
 841            (addr != sym->end || sym->start != sym->end)) {
 842                pr_debug("%s(%d): ERANGE! sym->name=%s, start=%#" PRIx64 ", addr=%#" PRIx64 ", end=%#" PRIx64 "\n",
 843                       __func__, __LINE__, sym->name, sym->start, addr, sym->end);
 844                return -ERANGE;
 845        }
 846
 847        offset = addr - sym->start;
 848        h = annotated_source__histogram(src, evidx);
 849        if (h == NULL) {
 850                pr_debug("%s(%d): ENOMEM! sym->name=%s, start=%#" PRIx64 ", addr=%#" PRIx64 ", end=%#" PRIx64 ", func: %d\n",
 851                         __func__, __LINE__, sym->name, sym->start, addr, sym->end, sym->type == STT_FUNC);
 852                return -ENOMEM;
 853        }
 854        h->nr_samples++;
 855        h->addr[offset].nr_samples++;
 856        h->period += sample->period;
 857        h->addr[offset].period += sample->period;
 858
 859        pr_debug3("%#" PRIx64 " %s: period++ [addr: %#" PRIx64 ", %#" PRIx64
 860                  ", evidx=%d] => nr_samples: %" PRIu64 ", period: %" PRIu64 "\n",
 861                  sym->start, sym->name, addr, addr - sym->start, evidx,
 862                  h->addr[offset].nr_samples, h->addr[offset].period);
 863        return 0;
 864}
 865
 866static struct cyc_hist *symbol__cycles_hist(struct symbol *sym)
 867{
 868        struct annotation *notes = symbol__annotation(sym);
 869
 870        if (notes->src == NULL) {
 871                notes->src = annotated_source__new();
 872                if (notes->src == NULL)
 873                        return NULL;
 874                goto alloc_cycles_hist;
 875        }
 876
 877        if (!notes->src->cycles_hist) {
 878alloc_cycles_hist:
 879                symbol__alloc_hist_cycles(sym);
 880        }
 881
 882        return notes->src->cycles_hist;
 883}
 884
 885struct annotated_source *symbol__hists(struct symbol *sym, int nr_hists)
 886{
 887        struct annotation *notes = symbol__annotation(sym);
 888
 889        if (notes->src == NULL) {
 890                notes->src = annotated_source__new();
 891                if (notes->src == NULL)
 892                        return NULL;
 893                goto alloc_histograms;
 894        }
 895
 896        if (notes->src->histograms == NULL) {
 897alloc_histograms:
 898                annotated_source__alloc_histograms(notes->src, symbol__size(sym),
 899                                                   nr_hists);
 900        }
 901
 902        return notes->src;
 903}
 904
 905static int symbol__inc_addr_samples(struct symbol *sym, struct map *map,
 906                                    struct perf_evsel *evsel, u64 addr,
 907                                    struct perf_sample *sample)
 908{
 909        struct annotated_source *src;
 910
 911        if (sym == NULL)
 912                return 0;
 913        src = symbol__hists(sym, evsel->evlist->nr_entries);
 914        if (src == NULL)
 915                return -ENOMEM;
 916        return __symbol__inc_addr_samples(sym, map, src, evsel->idx, addr, sample);
 917}
 918
 919static int symbol__account_cycles(u64 addr, u64 start,
 920                                  struct symbol *sym, unsigned cycles)
 921{
 922        struct cyc_hist *cycles_hist;
 923        unsigned offset;
 924
 925        if (sym == NULL)
 926                return 0;
 927        cycles_hist = symbol__cycles_hist(sym);
 928        if (cycles_hist == NULL)
 929                return -ENOMEM;
 930        if (addr < sym->start || addr >= sym->end)
 931                return -ERANGE;
 932
 933        if (start) {
 934                if (start < sym->start || start >= sym->end)
 935                        return -ERANGE;
 936                if (start >= addr)
 937                        start = 0;
 938        }
 939        offset = addr - sym->start;
 940        return __symbol__account_cycles(cycles_hist,
 941                                        start ? start - sym->start : 0,
 942                                        offset, cycles,
 943                                        !!start);
 944}
 945
 946int addr_map_symbol__account_cycles(struct addr_map_symbol *ams,
 947                                    struct addr_map_symbol *start,
 948                                    unsigned cycles)
 949{
 950        u64 saddr = 0;
 951        int err;
 952
 953        if (!cycles)
 954                return 0;
 955
 956        /*
 957         * Only set start when IPC can be computed. We can only
 958         * compute it when the basic block is completely in a single
 959         * function.
 960         * Special case the case when the jump is elsewhere, but
 961         * it starts on the function start.
 962         */
 963        if (start &&
 964                (start->sym == ams->sym ||
 965                 (ams->sym &&
 966                   start->addr == ams->sym->start + ams->map->start)))
 967                saddr = start->al_addr;
 968        if (saddr == 0)
 969                pr_debug2("BB with bad start: addr %"PRIx64" start %"PRIx64" sym %"PRIx64" saddr %"PRIx64"\n",
 970                        ams->addr,
 971                        start ? start->addr : 0,
 972                        ams->sym ? ams->sym->start + ams->map->start : 0,
 973                        saddr);
 974        err = symbol__account_cycles(ams->al_addr, saddr, ams->sym, cycles);
 975        if (err)
 976                pr_debug2("account_cycles failed %d\n", err);
 977        return err;
 978}
 979
 980static unsigned annotation__count_insn(struct annotation *notes, u64 start, u64 end)
 981{
 982        unsigned n_insn = 0;
 983        u64 offset;
 984
 985        for (offset = start; offset <= end; offset++) {
 986                if (notes->offsets[offset])
 987                        n_insn++;
 988        }
 989        return n_insn;
 990}
 991
 992static void annotation__count_and_fill(struct annotation *notes, u64 start, u64 end, struct cyc_hist *ch)
 993{
 994        unsigned n_insn;
 995        u64 offset;
 996
 997        n_insn = annotation__count_insn(notes, start, end);
 998        if (n_insn && ch->num && ch->cycles) {
 999                float ipc = n_insn / ((double)ch->cycles / (double)ch->num);
1000
1001                /* Hide data when there are too many overlaps. */
1002                if (ch->reset >= 0x7fff || ch->reset >= ch->num / 2)
1003                        return;
1004
1005                for (offset = start; offset <= end; offset++) {
1006                        struct annotation_line *al = notes->offsets[offset];
1007
1008                        if (al)
1009                                al->ipc = ipc;
1010                }
1011        }
1012}
1013
1014void annotation__compute_ipc(struct annotation *notes, size_t size)
1015{
1016        u64 offset;
1017
1018        if (!notes->src || !notes->src->cycles_hist)
1019                return;
1020
1021        pthread_mutex_lock(&notes->lock);
1022        for (offset = 0; offset < size; ++offset) {
1023                struct cyc_hist *ch;
1024
1025                ch = &notes->src->cycles_hist[offset];
1026                if (ch && ch->cycles) {
1027                        struct annotation_line *al;
1028
1029                        if (ch->have_start)
1030                                annotation__count_and_fill(notes, ch->start, offset, ch);
1031                        al = notes->offsets[offset];
1032                        if (al && ch->num_aggr) {
1033                                al->cycles = ch->cycles_aggr / ch->num_aggr;
1034                                al->cycles_max = ch->cycles_max;
1035                                al->cycles_min = ch->cycles_min;
1036                        }
1037                        notes->have_cycles = true;
1038                }
1039        }
1040        pthread_mutex_unlock(&notes->lock);
1041}
1042
1043int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, struct perf_sample *sample,
1044                                 struct perf_evsel *evsel)
1045{
1046        return symbol__inc_addr_samples(ams->sym, ams->map, evsel, ams->al_addr, sample);
1047}
1048
1049int hist_entry__inc_addr_samples(struct hist_entry *he, struct perf_sample *sample,
1050                                 struct perf_evsel *evsel, u64 ip)
1051{
1052        return symbol__inc_addr_samples(he->ms.sym, he->ms.map, evsel, ip, sample);
1053}
1054
1055static void disasm_line__init_ins(struct disasm_line *dl, struct arch *arch, struct map_symbol *ms)
1056{
1057        dl->ins.ops = ins__find(arch, dl->ins.name);
1058
1059        if (!dl->ins.ops)
1060                return;
1061
1062        if (dl->ins.ops->parse && dl->ins.ops->parse(arch, &dl->ops, ms) < 0)
1063                dl->ins.ops = NULL;
1064}
1065
1066static int disasm_line__parse(char *line, const char **namep, char **rawp)
1067{
1068        char tmp, *name = ltrim(line);
1069
1070        if (name[0] == '\0')
1071                return -1;
1072
1073        *rawp = name + 1;
1074
1075        while ((*rawp)[0] != '\0' && !isspace((*rawp)[0]))
1076                ++*rawp;
1077
1078        tmp = (*rawp)[0];
1079        (*rawp)[0] = '\0';
1080        *namep = strdup(name);
1081
1082        if (*namep == NULL)
1083                goto out_free_name;
1084
1085        (*rawp)[0] = tmp;
1086        *rawp = ltrim(*rawp);
1087
1088        return 0;
1089
1090out_free_name:
1091        free((void *)namep);
1092        *namep = NULL;
1093        return -1;
1094}
1095
1096struct annotate_args {
1097        size_t                   privsize;
1098        struct arch             *arch;
1099        struct map_symbol        ms;
1100        struct perf_evsel       *evsel;
1101        struct annotation_options *options;
1102        s64                      offset;
1103        char                    *line;
1104        int                      line_nr;
1105};
1106
1107static void annotation_line__delete(struct annotation_line *al)
1108{
1109        void *ptr = (void *) al - al->privsize;
1110
1111        free_srcline(al->path);
1112        zfree(&al->line);
1113        free(ptr);
1114}
1115
1116/*
1117 * Allocating the annotation line data with following
1118 * structure:
1119 *
1120 *    --------------------------------------
1121 *    private space | struct annotation_line
1122 *    --------------------------------------
1123 *
1124 * Size of the private space is stored in 'struct annotation_line'.
1125 *
1126 */
1127static struct annotation_line *
1128annotation_line__new(struct annotate_args *args, size_t privsize)
1129{
1130        struct annotation_line *al;
1131        struct perf_evsel *evsel = args->evsel;
1132        size_t size = privsize + sizeof(*al);
1133        int nr = 1;
1134
1135        if (perf_evsel__is_group_event(evsel))
1136                nr = evsel->nr_members;
1137
1138        size += sizeof(al->data[0]) * nr;
1139
1140        al = zalloc(size);
1141        if (al) {
1142                al = (void *) al + privsize;
1143                al->privsize   = privsize;
1144                al->offset     = args->offset;
1145                al->line       = strdup(args->line);
1146                al->line_nr    = args->line_nr;
1147                al->data_nr    = nr;
1148        }
1149
1150        return al;
1151}
1152
1153/*
1154 * Allocating the disasm annotation line data with
1155 * following structure:
1156 *
1157 *    ------------------------------------------------------------
1158 *    privsize space | struct disasm_line | struct annotation_line
1159 *    ------------------------------------------------------------
1160 *
1161 * We have 'struct annotation_line' member as last member
1162 * of 'struct disasm_line' to have an easy access.
1163 *
1164 */
1165static struct disasm_line *disasm_line__new(struct annotate_args *args)
1166{
1167        struct disasm_line *dl = NULL;
1168        struct annotation_line *al;
1169        size_t privsize = args->privsize + offsetof(struct disasm_line, al);
1170
1171        al = annotation_line__new(args, privsize);
1172        if (al != NULL) {
1173                dl = disasm_line(al);
1174
1175                if (dl->al.line == NULL)
1176                        goto out_delete;
1177
1178                if (args->offset != -1) {
1179                        if (disasm_line__parse(dl->al.line, &dl->ins.name, &dl->ops.raw) < 0)
1180                                goto out_free_line;
1181
1182                        disasm_line__init_ins(dl, args->arch, &args->ms);
1183                }
1184        }
1185
1186        return dl;
1187
1188out_free_line:
1189        zfree(&dl->al.line);
1190out_delete:
1191        free(dl);
1192        return NULL;
1193}
1194
1195void disasm_line__free(struct disasm_line *dl)
1196{
1197        if (dl->ins.ops && dl->ins.ops->free)
1198                dl->ins.ops->free(&dl->ops);
1199        else
1200                ins__delete(&dl->ops);
1201        free((void *)dl->ins.name);
1202        dl->ins.name = NULL;
1203        annotation_line__delete(&dl->al);
1204}
1205
1206int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, bool raw)
1207{
1208        if (raw || !dl->ins.ops)
1209                return scnprintf(bf, size, "%-6s %s", dl->ins.name, dl->ops.raw);
1210
1211        return ins__scnprintf(&dl->ins, bf, size, &dl->ops);
1212}
1213
1214static void annotation_line__add(struct annotation_line *al, struct list_head *head)
1215{
1216        list_add_tail(&al->node, head);
1217}
1218
1219struct annotation_line *
1220annotation_line__next(struct annotation_line *pos, struct list_head *head)
1221{
1222        list_for_each_entry_continue(pos, head, node)
1223                if (pos->offset >= 0)
1224                        return pos;
1225
1226        return NULL;
1227}
1228
1229static const char *annotate__address_color(struct block_range *br)
1230{
1231        double cov = block_range__coverage(br);
1232
1233        if (cov >= 0) {
1234                /* mark red for >75% coverage */
1235                if (cov > 0.75)
1236                        return PERF_COLOR_RED;
1237
1238                /* mark dull for <1% coverage */
1239                if (cov < 0.01)
1240                        return PERF_COLOR_NORMAL;
1241        }
1242
1243        return PERF_COLOR_MAGENTA;
1244}
1245
1246static const char *annotate__asm_color(struct block_range *br)
1247{
1248        double cov = block_range__coverage(br);
1249
1250        if (cov >= 0) {
1251                /* mark dull for <1% coverage */
1252                if (cov < 0.01)
1253                        return PERF_COLOR_NORMAL;
1254        }
1255
1256        return PERF_COLOR_BLUE;
1257}
1258
1259static void annotate__branch_printf(struct block_range *br, u64 addr)
1260{
1261        bool emit_comment = true;
1262
1263        if (!br)
1264                return;
1265
1266#if 1
1267        if (br->is_target && br->start == addr) {
1268                struct block_range *branch = br;
1269                double p;
1270
1271                /*
1272                 * Find matching branch to our target.
1273                 */
1274                while (!branch->is_branch)
1275                        branch = block_range__next(branch);
1276
1277                p = 100 *(double)br->entry / branch->coverage;
1278
1279                if (p > 0.1) {
1280                        if (emit_comment) {
1281                                emit_comment = false;
1282                                printf("\t#");
1283                        }
1284
1285                        /*
1286                         * The percentage of coverage joined at this target in relation
1287                         * to the next branch.
1288                         */
1289                        printf(" +%.2f%%", p);
1290                }
1291        }
1292#endif
1293        if (br->is_branch && br->end == addr) {
1294                double p = 100*(double)br->taken / br->coverage;
1295
1296                if (p > 0.1) {
1297                        if (emit_comment) {
1298                                emit_comment = false;
1299                                printf("\t#");
1300                        }
1301
1302                        /*
1303                         * The percentage of coverage leaving at this branch, and
1304                         * its prediction ratio.
1305                         */
1306                        printf(" -%.2f%% (p:%.2f%%)", p, 100*(double)br->pred  / br->taken);
1307                }
1308        }
1309}
1310
1311static int disasm_line__print(struct disasm_line *dl, u64 start, int addr_fmt_width)
1312{
1313        s64 offset = dl->al.offset;
1314        const u64 addr = start + offset;
1315        struct block_range *br;
1316
1317        br = block_range__find(addr);
1318        color_fprintf(stdout, annotate__address_color(br), "  %*" PRIx64 ":", addr_fmt_width, addr);
1319        color_fprintf(stdout, annotate__asm_color(br), "%s", dl->al.line);
1320        annotate__branch_printf(br, addr);
1321        return 0;
1322}
1323
1324static int
1325annotation_line__print(struct annotation_line *al, struct symbol *sym, u64 start,
1326                       struct perf_evsel *evsel, u64 len, int min_pcnt, int printed,
1327                       int max_lines, struct annotation_line *queue, int addr_fmt_width,
1328                       int percent_type)
1329{
1330        struct disasm_line *dl = container_of(al, struct disasm_line, al);
1331        static const char *prev_line;
1332        static const char *prev_color;
1333
1334        if (al->offset != -1) {
1335                double max_percent = 0.0;
1336                int i, nr_percent = 1;
1337                const char *color;
1338                struct annotation *notes = symbol__annotation(sym);
1339
1340                for (i = 0; i < al->data_nr; i++) {
1341                        double percent;
1342
1343                        percent = annotation_data__percent(&al->data[i],
1344                                                           percent_type);
1345
1346                        if (percent > max_percent)
1347                                max_percent = percent;
1348                }
1349
1350                if (al->data_nr > nr_percent)
1351                        nr_percent = al->data_nr;
1352
1353                if (max_percent < min_pcnt)
1354                        return -1;
1355
1356                if (max_lines && printed >= max_lines)
1357                        return 1;
1358
1359                if (queue != NULL) {
1360                        list_for_each_entry_from(queue, &notes->src->source, node) {
1361                                if (queue == al)
1362                                        break;
1363                                annotation_line__print(queue, sym, start, evsel, len,
1364                                                       0, 0, 1, NULL, addr_fmt_width,
1365                                                       percent_type);
1366                        }
1367                }
1368
1369                color = get_percent_color(max_percent);
1370
1371                /*
1372                 * Also color the filename and line if needed, with
1373                 * the same color than the percentage. Don't print it
1374                 * twice for close colored addr with the same filename:line
1375                 */
1376                if (al->path) {
1377                        if (!prev_line || strcmp(prev_line, al->path)
1378                                       || color != prev_color) {
1379                                color_fprintf(stdout, color, " %s", al->path);
1380                                prev_line = al->path;
1381                                prev_color = color;
1382                        }
1383                }
1384
1385                for (i = 0; i < nr_percent; i++) {
1386                        struct annotation_data *data = &al->data[i];
1387                        double percent;
1388
1389                        percent = annotation_data__percent(data, percent_type);
1390                        color = get_percent_color(percent);
1391
1392                        if (symbol_conf.show_total_period)
1393                                color_fprintf(stdout, color, " %11" PRIu64,
1394                                              data->he.period);
1395                        else if (symbol_conf.show_nr_samples)
1396                                color_fprintf(stdout, color, " %7" PRIu64,
1397                                              data->he.nr_samples);
1398                        else
1399                                color_fprintf(stdout, color, " %7.2f", percent);
1400                }
1401
1402                printf(" : ");
1403
1404                disasm_line__print(dl, start, addr_fmt_width);
1405                printf("\n");
1406        } else if (max_lines && printed >= max_lines)
1407                return 1;
1408        else {
1409                int width = symbol_conf.show_total_period ? 12 : 8;
1410
1411                if (queue)
1412                        return -1;
1413
1414                if (perf_evsel__is_group_event(evsel))
1415                        width *= evsel->nr_members;
1416
1417                if (!*al->line)
1418                        printf(" %*s:\n", width, " ");
1419                else
1420                        printf(" %*s:     %*s %s\n", width, " ", addr_fmt_width, " ", al->line);
1421        }
1422
1423        return 0;
1424}
1425
1426/*
1427 * symbol__parse_objdump_line() parses objdump output (with -d --no-show-raw)
1428 * which looks like following
1429 *
1430 *  0000000000415500 <_init>:
1431 *    415500:       sub    $0x8,%rsp
1432 *    415504:       mov    0x2f5ad5(%rip),%rax        # 70afe0 <_DYNAMIC+0x2f8>
1433 *    41550b:       test   %rax,%rax
1434 *    41550e:       je     415515 <_init+0x15>
1435 *    415510:       callq  416e70 <__gmon_start__@plt>
1436 *    415515:       add    $0x8,%rsp
1437 *    415519:       retq
1438 *
1439 * it will be parsed and saved into struct disasm_line as
1440 *  <offset>       <name>  <ops.raw>
1441 *
1442 * The offset will be a relative offset from the start of the symbol and -1
1443 * means that it's not a disassembly line so should be treated differently.
1444 * The ops.raw part will be parsed further according to type of the instruction.
1445 */
1446static int symbol__parse_objdump_line(struct symbol *sym, FILE *file,
1447                                      struct annotate_args *args,
1448                                      int *line_nr)
1449{
1450        struct map *map = args->ms.map;
1451        struct annotation *notes = symbol__annotation(sym);
1452        struct disasm_line *dl;
1453        char *line = NULL, *parsed_line, *tmp, *tmp2;
1454        size_t line_len;
1455        s64 line_ip, offset = -1;
1456        regmatch_t match[2];
1457
1458        if (getline(&line, &line_len, file) < 0)
1459                return -1;
1460
1461        if (!line)
1462                return -1;
1463
1464        line_ip = -1;
1465        parsed_line = rtrim(line);
1466
1467        /* /filename:linenr ? Save line number and ignore. */
1468        if (regexec(&file_lineno, parsed_line, 2, match, 0) == 0) {
1469                *line_nr = atoi(parsed_line + match[1].rm_so);
1470                return 0;
1471        }
1472
1473        tmp = ltrim(parsed_line);
1474        if (*tmp) {
1475                /*
1476                 * Parse hexa addresses followed by ':'
1477                 */
1478                line_ip = strtoull(tmp, &tmp2, 16);
1479                if (*tmp2 != ':' || tmp == tmp2 || tmp2[1] == '\0')
1480                        line_ip = -1;
1481        }
1482
1483        if (line_ip != -1) {
1484                u64 start = map__rip_2objdump(map, sym->start),
1485                    end = map__rip_2objdump(map, sym->end);
1486
1487                offset = line_ip - start;
1488                if ((u64)line_ip < start || (u64)line_ip >= end)
1489                        offset = -1;
1490                else
1491                        parsed_line = tmp2 + 1;
1492        }
1493
1494        args->offset  = offset;
1495        args->line    = parsed_line;
1496        args->line_nr = *line_nr;
1497        args->ms.sym  = sym;
1498
1499        dl = disasm_line__new(args);
1500        free(line);
1501        (*line_nr)++;
1502
1503        if (dl == NULL)
1504                return -1;
1505
1506        if (!disasm_line__has_local_offset(dl)) {
1507                dl->ops.target.offset = dl->ops.target.addr -
1508                                        map__rip_2objdump(map, sym->start);
1509                dl->ops.target.offset_avail = true;
1510        }
1511
1512        /* kcore has no symbols, so add the call target symbol */
1513        if (dl->ins.ops && ins__is_call(&dl->ins) && !dl->ops.target.sym) {
1514                struct addr_map_symbol target = {
1515                        .map = map,
1516                        .addr = dl->ops.target.addr,
1517                };
1518
1519                if (!map_groups__find_ams(&target) &&
1520                    target.sym->start == target.al_addr)
1521                        dl->ops.target.sym = target.sym;
1522        }
1523
1524        annotation_line__add(&dl->al, &notes->src->source);
1525
1526        return 0;
1527}
1528
1529static __attribute__((constructor)) void symbol__init_regexpr(void)
1530{
1531        regcomp(&file_lineno, "^/[^:]+:([0-9]+)", REG_EXTENDED);
1532}
1533
1534static void delete_last_nop(struct symbol *sym)
1535{
1536        struct annotation *notes = symbol__annotation(sym);
1537        struct list_head *list = &notes->src->source;
1538        struct disasm_line *dl;
1539
1540        while (!list_empty(list)) {
1541                dl = list_entry(list->prev, struct disasm_line, al.node);
1542
1543                if (dl->ins.ops) {
1544                        if (dl->ins.ops != &nop_ops)
1545                                return;
1546                } else {
1547                        if (!strstr(dl->al.line, " nop ") &&
1548                            !strstr(dl->al.line, " nopl ") &&
1549                            !strstr(dl->al.line, " nopw "))
1550                                return;
1551                }
1552
1553                list_del(&dl->al.node);
1554                disasm_line__free(dl);
1555        }
1556}
1557
1558int symbol__strerror_disassemble(struct symbol *sym __maybe_unused, struct map *map,
1559                              int errnum, char *buf, size_t buflen)
1560{
1561        struct dso *dso = map->dso;
1562
1563        BUG_ON(buflen == 0);
1564
1565        if (errnum >= 0) {
1566                str_error_r(errnum, buf, buflen);
1567                return 0;
1568        }
1569
1570        switch (errnum) {
1571        case SYMBOL_ANNOTATE_ERRNO__NO_VMLINUX: {
1572                char bf[SBUILD_ID_SIZE + 15] = " with build id ";
1573                char *build_id_msg = NULL;
1574
1575                if (dso->has_build_id) {
1576                        build_id__sprintf(dso->build_id,
1577                                          sizeof(dso->build_id), bf + 15);
1578                        build_id_msg = bf;
1579                }
1580                scnprintf(buf, buflen,
1581                          "No vmlinux file%s\nwas found in the path.\n\n"
1582                          "Note that annotation using /proc/kcore requires CAP_SYS_RAWIO capability.\n\n"
1583                          "Please use:\n\n"
1584                          "  perf buildid-cache -vu vmlinux\n\n"
1585                          "or:\n\n"
1586                          "  --vmlinux vmlinux\n", build_id_msg ?: "");
1587        }
1588                break;
1589        default:
1590                scnprintf(buf, buflen, "Internal error: Invalid %d error code\n", errnum);
1591                break;
1592        }
1593
1594        return 0;
1595}
1596
1597static int dso__disassemble_filename(struct dso *dso, char *filename, size_t filename_size)
1598{
1599        char linkname[PATH_MAX];
1600        char *build_id_filename;
1601        char *build_id_path = NULL;
1602        char *pos;
1603
1604        if (dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS &&
1605            !dso__is_kcore(dso))
1606                return SYMBOL_ANNOTATE_ERRNO__NO_VMLINUX;
1607
1608        build_id_filename = dso__build_id_filename(dso, NULL, 0, false);
1609        if (build_id_filename) {
1610                __symbol__join_symfs(filename, filename_size, build_id_filename);
1611                free(build_id_filename);
1612        } else {
1613                if (dso->has_build_id)
1614                        return ENOMEM;
1615                goto fallback;
1616        }
1617
1618        build_id_path = strdup(filename);
1619        if (!build_id_path)
1620                return -1;
1621
1622        /*
1623         * old style build-id cache has name of XX/XXXXXXX.. while
1624         * new style has XX/XXXXXXX../{elf,kallsyms,vdso}.
1625         * extract the build-id part of dirname in the new style only.
1626         */
1627        pos = strrchr(build_id_path, '/');
1628        if (pos && strlen(pos) < SBUILD_ID_SIZE - 2)
1629                dirname(build_id_path);
1630
1631        if (dso__is_kcore(dso) ||
1632            readlink(build_id_path, linkname, sizeof(linkname)) < 0 ||
1633            strstr(linkname, DSO__NAME_KALLSYMS) ||
1634            access(filename, R_OK)) {
1635fallback:
1636                /*
1637                 * If we don't have build-ids or the build-id file isn't in the
1638                 * cache, or is just a kallsyms file, well, lets hope that this
1639                 * DSO is the same as when 'perf record' ran.
1640                 */
1641                __symbol__join_symfs(filename, filename_size, dso->long_name);
1642        }
1643
1644        free(build_id_path);
1645        return 0;
1646}
1647
1648static int symbol__disassemble(struct symbol *sym, struct annotate_args *args)
1649{
1650        struct annotation_options *opts = args->options;
1651        struct map *map = args->ms.map;
1652        struct dso *dso = map->dso;
1653        char *command;
1654        FILE *file;
1655        char symfs_filename[PATH_MAX];
1656        struct kcore_extract kce;
1657        bool delete_extract = false;
1658        bool decomp = false;
1659        int stdout_fd[2];
1660        int lineno = 0;
1661        int nline;
1662        pid_t pid;
1663        int err = dso__disassemble_filename(dso, symfs_filename, sizeof(symfs_filename));
1664
1665        if (err)
1666                return err;
1667
1668        pr_debug("%s: filename=%s, sym=%s, start=%#" PRIx64 ", end=%#" PRIx64 "\n", __func__,
1669                 symfs_filename, sym->name, map->unmap_ip(map, sym->start),
1670                 map->unmap_ip(map, sym->end));
1671
1672        pr_debug("annotating [%p] %30s : [%p] %30s\n",
1673                 dso, dso->long_name, sym, sym->name);
1674
1675        if (dso__is_kcore(dso)) {
1676                kce.kcore_filename = symfs_filename;
1677                kce.addr = map__rip_2objdump(map, sym->start);
1678                kce.offs = sym->start;
1679                kce.len = sym->end - sym->start;
1680                if (!kcore_extract__create(&kce)) {
1681                        delete_extract = true;
1682                        strlcpy(symfs_filename, kce.extract_filename,
1683                                sizeof(symfs_filename));
1684                }
1685        } else if (dso__needs_decompress(dso)) {
1686                char tmp[KMOD_DECOMP_LEN];
1687
1688                if (dso__decompress_kmodule_path(dso, symfs_filename,
1689                                                 tmp, sizeof(tmp)) < 0)
1690                        goto out;
1691
1692                decomp = true;
1693                strcpy(symfs_filename, tmp);
1694        }
1695
1696        err = asprintf(&command,
1697                 "%s %s%s --start-address=0x%016" PRIx64
1698                 " --stop-address=0x%016" PRIx64
1699                 " -l -d %s %s -C \"%s\" 2>/dev/null|grep -v \"%s:\"|expand",
1700                 opts->objdump_path ?: "objdump",
1701                 opts->disassembler_style ? "-M " : "",
1702                 opts->disassembler_style ?: "",
1703                 map__rip_2objdump(map, sym->start),
1704                 map__rip_2objdump(map, sym->end),
1705                 opts->show_asm_raw ? "" : "--no-show-raw",
1706                 opts->annotate_src ? "-S" : "",
1707                 symfs_filename, symfs_filename);
1708
1709        if (err < 0) {
1710                pr_err("Failure allocating memory for the command to run\n");
1711                goto out_remove_tmp;
1712        }
1713
1714        pr_debug("Executing: %s\n", command);
1715
1716        err = -1;
1717        if (pipe(stdout_fd) < 0) {
1718                pr_err("Failure creating the pipe to run %s\n", command);
1719                goto out_free_command;
1720        }
1721
1722        pid = fork();
1723        if (pid < 0) {
1724                pr_err("Failure forking to run %s\n", command);
1725                goto out_close_stdout;
1726        }
1727
1728        if (pid == 0) {
1729                close(stdout_fd[0]);
1730                dup2(stdout_fd[1], 1);
1731                close(stdout_fd[1]);
1732                execl("/bin/sh", "sh", "-c", command, NULL);
1733                perror(command);
1734                exit(-1);
1735        }
1736
1737        close(stdout_fd[1]);
1738
1739        file = fdopen(stdout_fd[0], "r");
1740        if (!file) {
1741                pr_err("Failure creating FILE stream for %s\n", command);
1742                /*
1743                 * If we were using debug info should retry with
1744                 * original binary.
1745                 */
1746                goto out_free_command;
1747        }
1748
1749        nline = 0;
1750        while (!feof(file)) {
1751                /*
1752                 * The source code line number (lineno) needs to be kept in
1753                 * accross calls to symbol__parse_objdump_line(), so that it
1754                 * can associate it with the instructions till the next one.
1755                 * See disasm_line__new() and struct disasm_line::line_nr.
1756                 */
1757                if (symbol__parse_objdump_line(sym, file, args, &lineno) < 0)
1758                        break;
1759                nline++;
1760        }
1761
1762        if (nline == 0)
1763                pr_err("No output from %s\n", command);
1764
1765        /*
1766         * kallsyms does not have symbol sizes so there may a nop at the end.
1767         * Remove it.
1768         */
1769        if (dso__is_kcore(dso))
1770                delete_last_nop(sym);
1771
1772        fclose(file);
1773        err = 0;
1774out_free_command:
1775        free(command);
1776out_remove_tmp:
1777        close(stdout_fd[0]);
1778
1779        if (decomp)
1780                unlink(symfs_filename);
1781
1782        if (delete_extract)
1783                kcore_extract__delete(&kce);
1784out:
1785        return err;
1786
1787out_close_stdout:
1788        close(stdout_fd[1]);
1789        goto out_free_command;
1790}
1791
1792static void calc_percent(struct sym_hist *sym_hist,
1793                         struct hists *hists,
1794                         struct annotation_data *data,
1795                         s64 offset, s64 end)
1796{
1797        unsigned int hits = 0;
1798        u64 period = 0;
1799
1800        while (offset < end) {
1801                hits   += sym_hist->addr[offset].nr_samples;
1802                period += sym_hist->addr[offset].period;
1803                ++offset;
1804        }
1805
1806        if (sym_hist->nr_samples) {
1807                data->he.period     = period;
1808                data->he.nr_samples = hits;
1809                data->percent[PERCENT_HITS_LOCAL] = 100.0 * hits / sym_hist->nr_samples;
1810        }
1811
1812        if (hists->stats.nr_non_filtered_samples)
1813                data->percent[PERCENT_HITS_GLOBAL] = 100.0 * hits / hists->stats.nr_non_filtered_samples;
1814
1815        if (sym_hist->period)
1816                data->percent[PERCENT_PERIOD_LOCAL] = 100.0 * period / sym_hist->period;
1817
1818        if (hists->stats.total_period)
1819                data->percent[PERCENT_PERIOD_GLOBAL] = 100.0 * period / hists->stats.total_period;
1820}
1821
1822static void annotation__calc_percent(struct annotation *notes,
1823                                     struct perf_evsel *leader, s64 len)
1824{
1825        struct annotation_line *al, *next;
1826        struct perf_evsel *evsel;
1827
1828        list_for_each_entry(al, &notes->src->source, node) {
1829                s64 end;
1830                int i = 0;
1831
1832                if (al->offset == -1)
1833                        continue;
1834
1835                next = annotation_line__next(al, &notes->src->source);
1836                end  = next ? next->offset : len;
1837
1838                for_each_group_evsel(evsel, leader) {
1839                        struct hists *hists = evsel__hists(evsel);
1840                        struct annotation_data *data;
1841                        struct sym_hist *sym_hist;
1842
1843                        BUG_ON(i >= al->data_nr);
1844
1845                        sym_hist = annotation__histogram(notes, evsel->idx);
1846                        data = &al->data[i++];
1847
1848                        calc_percent(sym_hist, hists, data, al->offset, end);
1849                }
1850        }
1851}
1852
1853void symbol__calc_percent(struct symbol *sym, struct perf_evsel *evsel)
1854{
1855        struct annotation *notes = symbol__annotation(sym);
1856
1857        annotation__calc_percent(notes, evsel, symbol__size(sym));
1858}
1859
1860int symbol__annotate(struct symbol *sym, struct map *map,
1861                     struct perf_evsel *evsel, size_t privsize,
1862                     struct annotation_options *options,
1863                     struct arch **parch)
1864{
1865        struct annotate_args args = {
1866                .privsize       = privsize,
1867                .evsel          = evsel,
1868                .options        = options,
1869        };
1870        struct perf_env *env = perf_evsel__env(evsel);
1871        const char *arch_name = perf_env__arch(env);
1872        struct arch *arch;
1873        int err;
1874
1875        if (!arch_name)
1876                return -1;
1877
1878        args.arch = arch = arch__find(arch_name);
1879        if (arch == NULL)
1880                return -ENOTSUP;
1881
1882        if (parch)
1883                *parch = arch;
1884
1885        if (arch->init) {
1886                err = arch->init(arch, env ? env->cpuid : NULL);
1887                if (err) {
1888                        pr_err("%s: failed to initialize %s arch priv area\n", __func__, arch->name);
1889                        return err;
1890                }
1891        }
1892
1893        args.ms.map = map;
1894        args.ms.sym = sym;
1895
1896        return symbol__disassemble(sym, &args);
1897}
1898
1899static void insert_source_line(struct rb_root *root, struct annotation_line *al,
1900                               struct annotation_options *opts)
1901{
1902        struct annotation_line *iter;
1903        struct rb_node **p = &root->rb_node;
1904        struct rb_node *parent = NULL;
1905        int i, ret;
1906
1907        while (*p != NULL) {
1908                parent = *p;
1909                iter = rb_entry(parent, struct annotation_line, rb_node);
1910
1911                ret = strcmp(iter->path, al->path);
1912                if (ret == 0) {
1913                        for (i = 0; i < al->data_nr; i++) {
1914                                iter->data[i].percent_sum += annotation_data__percent(&al->data[i],
1915                                                                                      opts->percent_type);
1916                        }
1917                        return;
1918                }
1919
1920                if (ret < 0)
1921                        p = &(*p)->rb_left;
1922                else
1923                        p = &(*p)->rb_right;
1924        }
1925
1926        for (i = 0; i < al->data_nr; i++) {
1927                al->data[i].percent_sum = annotation_data__percent(&al->data[i],
1928                                                                   opts->percent_type);
1929        }
1930
1931        rb_link_node(&al->rb_node, parent, p);
1932        rb_insert_color(&al->rb_node, root);
1933}
1934
1935static int cmp_source_line(struct annotation_line *a, struct annotation_line *b)
1936{
1937        int i;
1938
1939        for (i = 0; i < a->data_nr; i++) {
1940                if (a->data[i].percent_sum == b->data[i].percent_sum)
1941                        continue;
1942                return a->data[i].percent_sum > b->data[i].percent_sum;
1943        }
1944
1945        return 0;
1946}
1947
1948static void __resort_source_line(struct rb_root *root, struct annotation_line *al)
1949{
1950        struct annotation_line *iter;
1951        struct rb_node **p = &root->rb_node;
1952        struct rb_node *parent = NULL;
1953
1954        while (*p != NULL) {
1955                parent = *p;
1956                iter = rb_entry(parent, struct annotation_line, rb_node);
1957
1958                if (cmp_source_line(al, iter))
1959                        p = &(*p)->rb_left;
1960                else
1961                        p = &(*p)->rb_right;
1962        }
1963
1964        rb_link_node(&al->rb_node, parent, p);
1965        rb_insert_color(&al->rb_node, root);
1966}
1967
1968static void resort_source_line(struct rb_root *dest_root, struct rb_root *src_root)
1969{
1970        struct annotation_line *al;
1971        struct rb_node *node;
1972
1973        node = rb_first(src_root);
1974        while (node) {
1975                struct rb_node *next;
1976
1977                al = rb_entry(node, struct annotation_line, rb_node);
1978                next = rb_next(node);
1979                rb_erase(node, src_root);
1980
1981                __resort_source_line(dest_root, al);
1982                node = next;
1983        }
1984}
1985
1986static void print_summary(struct rb_root *root, const char *filename)
1987{
1988        struct annotation_line *al;
1989        struct rb_node *node;
1990
1991        printf("\nSorted summary for file %s\n", filename);
1992        printf("----------------------------------------------\n\n");
1993
1994        if (RB_EMPTY_ROOT(root)) {
1995                printf(" Nothing higher than %1.1f%%\n", MIN_GREEN);
1996                return;
1997        }
1998
1999        node = rb_first(root);
2000        while (node) {
2001                double percent, percent_max = 0.0;
2002                const char *color;
2003                char *path;
2004                int i;
2005
2006                al = rb_entry(node, struct annotation_line, rb_node);
2007                for (i = 0; i < al->data_nr; i++) {
2008                        percent = al->data[i].percent_sum;
2009                        color = get_percent_color(percent);
2010                        color_fprintf(stdout, color, " %7.2f", percent);
2011
2012                        if (percent > percent_max)
2013                                percent_max = percent;
2014                }
2015
2016                path = al->path;
2017                color = get_percent_color(percent_max);
2018                color_fprintf(stdout, color, " %s\n", path);
2019
2020                node = rb_next(node);
2021        }
2022}
2023
2024static void symbol__annotate_hits(struct symbol *sym, struct perf_evsel *evsel)
2025{
2026        struct annotation *notes = symbol__annotation(sym);
2027        struct sym_hist *h = annotation__histogram(notes, evsel->idx);
2028        u64 len = symbol__size(sym), offset;
2029
2030        for (offset = 0; offset < len; ++offset)
2031                if (h->addr[offset].nr_samples != 0)
2032                        printf("%*" PRIx64 ": %" PRIu64 "\n", BITS_PER_LONG / 2,
2033                               sym->start + offset, h->addr[offset].nr_samples);
2034        printf("%*s: %" PRIu64 "\n", BITS_PER_LONG / 2, "h->nr_samples", h->nr_samples);
2035}
2036
2037static int annotated_source__addr_fmt_width(struct list_head *lines, u64 start)
2038{
2039        char bf[32];
2040        struct annotation_line *line;
2041
2042        list_for_each_entry_reverse(line, lines, node) {
2043                if (line->offset != -1)
2044                        return scnprintf(bf, sizeof(bf), "%" PRIx64, start + line->offset);
2045        }
2046
2047        return 0;
2048}
2049
2050int symbol__annotate_printf(struct symbol *sym, struct map *map,
2051                            struct perf_evsel *evsel,
2052                            struct annotation_options *opts)
2053{
2054        struct dso *dso = map->dso;
2055        char *filename;
2056        const char *d_filename;
2057        const char *evsel_name = perf_evsel__name(evsel);
2058        struct annotation *notes = symbol__annotation(sym);
2059        struct sym_hist *h = annotation__histogram(notes, evsel->idx);
2060        struct annotation_line *pos, *queue = NULL;
2061        u64 start = map__rip_2objdump(map, sym->start);
2062        int printed = 2, queue_len = 0, addr_fmt_width;
2063        int more = 0;
2064        bool context = opts->context;
2065        u64 len;
2066        int width = symbol_conf.show_total_period ? 12 : 8;
2067        int graph_dotted_len;
2068        char buf[512];
2069
2070        filename = strdup(dso->long_name);
2071        if (!filename)
2072                return -ENOMEM;
2073
2074        if (opts->full_path)
2075                d_filename = filename;
2076        else
2077                d_filename = basename(filename);
2078
2079        len = symbol__size(sym);
2080
2081        if (perf_evsel__is_group_event(evsel)) {
2082                width *= evsel->nr_members;
2083                perf_evsel__group_desc(evsel, buf, sizeof(buf));
2084                evsel_name = buf;
2085        }
2086
2087        graph_dotted_len = printf(" %-*.*s|     Source code & Disassembly of %s for %s (%" PRIu64 " samples, "
2088                                  "percent: %s)\n",
2089                                  width, width, symbol_conf.show_total_period ? "Period" :
2090                                  symbol_conf.show_nr_samples ? "Samples" : "Percent",
2091                                  d_filename, evsel_name, h->nr_samples,
2092                                  percent_type_str(opts->percent_type));
2093
2094        printf("%-*.*s----\n",
2095               graph_dotted_len, graph_dotted_len, graph_dotted_line);
2096
2097        if (verbose > 0)
2098                symbol__annotate_hits(sym, evsel);
2099
2100        addr_fmt_width = annotated_source__addr_fmt_width(&notes->src->source, start);
2101
2102        list_for_each_entry(pos, &notes->src->source, node) {
2103                int err;
2104
2105                if (context && queue == NULL) {
2106                        queue = pos;
2107                        queue_len = 0;
2108                }
2109
2110                err = annotation_line__print(pos, sym, start, evsel, len,
2111                                             opts->min_pcnt, printed, opts->max_lines,
2112                                             queue, addr_fmt_width, opts->percent_type);
2113
2114                switch (err) {
2115                case 0:
2116                        ++printed;
2117                        if (context) {
2118                                printed += queue_len;
2119                                queue = NULL;
2120                                queue_len = 0;
2121                        }
2122                        break;
2123                case 1:
2124                        /* filtered by max_lines */
2125                        ++more;
2126                        break;
2127                case -1:
2128                default:
2129                        /*
2130                         * Filtered by min_pcnt or non IP lines when
2131                         * context != 0
2132                         */
2133                        if (!context)
2134                                break;
2135                        if (queue_len == context)
2136                                queue = list_entry(queue->node.next, typeof(*queue), node);
2137                        else
2138                                ++queue_len;
2139                        break;
2140                }
2141        }
2142
2143        free(filename);
2144
2145        return more;
2146}
2147
2148static void FILE__set_percent_color(void *fp __maybe_unused,
2149                                    double percent __maybe_unused,
2150                                    bool current __maybe_unused)
2151{
2152}
2153
2154static int FILE__set_jumps_percent_color(void *fp __maybe_unused,
2155                                         int nr __maybe_unused, bool current __maybe_unused)
2156{
2157        return 0;
2158}
2159
2160static int FILE__set_color(void *fp __maybe_unused, int color __maybe_unused)
2161{
2162        return 0;
2163}
2164
2165static void FILE__printf(void *fp, const char *fmt, ...)
2166{
2167        va_list args;
2168
2169        va_start(args, fmt);
2170        vfprintf(fp, fmt, args);
2171        va_end(args);
2172}
2173
2174static void FILE__write_graph(void *fp, int graph)
2175{
2176        const char *s;
2177        switch (graph) {
2178
2179        case DARROW_CHAR: s = "↓"; break;
2180        case UARROW_CHAR: s = "↑"; break;
2181        case LARROW_CHAR: s = "←"; break;
2182        case RARROW_CHAR: s = "→"; break;
2183        default:                s = "?"; break;
2184        }
2185
2186        fputs(s, fp);
2187}
2188
2189static int symbol__annotate_fprintf2(struct symbol *sym, FILE *fp,
2190                                     struct annotation_options *opts)
2191{
2192        struct annotation *notes = symbol__annotation(sym);
2193        struct annotation_write_ops wops = {
2194                .first_line              = true,
2195                .obj                     = fp,
2196                .set_color               = FILE__set_color,
2197                .set_percent_color       = FILE__set_percent_color,
2198                .set_jumps_percent_color = FILE__set_jumps_percent_color,
2199                .printf                  = FILE__printf,
2200                .write_graph             = FILE__write_graph,
2201        };
2202        struct annotation_line *al;
2203
2204        list_for_each_entry(al, &notes->src->source, node) {
2205                if (annotation_line__filter(al, notes))
2206                        continue;
2207                annotation_line__write(al, notes, &wops, opts);
2208                fputc('\n', fp);
2209                wops.first_line = false;
2210        }
2211
2212        return 0;
2213}
2214
2215int map_symbol__annotation_dump(struct map_symbol *ms, struct perf_evsel *evsel,
2216                                struct annotation_options *opts)
2217{
2218        const char *ev_name = perf_evsel__name(evsel);
2219        char buf[1024];
2220        char *filename;
2221        int err = -1;
2222        FILE *fp;
2223
2224        if (asprintf(&filename, "%s.annotation", ms->sym->name) < 0)
2225                return -1;
2226
2227        fp = fopen(filename, "w");
2228        if (fp == NULL)
2229                goto out_free_filename;
2230
2231        if (perf_evsel__is_group_event(evsel)) {
2232                perf_evsel__group_desc(evsel, buf, sizeof(buf));
2233                ev_name = buf;
2234        }
2235
2236        fprintf(fp, "%s() %s\nEvent: %s\n\n",
2237                ms->sym->name, ms->map->dso->long_name, ev_name);
2238        symbol__annotate_fprintf2(ms->sym, fp, opts);
2239
2240        fclose(fp);
2241        err = 0;
2242out_free_filename:
2243        free(filename);
2244        return err;
2245}
2246
2247void symbol__annotate_zero_histogram(struct symbol *sym, int evidx)
2248{
2249        struct annotation *notes = symbol__annotation(sym);
2250        struct sym_hist *h = annotation__histogram(notes, evidx);
2251
2252        memset(h, 0, notes->src->sizeof_sym_hist);
2253}
2254
2255void symbol__annotate_decay_histogram(struct symbol *sym, int evidx)
2256{
2257        struct annotation *notes = symbol__annotation(sym);
2258        struct sym_hist *h = annotation__histogram(notes, evidx);
2259        int len = symbol__size(sym), offset;
2260
2261        h->nr_samples = 0;
2262        for (offset = 0; offset < len; ++offset) {
2263                h->addr[offset].nr_samples = h->addr[offset].nr_samples * 7 / 8;
2264                h->nr_samples += h->addr[offset].nr_samples;
2265        }
2266}
2267
2268void annotated_source__purge(struct annotated_source *as)
2269{
2270        struct annotation_line *al, *n;
2271
2272        list_for_each_entry_safe(al, n, &as->source, node) {
2273                list_del(&al->node);
2274                disasm_line__free(disasm_line(al));
2275        }
2276}
2277
2278static size_t disasm_line__fprintf(struct disasm_line *dl, FILE *fp)
2279{
2280        size_t printed;
2281
2282        if (dl->al.offset == -1)
2283                return fprintf(fp, "%s\n", dl->al.line);
2284
2285        printed = fprintf(fp, "%#" PRIx64 " %s", dl->al.offset, dl->ins.name);
2286
2287        if (dl->ops.raw[0] != '\0') {
2288                printed += fprintf(fp, "%.*s %s\n", 6 - (int)printed, " ",
2289                                   dl->ops.raw);
2290        }
2291
2292        return printed + fprintf(fp, "\n");
2293}
2294
2295size_t disasm__fprintf(struct list_head *head, FILE *fp)
2296{
2297        struct disasm_line *pos;
2298        size_t printed = 0;
2299
2300        list_for_each_entry(pos, head, al.node)
2301                printed += disasm_line__fprintf(pos, fp);
2302
2303        return printed;
2304}
2305
2306bool disasm_line__is_valid_local_jump(struct disasm_line *dl, struct symbol *sym)
2307{
2308        if (!dl || !dl->ins.ops || !ins__is_jump(&dl->ins) ||
2309            !disasm_line__has_local_offset(dl) || dl->ops.target.offset < 0 ||
2310            dl->ops.target.offset >= (s64)symbol__size(sym))
2311                return false;
2312
2313        return true;
2314}
2315
2316void annotation__mark_jump_targets(struct annotation *notes, struct symbol *sym)
2317{
2318        u64 offset, size = symbol__size(sym);
2319
2320        /* PLT symbols contain external offsets */
2321        if (strstr(sym->name, "@plt"))
2322                return;
2323
2324        for (offset = 0; offset < size; ++offset) {
2325                struct annotation_line *al = notes->offsets[offset];
2326                struct disasm_line *dl;
2327
2328                dl = disasm_line(al);
2329
2330                if (!disasm_line__is_valid_local_jump(dl, sym))
2331                        continue;
2332
2333                al = notes->offsets[dl->ops.target.offset];
2334
2335                /*
2336                 * FIXME: Oops, no jump target? Buggy disassembler? Or do we
2337                 * have to adjust to the previous offset?
2338                 */
2339                if (al == NULL)
2340                        continue;
2341
2342                if (++al->jump_sources > notes->max_jump_sources)
2343                        notes->max_jump_sources = al->jump_sources;
2344
2345                ++notes->nr_jumps;
2346        }
2347}
2348
2349void annotation__set_offsets(struct annotation *notes, s64 size)
2350{
2351        struct annotation_line *al;
2352
2353        notes->max_line_len = 0;
2354
2355        list_for_each_entry(al, &notes->src->source, node) {
2356                size_t line_len = strlen(al->line);
2357
2358                if (notes->max_line_len < line_len)
2359                        notes->max_line_len = line_len;
2360                al->idx = notes->nr_entries++;
2361                if (al->offset != -1) {
2362                        al->idx_asm = notes->nr_asm_entries++;
2363                        /*
2364                         * FIXME: short term bandaid to cope with assembly
2365                         * routines that comes with labels in the same column
2366                         * as the address in objdump, sigh.
2367                         *
2368                         * E.g. copy_user_generic_unrolled
2369                         */
2370                        if (al->offset < size)
2371                                notes->offsets[al->offset] = al;
2372                } else
2373                        al->idx_asm = -1;
2374        }
2375}
2376
2377static inline int width_jumps(int n)
2378{
2379        if (n >= 100)
2380                return 5;
2381        if (n / 10)
2382                return 2;
2383        return 1;
2384}
2385
2386void annotation__init_column_widths(struct annotation *notes, struct symbol *sym)
2387{
2388        notes->widths.addr = notes->widths.target =
2389                notes->widths.min_addr = hex_width(symbol__size(sym));
2390        notes->widths.max_addr = hex_width(sym->end);
2391        notes->widths.jumps = width_jumps(notes->max_jump_sources);
2392}
2393
2394void annotation__update_column_widths(struct annotation *notes)
2395{
2396        if (notes->options->use_offset)
2397                notes->widths.target = notes->widths.min_addr;
2398        else
2399                notes->widths.target = notes->widths.max_addr;
2400
2401        notes->widths.addr = notes->widths.target;
2402
2403        if (notes->options->show_nr_jumps)
2404                notes->widths.addr += notes->widths.jumps + 1;
2405}
2406
2407static void annotation__calc_lines(struct annotation *notes, struct map *map,
2408                                   struct rb_root *root,
2409                                   struct annotation_options *opts)
2410{
2411        struct annotation_line *al;
2412        struct rb_root tmp_root = RB_ROOT;
2413
2414        list_for_each_entry(al, &notes->src->source, node) {
2415                double percent_max = 0.0;
2416                int i;
2417
2418                for (i = 0; i < al->data_nr; i++) {
2419                        double percent;
2420
2421                        percent = annotation_data__percent(&al->data[i],
2422                                                           opts->percent_type);
2423
2424                        if (percent > percent_max)
2425                                percent_max = percent;
2426                }
2427
2428                if (percent_max <= 0.5)
2429                        continue;
2430
2431                al->path = get_srcline(map->dso, notes->start + al->offset, NULL,
2432                                       false, true, notes->start + al->offset);
2433                insert_source_line(&tmp_root, al, opts);
2434        }
2435
2436        resort_source_line(root, &tmp_root);
2437}
2438
2439static void symbol__calc_lines(struct symbol *sym, struct map *map,
2440                               struct rb_root *root,
2441                               struct annotation_options *opts)
2442{
2443        struct annotation *notes = symbol__annotation(sym);
2444
2445        annotation__calc_lines(notes, map, root, opts);
2446}
2447
2448int symbol__tty_annotate2(struct symbol *sym, struct map *map,
2449                          struct perf_evsel *evsel,
2450                          struct annotation_options *opts)
2451{
2452        struct dso *dso = map->dso;
2453        struct rb_root source_line = RB_ROOT;
2454        struct hists *hists = evsel__hists(evsel);
2455        char buf[1024];
2456
2457        if (symbol__annotate2(sym, map, evsel, opts, NULL) < 0)
2458                return -1;
2459
2460        if (opts->print_lines) {
2461                srcline_full_filename = opts->full_path;
2462                symbol__calc_lines(sym, map, &source_line, opts);
2463                print_summary(&source_line, dso->long_name);
2464        }
2465
2466        hists__scnprintf_title(hists, buf, sizeof(buf));
2467        fprintf(stdout, "%s, [percent: %s]\n%s() %s\n",
2468                buf, percent_type_str(opts->percent_type), sym->name, dso->long_name);
2469        symbol__annotate_fprintf2(sym, stdout, opts);
2470
2471        annotated_source__purge(symbol__annotation(sym)->src);
2472
2473        return 0;
2474}
2475
2476int symbol__tty_annotate(struct symbol *sym, struct map *map,
2477                         struct perf_evsel *evsel,
2478                         struct annotation_options *opts)
2479{
2480        struct dso *dso = map->dso;
2481        struct rb_root source_line = RB_ROOT;
2482
2483        if (symbol__annotate(sym, map, evsel, 0, opts, NULL) < 0)
2484                return -1;
2485
2486        symbol__calc_percent(sym, evsel);
2487
2488        if (opts->print_lines) {
2489                srcline_full_filename = opts->full_path;
2490                symbol__calc_lines(sym, map, &source_line, opts);
2491                print_summary(&source_line, dso->long_name);
2492        }
2493
2494        symbol__annotate_printf(sym, map, evsel, opts);
2495
2496        annotated_source__purge(symbol__annotation(sym)->src);
2497
2498        return 0;
2499}
2500
2501bool ui__has_annotation(void)
2502{
2503        return use_browser == 1 && perf_hpp_list.sym;
2504}
2505
2506
2507static double annotation_line__max_percent(struct annotation_line *al,
2508                                           struct annotation *notes,
2509                                           unsigned int percent_type)
2510{
2511        double percent_max = 0.0;
2512        int i;
2513
2514        for (i = 0; i < notes->nr_events; i++) {
2515                double percent;
2516
2517                percent = annotation_data__percent(&al->data[i],
2518                                                   percent_type);
2519
2520                if (percent > percent_max)
2521                        percent_max = percent;
2522        }
2523
2524        return percent_max;
2525}
2526
2527static void disasm_line__write(struct disasm_line *dl, struct annotation *notes,
2528                               void *obj, char *bf, size_t size,
2529                               void (*obj__printf)(void *obj, const char *fmt, ...),
2530                               void (*obj__write_graph)(void *obj, int graph))
2531{
2532        if (dl->ins.ops && dl->ins.ops->scnprintf) {
2533                if (ins__is_jump(&dl->ins)) {
2534                        bool fwd;
2535
2536                        if (dl->ops.target.outside)
2537                                goto call_like;
2538                        fwd = dl->ops.target.offset > dl->al.offset;
2539                        obj__write_graph(obj, fwd ? DARROW_CHAR : UARROW_CHAR);
2540                        obj__printf(obj, " ");
2541                } else if (ins__is_call(&dl->ins)) {
2542call_like:
2543                        obj__write_graph(obj, RARROW_CHAR);
2544                        obj__printf(obj, " ");
2545                } else if (ins__is_ret(&dl->ins)) {
2546                        obj__write_graph(obj, LARROW_CHAR);
2547                        obj__printf(obj, " ");
2548                } else {
2549                        obj__printf(obj, "  ");
2550                }
2551        } else {
2552                obj__printf(obj, "  ");
2553        }
2554
2555        disasm_line__scnprintf(dl, bf, size, !notes->options->use_offset);
2556}
2557
2558static void __annotation_line__write(struct annotation_line *al, struct annotation *notes,
2559                                     bool first_line, bool current_entry, bool change_color, int width,
2560                                     void *obj, unsigned int percent_type,
2561                                     int  (*obj__set_color)(void *obj, int color),
2562                                     void (*obj__set_percent_color)(void *obj, double percent, bool current),
2563                                     int  (*obj__set_jumps_percent_color)(void *obj, int nr, bool current),
2564                                     void (*obj__printf)(void *obj, const char *fmt, ...),
2565                                     void (*obj__write_graph)(void *obj, int graph))
2566
2567{
2568        double percent_max = annotation_line__max_percent(al, notes, percent_type);
2569        int pcnt_width = annotation__pcnt_width(notes),
2570            cycles_width = annotation__cycles_width(notes);
2571        bool show_title = false;
2572        char bf[256];
2573        int printed;
2574
2575        if (first_line && (al->offset == -1 || percent_max == 0.0)) {
2576                if (notes->have_cycles) {
2577                        if (al->ipc == 0.0 && al->cycles == 0)
2578                                show_title = true;
2579                } else
2580                        show_title = true;
2581        }
2582
2583        if (al->offset != -1 && percent_max != 0.0) {
2584                int i;
2585
2586                for (i = 0; i < notes->nr_events; i++) {
2587                        double percent;
2588
2589                        percent = annotation_data__percent(&al->data[i], percent_type);
2590
2591                        obj__set_percent_color(obj, percent, current_entry);
2592                        if (notes->options->show_total_period) {
2593                                obj__printf(obj, "%11" PRIu64 " ", al->data[i].he.period);
2594                        } else if (notes->options->show_nr_samples) {
2595                                obj__printf(obj, "%6" PRIu64 " ",
2596                                                   al->data[i].he.nr_samples);
2597                        } else {
2598                                obj__printf(obj, "%6.2f ", percent);
2599                        }
2600                }
2601        } else {
2602                obj__set_percent_color(obj, 0, current_entry);
2603
2604                if (!show_title)
2605                        obj__printf(obj, "%-*s", pcnt_width, " ");
2606                else {
2607                        obj__printf(obj, "%-*s", pcnt_width,
2608                                           notes->options->show_total_period ? "Period" :
2609                                           notes->options->show_nr_samples ? "Samples" : "Percent");
2610                }
2611        }
2612
2613        if (notes->have_cycles) {
2614                if (al->ipc)
2615                        obj__printf(obj, "%*.2f ", ANNOTATION__IPC_WIDTH - 1, al->ipc);
2616                else if (!show_title)
2617                        obj__printf(obj, "%*s", ANNOTATION__IPC_WIDTH, " ");
2618                else
2619                        obj__printf(obj, "%*s ", ANNOTATION__IPC_WIDTH - 1, "IPC");
2620
2621                if (!notes->options->show_minmax_cycle) {
2622                        if (al->cycles)
2623                                obj__printf(obj, "%*" PRIu64 " ",
2624                                           ANNOTATION__CYCLES_WIDTH - 1, al->cycles);
2625                        else if (!show_title)
2626                                obj__printf(obj, "%*s",
2627                                            ANNOTATION__CYCLES_WIDTH, " ");
2628                        else
2629                                obj__printf(obj, "%*s ",
2630                                            ANNOTATION__CYCLES_WIDTH - 1,
2631                                            "Cycle");
2632                } else {
2633                        if (al->cycles) {
2634                                char str[32];
2635
2636                                scnprintf(str, sizeof(str),
2637                                        "%" PRIu64 "(%" PRIu64 "/%" PRIu64 ")",
2638                                        al->cycles, al->cycles_min,
2639                                        al->cycles_max);
2640
2641                                obj__printf(obj, "%*s ",
2642                                            ANNOTATION__MINMAX_CYCLES_WIDTH - 1,
2643                                            str);
2644                        } else if (!show_title)
2645                                obj__printf(obj, "%*s",
2646                                            ANNOTATION__MINMAX_CYCLES_WIDTH,
2647                                            " ");
2648                        else
2649                                obj__printf(obj, "%*s ",
2650                                            ANNOTATION__MINMAX_CYCLES_WIDTH - 1,
2651                                            "Cycle(min/max)");
2652                }
2653        }
2654
2655        obj__printf(obj, " ");
2656
2657        if (!*al->line)
2658                obj__printf(obj, "%-*s", width - pcnt_width - cycles_width, " ");
2659        else if (al->offset == -1) {
2660                if (al->line_nr && notes->options->show_linenr)
2661                        printed = scnprintf(bf, sizeof(bf), "%-*d ", notes->widths.addr + 1, al->line_nr);
2662                else
2663                        printed = scnprintf(bf, sizeof(bf), "%-*s  ", notes->widths.addr, " ");
2664                obj__printf(obj, bf);
2665                obj__printf(obj, "%-*s", width - printed - pcnt_width - cycles_width + 1, al->line);
2666        } else {
2667                u64 addr = al->offset;
2668                int color = -1;
2669
2670                if (!notes->options->use_offset)
2671                        addr += notes->start;
2672
2673                if (!notes->options->use_offset) {
2674                        printed = scnprintf(bf, sizeof(bf), "%" PRIx64 ": ", addr);
2675                } else {
2676                        if (al->jump_sources &&
2677                            notes->options->offset_level >= ANNOTATION__OFFSET_JUMP_TARGETS) {
2678                                if (notes->options->show_nr_jumps) {
2679                                        int prev;
2680                                        printed = scnprintf(bf, sizeof(bf), "%*d ",
2681                                                            notes->widths.jumps,
2682                                                            al->jump_sources);
2683                                        prev = obj__set_jumps_percent_color(obj, al->jump_sources,
2684                                                                            current_entry);
2685                                        obj__printf(obj, bf);
2686                                        obj__set_color(obj, prev);
2687                                }
2688print_addr:
2689                                printed = scnprintf(bf, sizeof(bf), "%*" PRIx64 ": ",
2690                                                    notes->widths.target, addr);
2691                        } else if (ins__is_call(&disasm_line(al)->ins) &&
2692                                   notes->options->offset_level >= ANNOTATION__OFFSET_CALL) {
2693                                goto print_addr;
2694                        } else if (notes->options->offset_level == ANNOTATION__MAX_OFFSET_LEVEL) {
2695                                goto print_addr;
2696                        } else {
2697                                printed = scnprintf(bf, sizeof(bf), "%-*s  ",
2698                                                    notes->widths.addr, " ");
2699                        }
2700                }
2701
2702                if (change_color)
2703                        color = obj__set_color(obj, HE_COLORSET_ADDR);
2704                obj__printf(obj, bf);
2705                if (change_color)
2706                        obj__set_color(obj, color);
2707
2708                disasm_line__write(disasm_line(al), notes, obj, bf, sizeof(bf), obj__printf, obj__write_graph);
2709
2710                obj__printf(obj, "%-*s", width - pcnt_width - cycles_width - 3 - printed, bf);
2711        }
2712
2713}
2714
2715void annotation_line__write(struct annotation_line *al, struct annotation *notes,
2716                            struct annotation_write_ops *wops,
2717                            struct annotation_options *opts)
2718{
2719        __annotation_line__write(al, notes, wops->first_line, wops->current_entry,
2720                                 wops->change_color, wops->width, wops->obj,
2721                                 opts->percent_type,
2722                                 wops->set_color, wops->set_percent_color,
2723                                 wops->set_jumps_percent_color, wops->printf,
2724                                 wops->write_graph);
2725}
2726
2727int symbol__annotate2(struct symbol *sym, struct map *map, struct perf_evsel *evsel,
2728                      struct annotation_options *options, struct arch **parch)
2729{
2730        struct annotation *notes = symbol__annotation(sym);
2731        size_t size = symbol__size(sym);
2732        int nr_pcnt = 1, err;
2733
2734        notes->offsets = zalloc(size * sizeof(struct annotation_line *));
2735        if (notes->offsets == NULL)
2736                return -1;
2737
2738        if (perf_evsel__is_group_event(evsel))
2739                nr_pcnt = evsel->nr_members;
2740
2741        err = symbol__annotate(sym, map, evsel, 0, options, parch);
2742        if (err)
2743                goto out_free_offsets;
2744
2745        notes->options = options;
2746
2747        symbol__calc_percent(sym, evsel);
2748
2749        notes->start = map__rip_2objdump(map, sym->start);
2750
2751        annotation__set_offsets(notes, size);
2752        annotation__mark_jump_targets(notes, sym);
2753        annotation__compute_ipc(notes, size);
2754        annotation__init_column_widths(notes, sym);
2755        notes->nr_events = nr_pcnt;
2756
2757        annotation__update_column_widths(notes);
2758
2759        return 0;
2760
2761out_free_offsets:
2762        zfree(&notes->offsets);
2763        return -1;
2764}
2765
2766#define ANNOTATION__CFG(n) \
2767        { .name = #n, .value = &annotation__default_options.n, }
2768
2769/*
2770 * Keep the entries sorted, they are bsearch'ed
2771 */
2772static struct annotation_config {
2773        const char *name;
2774        void *value;
2775} annotation__configs[] = {
2776        ANNOTATION__CFG(hide_src_code),
2777        ANNOTATION__CFG(jump_arrows),
2778        ANNOTATION__CFG(offset_level),
2779        ANNOTATION__CFG(show_linenr),
2780        ANNOTATION__CFG(show_nr_jumps),
2781        ANNOTATION__CFG(show_nr_samples),
2782        ANNOTATION__CFG(show_total_period),
2783        ANNOTATION__CFG(use_offset),
2784};
2785
2786#undef ANNOTATION__CFG
2787
2788static int annotation_config__cmp(const void *name, const void *cfgp)
2789{
2790        const struct annotation_config *cfg = cfgp;
2791
2792        return strcmp(name, cfg->name);
2793}
2794
2795static int annotation__config(const char *var, const char *value,
2796                            void *data __maybe_unused)
2797{
2798        struct annotation_config *cfg;
2799        const char *name;
2800
2801        if (!strstarts(var, "annotate."))
2802                return 0;
2803
2804        name = var + 9;
2805        cfg = bsearch(name, annotation__configs, ARRAY_SIZE(annotation__configs),
2806                      sizeof(struct annotation_config), annotation_config__cmp);
2807
2808        if (cfg == NULL)
2809                pr_debug("%s variable unknown, ignoring...", var);
2810        else if (strcmp(var, "annotate.offset_level") == 0) {
2811                perf_config_int(cfg->value, name, value);
2812
2813                if (*(int *)cfg->value > ANNOTATION__MAX_OFFSET_LEVEL)
2814                        *(int *)cfg->value = ANNOTATION__MAX_OFFSET_LEVEL;
2815                else if (*(int *)cfg->value < ANNOTATION__MIN_OFFSET_LEVEL)
2816                        *(int *)cfg->value = ANNOTATION__MIN_OFFSET_LEVEL;
2817        } else {
2818                *(bool *)cfg->value = perf_config_bool(name, value);
2819        }
2820        return 0;
2821}
2822
2823void annotation_config__init(void)
2824{
2825        perf_config(annotation__config, NULL);
2826
2827        annotation__default_options.show_total_period = symbol_conf.show_total_period;
2828        annotation__default_options.show_nr_samples   = symbol_conf.show_nr_samples;
2829}
2830
2831static unsigned int parse_percent_type(char *str1, char *str2)
2832{
2833        unsigned int type = (unsigned int) -1;
2834
2835        if (!strcmp("period", str1)) {
2836                if (!strcmp("local", str2))
2837                        type = PERCENT_PERIOD_LOCAL;
2838                else if (!strcmp("global", str2))
2839                        type = PERCENT_PERIOD_GLOBAL;
2840        }
2841
2842        if (!strcmp("hits", str1)) {
2843                if (!strcmp("local", str2))
2844                        type = PERCENT_HITS_LOCAL;
2845                else if (!strcmp("global", str2))
2846                        type = PERCENT_HITS_GLOBAL;
2847        }
2848
2849        return type;
2850}
2851
2852int annotate_parse_percent_type(const struct option *opt, const char *_str,
2853                                int unset __maybe_unused)
2854{
2855        struct annotation_options *opts = opt->value;
2856        unsigned int type;
2857        char *str1, *str2;
2858        int err = -1;
2859
2860        str1 = strdup(_str);
2861        if (!str1)
2862                return -ENOMEM;
2863
2864        str2 = strchr(str1, '-');
2865        if (!str2)
2866                goto out;
2867
2868        *str2++ = 0;
2869
2870        type = parse_percent_type(str1, str2);
2871        if (type == (unsigned int) -1)
2872                type = parse_percent_type(str2, str1);
2873        if (type != (unsigned int) -1) {
2874                opts->percent_type = type;
2875                err = 0;
2876        }
2877
2878out:
2879        free(str1);
2880        return err;
2881}
2882