linux/tools/perf/util/trace-event-parse.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2009, Steven Rostedt <srostedt@redhat.com>
   3 *
   4 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation; version 2 of the License (not later!)
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  14 *
  15 * You should have received a copy of the GNU General Public License
  16 * along with this program; if not, write to the Free Software
  17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18 *
  19 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  20 *
  21 *  The parts for function graph printing was taken and modified from the
  22 *  Linux Kernel that were written by Frederic Weisbecker.
  23 */
  24#define _GNU_SOURCE
  25#include <stdio.h>
  26#include <stdlib.h>
  27#include <string.h>
  28#include <ctype.h>
  29#include <errno.h>
  30
  31#undef _GNU_SOURCE
  32#include "../perf.h"
  33#include "util.h"
  34#include "trace-event.h"
  35
  36int header_page_ts_offset;
  37int header_page_ts_size;
  38int header_page_size_offset;
  39int header_page_size_size;
  40int header_page_data_offset;
  41int header_page_data_size;
  42
  43static char *input_buf;
  44static unsigned long long input_buf_ptr;
  45static unsigned long long input_buf_siz;
  46
  47static int cpus;
  48static int long_size;
  49
  50static void init_input_buf(char *buf, unsigned long long size)
  51{
  52        input_buf = buf;
  53        input_buf_siz = size;
  54        input_buf_ptr = 0;
  55}
  56
  57struct cmdline {
  58        char *comm;
  59        int pid;
  60};
  61
  62static struct cmdline *cmdlines;
  63static int cmdline_count;
  64
  65static int cmdline_cmp(const void *a, const void *b)
  66{
  67        const struct cmdline *ca = a;
  68        const struct cmdline *cb = b;
  69
  70        if (ca->pid < cb->pid)
  71                return -1;
  72        if (ca->pid > cb->pid)
  73                return 1;
  74
  75        return 0;
  76}
  77
  78void parse_cmdlines(char *file, int size __unused)
  79{
  80        struct cmdline_list {
  81                struct cmdline_list     *next;
  82                char                    *comm;
  83                int                     pid;
  84        } *list = NULL, *item;
  85        char *line;
  86        char *next = NULL;
  87        int i;
  88
  89        line = strtok_r(file, "\n", &next);
  90        while (line) {
  91                item = malloc_or_die(sizeof(*item));
  92                sscanf(line, "%d %as", &item->pid,
  93                       (float *)(void *)&item->comm); /* workaround gcc warning */
  94                item->next = list;
  95                list = item;
  96                line = strtok_r(NULL, "\n", &next);
  97                cmdline_count++;
  98        }
  99
 100        cmdlines = malloc_or_die(sizeof(*cmdlines) * cmdline_count);
 101
 102        i = 0;
 103        while (list) {
 104                cmdlines[i].pid = list->pid;
 105                cmdlines[i].comm = list->comm;
 106                i++;
 107                item = list;
 108                list = list->next;
 109                free(item);
 110        }
 111
 112        qsort(cmdlines, cmdline_count, sizeof(*cmdlines), cmdline_cmp);
 113}
 114
 115static struct func_map {
 116        unsigned long long              addr;
 117        char                            *func;
 118        char                            *mod;
 119} *func_list;
 120static unsigned int func_count;
 121
 122static int func_cmp(const void *a, const void *b)
 123{
 124        const struct func_map *fa = a;
 125        const struct func_map *fb = b;
 126
 127        if (fa->addr < fb->addr)
 128                return -1;
 129        if (fa->addr > fb->addr)
 130                return 1;
 131
 132        return 0;
 133}
 134
 135void parse_proc_kallsyms(char *file, unsigned int size __unused)
 136{
 137        struct func_list {
 138                struct func_list        *next;
 139                unsigned long long      addr;
 140                char                    *func;
 141                char                    *mod;
 142        } *list = NULL, *item;
 143        char *line;
 144        char *next = NULL;
 145        char *addr_str;
 146        char ch;
 147        int ret;
 148        int i;
 149
 150        line = strtok_r(file, "\n", &next);
 151        while (line) {
 152                item = malloc_or_die(sizeof(*item));
 153                item->mod = NULL;
 154                ret = sscanf(line, "%as %c %as\t[%as",
 155                             (float *)(void *)&addr_str, /* workaround gcc warning */
 156                             &ch,
 157                             (float *)(void *)&item->func,
 158                             (float *)(void *)&item->mod);
 159                item->addr = strtoull(addr_str, NULL, 16);
 160                free(addr_str);
 161
 162                /* truncate the extra ']' */
 163                if (item->mod)
 164                        item->mod[strlen(item->mod) - 1] = 0;
 165
 166
 167                item->next = list;
 168                list = item;
 169                line = strtok_r(NULL, "\n", &next);
 170                func_count++;
 171        }
 172
 173        func_list = malloc_or_die(sizeof(*func_list) * func_count + 1);
 174
 175        i = 0;
 176        while (list) {
 177                func_list[i].func = list->func;
 178                func_list[i].addr = list->addr;
 179                func_list[i].mod = list->mod;
 180                i++;
 181                item = list;
 182                list = list->next;
 183                free(item);
 184        }
 185
 186        qsort(func_list, func_count, sizeof(*func_list), func_cmp);
 187
 188        /*
 189         * Add a special record at the end.
 190         */
 191        func_list[func_count].func = NULL;
 192        func_list[func_count].addr = 0;
 193        func_list[func_count].mod = NULL;
 194}
 195
 196/*
 197 * We are searching for a record in between, not an exact
 198 * match.
 199 */
 200static int func_bcmp(const void *a, const void *b)
 201{
 202        const struct func_map *fa = a;
 203        const struct func_map *fb = b;
 204
 205        if ((fa->addr == fb->addr) ||
 206
 207            (fa->addr > fb->addr &&
 208             fa->addr < (fb+1)->addr))
 209                return 0;
 210
 211        if (fa->addr < fb->addr)
 212                return -1;
 213
 214        return 1;
 215}
 216
 217static struct func_map *find_func(unsigned long long addr)
 218{
 219        struct func_map *func;
 220        struct func_map key;
 221
 222        key.addr = addr;
 223
 224        func = bsearch(&key, func_list, func_count, sizeof(*func_list),
 225                       func_bcmp);
 226
 227        return func;
 228}
 229
 230void print_funcs(void)
 231{
 232        int i;
 233
 234        for (i = 0; i < (int)func_count; i++) {
 235                printf("%016llx %s",
 236                       func_list[i].addr,
 237                       func_list[i].func);
 238                if (func_list[i].mod)
 239                        printf(" [%s]\n", func_list[i].mod);
 240                else
 241                        printf("\n");
 242        }
 243}
 244
 245static struct printk_map {
 246        unsigned long long              addr;
 247        char                            *printk;
 248} *printk_list;
 249static unsigned int printk_count;
 250
 251static int printk_cmp(const void *a, const void *b)
 252{
 253        const struct func_map *fa = a;
 254        const struct func_map *fb = b;
 255
 256        if (fa->addr < fb->addr)
 257                return -1;
 258        if (fa->addr > fb->addr)
 259                return 1;
 260
 261        return 0;
 262}
 263
 264static struct printk_map *find_printk(unsigned long long addr)
 265{
 266        struct printk_map *printk;
 267        struct printk_map key;
 268
 269        key.addr = addr;
 270
 271        printk = bsearch(&key, printk_list, printk_count, sizeof(*printk_list),
 272                         printk_cmp);
 273
 274        return printk;
 275}
 276
 277void parse_ftrace_printk(char *file, unsigned int size __unused)
 278{
 279        struct printk_list {
 280                struct printk_list      *next;
 281                unsigned long long      addr;
 282                char                    *printk;
 283        } *list = NULL, *item;
 284        char *line;
 285        char *next = NULL;
 286        char *addr_str;
 287        int ret;
 288        int i;
 289
 290        line = strtok_r(file, "\n", &next);
 291        while (line) {
 292                item = malloc_or_die(sizeof(*item));
 293                ret = sscanf(line, "%as : %as",
 294                             (float *)(void *)&addr_str, /* workaround gcc warning */
 295                             (float *)(void *)&item->printk);
 296                item->addr = strtoull(addr_str, NULL, 16);
 297                free(addr_str);
 298
 299                item->next = list;
 300                list = item;
 301                line = strtok_r(NULL, "\n", &next);
 302                printk_count++;
 303        }
 304
 305        printk_list = malloc_or_die(sizeof(*printk_list) * printk_count + 1);
 306
 307        i = 0;
 308        while (list) {
 309                printk_list[i].printk = list->printk;
 310                printk_list[i].addr = list->addr;
 311                i++;
 312                item = list;
 313                list = list->next;
 314                free(item);
 315        }
 316
 317        qsort(printk_list, printk_count, sizeof(*printk_list), printk_cmp);
 318}
 319
 320void print_printk(void)
 321{
 322        int i;
 323
 324        for (i = 0; i < (int)printk_count; i++) {
 325                printf("%016llx %s\n",
 326                       printk_list[i].addr,
 327                       printk_list[i].printk);
 328        }
 329}
 330
 331static struct event *alloc_event(void)
 332{
 333        struct event *event;
 334
 335        event = malloc_or_die(sizeof(*event));
 336        memset(event, 0, sizeof(*event));
 337
 338        return event;
 339}
 340
 341enum event_type {
 342        EVENT_ERROR,
 343        EVENT_NONE,
 344        EVENT_SPACE,
 345        EVENT_NEWLINE,
 346        EVENT_OP,
 347        EVENT_DELIM,
 348        EVENT_ITEM,
 349        EVENT_DQUOTE,
 350        EVENT_SQUOTE,
 351};
 352
 353static struct event *event_list;
 354
 355static void add_event(struct event *event)
 356{
 357        event->next = event_list;
 358        event_list = event;
 359}
 360
 361static int event_item_type(enum event_type type)
 362{
 363        switch (type) {
 364        case EVENT_ITEM ... EVENT_SQUOTE:
 365                return 1;
 366        case EVENT_ERROR ... EVENT_DELIM:
 367        default:
 368                return 0;
 369        }
 370}
 371
 372static void free_arg(struct print_arg *arg)
 373{
 374        if (!arg)
 375                return;
 376
 377        switch (arg->type) {
 378        case PRINT_ATOM:
 379                if (arg->atom.atom)
 380                        free(arg->atom.atom);
 381                break;
 382        case PRINT_NULL:
 383        case PRINT_FIELD ... PRINT_OP:
 384        default:
 385                /* todo */
 386                break;
 387        }
 388
 389        free(arg);
 390}
 391
 392static enum event_type get_type(int ch)
 393{
 394        if (ch == '\n')
 395                return EVENT_NEWLINE;
 396        if (isspace(ch))
 397                return EVENT_SPACE;
 398        if (isalnum(ch) || ch == '_')
 399                return EVENT_ITEM;
 400        if (ch == '\'')
 401                return EVENT_SQUOTE;
 402        if (ch == '"')
 403                return EVENT_DQUOTE;
 404        if (!isprint(ch))
 405                return EVENT_NONE;
 406        if (ch == '(' || ch == ')' || ch == ',')
 407                return EVENT_DELIM;
 408
 409        return EVENT_OP;
 410}
 411
 412static int __read_char(void)
 413{
 414        if (input_buf_ptr >= input_buf_siz)
 415                return -1;
 416
 417        return input_buf[input_buf_ptr++];
 418}
 419
 420static int __peek_char(void)
 421{
 422        if (input_buf_ptr >= input_buf_siz)
 423                return -1;
 424
 425        return input_buf[input_buf_ptr];
 426}
 427
 428static enum event_type __read_token(char **tok)
 429{
 430        char buf[BUFSIZ];
 431        int ch, last_ch, quote_ch, next_ch;
 432        int i = 0;
 433        int tok_size = 0;
 434        enum event_type type;
 435
 436        *tok = NULL;
 437
 438
 439        ch = __read_char();
 440        if (ch < 0)
 441                return EVENT_NONE;
 442
 443        type = get_type(ch);
 444        if (type == EVENT_NONE)
 445                return type;
 446
 447        buf[i++] = ch;
 448
 449        switch (type) {
 450        case EVENT_NEWLINE:
 451        case EVENT_DELIM:
 452                *tok = malloc_or_die(2);
 453                (*tok)[0] = ch;
 454                (*tok)[1] = 0;
 455                return type;
 456
 457        case EVENT_OP:
 458                switch (ch) {
 459                case '-':
 460                        next_ch = __peek_char();
 461                        if (next_ch == '>') {
 462                                buf[i++] = __read_char();
 463                                break;
 464                        }
 465                        /* fall through */
 466                case '+':
 467                case '|':
 468                case '&':
 469                case '>':
 470                case '<':
 471                        last_ch = ch;
 472                        ch = __peek_char();
 473                        if (ch != last_ch)
 474                                goto test_equal;
 475                        buf[i++] = __read_char();
 476                        switch (last_ch) {
 477                        case '>':
 478                        case '<':
 479                                goto test_equal;
 480                        default:
 481                                break;
 482                        }
 483                        break;
 484                case '!':
 485                case '=':
 486                        goto test_equal;
 487                default: /* what should we do instead? */
 488                        break;
 489                }
 490                buf[i] = 0;
 491                *tok = strdup(buf);
 492                return type;
 493
 494 test_equal:
 495                ch = __peek_char();
 496                if (ch == '=')
 497                        buf[i++] = __read_char();
 498                break;
 499
 500        case EVENT_DQUOTE:
 501        case EVENT_SQUOTE:
 502                /* don't keep quotes */
 503                i--;
 504                quote_ch = ch;
 505                last_ch = 0;
 506                do {
 507                        if (i == (BUFSIZ - 1)) {
 508                                buf[i] = 0;
 509                                if (*tok) {
 510                                        *tok = realloc(*tok, tok_size + BUFSIZ);
 511                                        if (!*tok)
 512                                                return EVENT_NONE;
 513                                        strcat(*tok, buf);
 514                                } else
 515                                        *tok = strdup(buf);
 516
 517                                if (!*tok)
 518                                        return EVENT_NONE;
 519                                tok_size += BUFSIZ;
 520                                i = 0;
 521                        }
 522                        last_ch = ch;
 523                        ch = __read_char();
 524                        buf[i++] = ch;
 525                } while (ch != quote_ch && last_ch != '\\');
 526                /* remove the last quote */
 527                i--;
 528                goto out;
 529
 530        case EVENT_ERROR ... EVENT_SPACE:
 531        case EVENT_ITEM:
 532        default:
 533                break;
 534        }
 535
 536        while (get_type(__peek_char()) == type) {
 537                if (i == (BUFSIZ - 1)) {
 538                        buf[i] = 0;
 539                        if (*tok) {
 540                                *tok = realloc(*tok, tok_size + BUFSIZ);
 541                                if (!*tok)
 542                                        return EVENT_NONE;
 543                                strcat(*tok, buf);
 544                        } else
 545                                *tok = strdup(buf);
 546
 547                        if (!*tok)
 548                                return EVENT_NONE;
 549                        tok_size += BUFSIZ;
 550                        i = 0;
 551                }
 552                ch = __read_char();
 553                buf[i++] = ch;
 554        }
 555
 556 out:
 557        buf[i] = 0;
 558        if (*tok) {
 559                *tok = realloc(*tok, tok_size + i);
 560                if (!*tok)
 561                        return EVENT_NONE;
 562                strcat(*tok, buf);
 563        } else
 564                *tok = strdup(buf);
 565        if (!*tok)
 566                return EVENT_NONE;
 567
 568        return type;
 569}
 570
 571static void free_token(char *tok)
 572{
 573        if (tok)
 574                free(tok);
 575}
 576
 577static enum event_type read_token(char **tok)
 578{
 579        enum event_type type;
 580
 581        for (;;) {
 582                type = __read_token(tok);
 583                if (type != EVENT_SPACE)
 584                        return type;
 585
 586                free_token(*tok);
 587        }
 588
 589        /* not reached */
 590        return EVENT_NONE;
 591}
 592
 593/* no newline */
 594static enum event_type read_token_item(char **tok)
 595{
 596        enum event_type type;
 597
 598        for (;;) {
 599                type = __read_token(tok);
 600                if (type != EVENT_SPACE && type != EVENT_NEWLINE)
 601                        return type;
 602
 603                free_token(*tok);
 604        }
 605
 606        /* not reached */
 607        return EVENT_NONE;
 608}
 609
 610static int test_type(enum event_type type, enum event_type expect)
 611{
 612        if (type != expect) {
 613                die("Error: expected type %d but read %d",
 614                    expect, type);
 615                return -1;
 616        }
 617        return 0;
 618}
 619
 620static int test_type_token(enum event_type type, char *token,
 621                    enum event_type expect, const char *expect_tok)
 622{
 623        if (type != expect) {
 624                die("Error: expected type %d but read %d",
 625                    expect, type);
 626                return -1;
 627        }
 628
 629        if (strcmp(token, expect_tok) != 0) {
 630                die("Error: expected '%s' but read '%s'",
 631                    expect_tok, token);
 632                return -1;
 633        }
 634        return 0;
 635}
 636
 637static int __read_expect_type(enum event_type expect, char **tok, int newline_ok)
 638{
 639        enum event_type type;
 640
 641        if (newline_ok)
 642                type = read_token(tok);
 643        else
 644                type = read_token_item(tok);
 645        return test_type(type, expect);
 646}
 647
 648static int read_expect_type(enum event_type expect, char **tok)
 649{
 650        return __read_expect_type(expect, tok, 1);
 651}
 652
 653static int __read_expected(enum event_type expect, const char *str, int newline_ok)
 654{
 655        enum event_type type;
 656        char *token;
 657        int ret;
 658
 659        if (newline_ok)
 660                type = read_token(&token);
 661        else
 662                type = read_token_item(&token);
 663
 664        ret = test_type_token(type, token, expect, str);
 665
 666        free_token(token);
 667
 668        return 0;
 669}
 670
 671static int read_expected(enum event_type expect, const char *str)
 672{
 673        return __read_expected(expect, str, 1);
 674}
 675
 676static int read_expected_item(enum event_type expect, const char *str)
 677{
 678        return __read_expected(expect, str, 0);
 679}
 680
 681static char *event_read_name(void)
 682{
 683        char *token;
 684
 685        if (read_expected(EVENT_ITEM, (char *)"name") < 0)
 686                return NULL;
 687
 688        if (read_expected(EVENT_OP, (char *)":") < 0)
 689                return NULL;
 690
 691        if (read_expect_type(EVENT_ITEM, &token) < 0)
 692                goto fail;
 693
 694        return token;
 695
 696 fail:
 697        free_token(token);
 698        return NULL;
 699}
 700
 701static int event_read_id(void)
 702{
 703        char *token;
 704        int id;
 705
 706        if (read_expected_item(EVENT_ITEM, (char *)"ID") < 0)
 707                return -1;
 708
 709        if (read_expected(EVENT_OP, (char *)":") < 0)
 710                return -1;
 711
 712        if (read_expect_type(EVENT_ITEM, &token) < 0)
 713                goto fail;
 714
 715        id = strtoul(token, NULL, 0);
 716        free_token(token);
 717        return id;
 718
 719 fail:
 720        free_token(token);
 721        return -1;
 722}
 723
 724static int event_read_fields(struct event *event, struct format_field **fields)
 725{
 726        struct format_field *field = NULL;
 727        enum event_type type;
 728        char *token;
 729        char *last_token;
 730        int count = 0;
 731
 732        do {
 733                type = read_token(&token);
 734                if (type == EVENT_NEWLINE) {
 735                        free_token(token);
 736                        return count;
 737                }
 738
 739                count++;
 740
 741                if (test_type_token(type, token, EVENT_ITEM, (char *)"field"))
 742                        goto fail;
 743                free_token(token);
 744
 745                type = read_token(&token);
 746                /*
 747                 * The ftrace fields may still use the "special" name.
 748                 * Just ignore it.
 749                 */
 750                if (event->flags & EVENT_FL_ISFTRACE &&
 751                    type == EVENT_ITEM && strcmp(token, "special") == 0) {
 752                        free_token(token);
 753                        type = read_token(&token);
 754                }
 755
 756                if (test_type_token(type, token, EVENT_OP, (char *)":") < 0)
 757                        return -1;
 758
 759                if (read_expect_type(EVENT_ITEM, &token) < 0)
 760                        goto fail;
 761
 762                last_token = token;
 763
 764                field = malloc_or_die(sizeof(*field));
 765                memset(field, 0, sizeof(*field));
 766
 767                /* read the rest of the type */
 768                for (;;) {
 769                        type = read_token(&token);
 770                        if (type == EVENT_ITEM ||
 771                            (type == EVENT_OP && strcmp(token, "*") == 0) ||
 772                            /*
 773                             * Some of the ftrace fields are broken and have
 774                             * an illegal "." in them.
 775                             */
 776                            (event->flags & EVENT_FL_ISFTRACE &&
 777                             type == EVENT_OP && strcmp(token, ".") == 0)) {
 778
 779                                if (strcmp(token, "*") == 0)
 780                                        field->flags |= FIELD_IS_POINTER;
 781
 782                                if (field->type) {
 783                                        field->type = realloc(field->type,
 784                                                              strlen(field->type) +
 785                                                              strlen(last_token) + 2);
 786                                        strcat(field->type, " ");
 787                                        strcat(field->type, last_token);
 788                                } else
 789                                        field->type = last_token;
 790                                last_token = token;
 791                                continue;
 792                        }
 793
 794                        break;
 795                }
 796
 797                if (!field->type) {
 798                        die("no type found");
 799                        goto fail;
 800                }
 801                field->name = last_token;
 802
 803                if (test_type(type, EVENT_OP))
 804                        goto fail;
 805
 806                if (strcmp(token, "[") == 0) {
 807                        enum event_type last_type = type;
 808                        char *brackets = token;
 809                        int len;
 810
 811                        field->flags |= FIELD_IS_ARRAY;
 812
 813                        type = read_token(&token);
 814                        while (strcmp(token, "]") != 0) {
 815                                if (last_type == EVENT_ITEM &&
 816                                    type == EVENT_ITEM)
 817                                        len = 2;
 818                                else
 819                                        len = 1;
 820                                last_type = type;
 821
 822                                brackets = realloc(brackets,
 823                                                   strlen(brackets) +
 824                                                   strlen(token) + len);
 825                                if (len == 2)
 826                                        strcat(brackets, " ");
 827                                strcat(brackets, token);
 828                                free_token(token);
 829                                type = read_token(&token);
 830                                if (type == EVENT_NONE) {
 831                                        die("failed to find token");
 832                                        goto fail;
 833                                }
 834                        }
 835
 836                        free_token(token);
 837
 838                        brackets = realloc(brackets, strlen(brackets) + 2);
 839                        strcat(brackets, "]");
 840
 841                        /* add brackets to type */
 842
 843                        type = read_token(&token);
 844                        /*
 845                         * If the next token is not an OP, then it is of
 846                         * the format: type [] item;
 847                         */
 848                        if (type == EVENT_ITEM) {
 849                                field->type = realloc(field->type,
 850                                                      strlen(field->type) +
 851                                                      strlen(field->name) +
 852                                                      strlen(brackets) + 2);
 853                                strcat(field->type, " ");
 854                                strcat(field->type, field->name);
 855                                free_token(field->name);
 856                                strcat(field->type, brackets);
 857                                field->name = token;
 858                                type = read_token(&token);
 859                        } else {
 860                                field->type = realloc(field->type,
 861                                                      strlen(field->type) +
 862                                                      strlen(brackets) + 1);
 863                                strcat(field->type, brackets);
 864                        }
 865                        free(brackets);
 866                }
 867
 868                if (test_type_token(type, token,  EVENT_OP, (char *)";"))
 869                        goto fail;
 870                free_token(token);
 871
 872                if (read_expected(EVENT_ITEM, (char *)"offset") < 0)
 873                        goto fail_expect;
 874
 875                if (read_expected(EVENT_OP, (char *)":") < 0)
 876                        goto fail_expect;
 877
 878                if (read_expect_type(EVENT_ITEM, &token))
 879                        goto fail;
 880                field->offset = strtoul(token, NULL, 0);
 881                free_token(token);
 882
 883                if (read_expected(EVENT_OP, (char *)";") < 0)
 884                        goto fail_expect;
 885
 886                if (read_expected(EVENT_ITEM, (char *)"size") < 0)
 887                        goto fail_expect;
 888
 889                if (read_expected(EVENT_OP, (char *)":") < 0)
 890                        goto fail_expect;
 891
 892                if (read_expect_type(EVENT_ITEM, &token))
 893                        goto fail;
 894                field->size = strtoul(token, NULL, 0);
 895                free_token(token);
 896
 897                if (read_expected(EVENT_OP, (char *)";") < 0)
 898                        goto fail_expect;
 899
 900                if (read_expect_type(EVENT_NEWLINE, &token) < 0)
 901                        goto fail;
 902                free_token(token);
 903
 904                *fields = field;
 905                fields = &field->next;
 906
 907        } while (1);
 908
 909        return 0;
 910
 911fail:
 912        free_token(token);
 913fail_expect:
 914        if (field)
 915                free(field);
 916        return -1;
 917}
 918
 919static int event_read_format(struct event *event)
 920{
 921        char *token;
 922        int ret;
 923
 924        if (read_expected_item(EVENT_ITEM, (char *)"format") < 0)
 925                return -1;
 926
 927        if (read_expected(EVENT_OP, (char *)":") < 0)
 928                return -1;
 929
 930        if (read_expect_type(EVENT_NEWLINE, &token))
 931                goto fail;
 932        free_token(token);
 933
 934        ret = event_read_fields(event, &event->format.common_fields);
 935        if (ret < 0)
 936                return ret;
 937        event->format.nr_common = ret;
 938
 939        ret = event_read_fields(event, &event->format.fields);
 940        if (ret < 0)
 941                return ret;
 942        event->format.nr_fields = ret;
 943
 944        return 0;
 945
 946 fail:
 947        free_token(token);
 948        return -1;
 949}
 950
 951enum event_type
 952process_arg_token(struct event *event, struct print_arg *arg,
 953                  char **tok, enum event_type type);
 954
 955static enum event_type
 956process_arg(struct event *event, struct print_arg *arg, char **tok)
 957{
 958        enum event_type type;
 959        char *token;
 960
 961        type = read_token(&token);
 962        *tok = token;
 963
 964        return process_arg_token(event, arg, tok, type);
 965}
 966
 967static enum event_type
 968process_cond(struct event *event, struct print_arg *top, char **tok)
 969{
 970        struct print_arg *arg, *left, *right;
 971        enum event_type type;
 972        char *token = NULL;
 973
 974        arg = malloc_or_die(sizeof(*arg));
 975        memset(arg, 0, sizeof(*arg));
 976
 977        left = malloc_or_die(sizeof(*left));
 978
 979        right = malloc_or_die(sizeof(*right));
 980
 981        arg->type = PRINT_OP;
 982        arg->op.left = left;
 983        arg->op.right = right;
 984
 985        *tok = NULL;
 986        type = process_arg(event, left, &token);
 987        if (test_type_token(type, token, EVENT_OP, (char *)":"))
 988                goto out_free;
 989
 990        arg->op.op = token;
 991
 992        type = process_arg(event, right, &token);
 993
 994        top->op.right = arg;
 995
 996        *tok = token;
 997        return type;
 998
 999out_free:
1000        free_token(*tok);
1001        free(right);
1002        free(left);
1003        free_arg(arg);
1004        return EVENT_ERROR;
1005}
1006
1007static int get_op_prio(char *op)
1008{
1009        if (!op[1]) {
1010                switch (op[0]) {
1011                case '*':
1012                case '/':
1013                case '%':
1014                        return 6;
1015                case '+':
1016                case '-':
1017                        return 7;
1018                        /* '>>' and '<<' are 8 */
1019                case '<':
1020                case '>':
1021                        return 9;
1022                        /* '==' and '!=' are 10 */
1023                case '&':
1024                        return 11;
1025                case '^':
1026                        return 12;
1027                case '|':
1028                        return 13;
1029                case '?':
1030                        return 16;
1031                default:
1032                        die("unknown op '%c'", op[0]);
1033                        return -1;
1034                }
1035        } else {
1036                if (strcmp(op, "++") == 0 ||
1037                    strcmp(op, "--") == 0) {
1038                        return 3;
1039                } else if (strcmp(op, ">>") == 0 ||
1040                           strcmp(op, "<<") == 0) {
1041                        return 8;
1042                } else if (strcmp(op, ">=") == 0 ||
1043                           strcmp(op, "<=") == 0) {
1044                        return 9;
1045                } else if (strcmp(op, "==") == 0 ||
1046                           strcmp(op, "!=") == 0) {
1047                        return 10;
1048                } else if (strcmp(op, "&&") == 0) {
1049                        return 14;
1050                } else if (strcmp(op, "||") == 0) {
1051                        return 15;
1052                } else {
1053                        die("unknown op '%s'", op);
1054                        return -1;
1055                }
1056        }
1057}
1058
1059static void set_op_prio(struct print_arg *arg)
1060{
1061
1062        /* single ops are the greatest */
1063        if (!arg->op.left || arg->op.left->type == PRINT_NULL) {
1064                arg->op.prio = 0;
1065                return;
1066        }
1067
1068        arg->op.prio = get_op_prio(arg->op.op);
1069}
1070
1071static enum event_type
1072process_op(struct event *event, struct print_arg *arg, char **tok)
1073{
1074        struct print_arg *left, *right = NULL;
1075        enum event_type type;
1076        char *token;
1077
1078        /* the op is passed in via tok */
1079        token = *tok;
1080
1081        if (arg->type == PRINT_OP && !arg->op.left) {
1082                /* handle single op */
1083                if (token[1]) {
1084                        die("bad op token %s", token);
1085                        return EVENT_ERROR;
1086                }
1087                switch (token[0]) {
1088                case '!':
1089                case '+':
1090                case '-':
1091                        break;
1092                default:
1093                        die("bad op token %s", token);
1094                        return EVENT_ERROR;
1095                }
1096
1097                /* make an empty left */
1098                left = malloc_or_die(sizeof(*left));
1099                left->type = PRINT_NULL;
1100                arg->op.left = left;
1101
1102                right = malloc_or_die(sizeof(*right));
1103                arg->op.right = right;
1104
1105                type = process_arg(event, right, tok);
1106
1107        } else if (strcmp(token, "?") == 0) {
1108
1109                left = malloc_or_die(sizeof(*left));
1110                /* copy the top arg to the left */
1111                *left = *arg;
1112
1113                arg->type = PRINT_OP;
1114                arg->op.op = token;
1115                arg->op.left = left;
1116                arg->op.prio = 0;
1117
1118                type = process_cond(event, arg, tok);
1119
1120        } else if (strcmp(token, ">>") == 0 ||
1121                   strcmp(token, "<<") == 0 ||
1122                   strcmp(token, "&") == 0 ||
1123                   strcmp(token, "|") == 0 ||
1124                   strcmp(token, "&&") == 0 ||
1125                   strcmp(token, "||") == 0 ||
1126                   strcmp(token, "-") == 0 ||
1127                   strcmp(token, "+") == 0 ||
1128                   strcmp(token, "*") == 0 ||
1129                   strcmp(token, "^") == 0 ||
1130                   strcmp(token, "/") == 0 ||
1131                   strcmp(token, "==") == 0 ||
1132                   strcmp(token, "!=") == 0) {
1133
1134                left = malloc_or_die(sizeof(*left));
1135
1136                /* copy the top arg to the left */
1137                *left = *arg;
1138
1139                arg->type = PRINT_OP;
1140                arg->op.op = token;
1141                arg->op.left = left;
1142
1143                set_op_prio(arg);
1144
1145                right = malloc_or_die(sizeof(*right));
1146
1147                type = process_arg(event, right, tok);
1148
1149                arg->op.right = right;
1150
1151        } else {
1152                die("unknown op '%s'", token);
1153                /* the arg is now the left side */
1154                return EVENT_NONE;
1155        }
1156
1157
1158        if (type == EVENT_OP) {
1159                int prio;
1160
1161                /* higher prios need to be closer to the root */
1162                prio = get_op_prio(*tok);
1163
1164                if (prio > arg->op.prio)
1165                        return process_op(event, arg, tok);
1166
1167                return process_op(event, right, tok);
1168        }
1169
1170        return type;
1171}
1172
1173static enum event_type
1174process_entry(struct event *event __unused, struct print_arg *arg,
1175              char **tok)
1176{
1177        enum event_type type;
1178        char *field;
1179        char *token;
1180
1181        if (read_expected(EVENT_OP, (char *)"->") < 0)
1182                return EVENT_ERROR;
1183
1184        if (read_expect_type(EVENT_ITEM, &token) < 0)
1185                goto fail;
1186        field = token;
1187
1188        arg->type = PRINT_FIELD;
1189        arg->field.name = field;
1190
1191        type = read_token(&token);
1192        *tok = token;
1193
1194        return type;
1195
1196fail:
1197        free_token(token);
1198        return EVENT_ERROR;
1199}
1200
1201static char *arg_eval (struct print_arg *arg);
1202
1203static long long arg_num_eval(struct print_arg *arg)
1204{
1205        long long left, right;
1206        long long val = 0;
1207
1208        switch (arg->type) {
1209        case PRINT_ATOM:
1210                val = strtoll(arg->atom.atom, NULL, 0);
1211                break;
1212        case PRINT_TYPE:
1213                val = arg_num_eval(arg->typecast.item);
1214                break;
1215        case PRINT_OP:
1216                switch (arg->op.op[0]) {
1217                case '|':
1218                        left = arg_num_eval(arg->op.left);
1219                        right = arg_num_eval(arg->op.right);
1220                        if (arg->op.op[1])
1221                                val = left || right;
1222                        else
1223                                val = left | right;
1224                        break;
1225                case '&':
1226                        left = arg_num_eval(arg->op.left);
1227                        right = arg_num_eval(arg->op.right);
1228                        if (arg->op.op[1])
1229                                val = left && right;
1230                        else
1231                                val = left & right;
1232                        break;
1233                case '<':
1234                        left = arg_num_eval(arg->op.left);
1235                        right = arg_num_eval(arg->op.right);
1236                        switch (arg->op.op[1]) {
1237                        case 0:
1238                                val = left < right;
1239                                break;
1240                        case '<':
1241                                val = left << right;
1242                                break;
1243                        case '=':
1244                                val = left <= right;
1245                                break;
1246                        default:
1247                                die("unknown op '%s'", arg->op.op);
1248                        }
1249                        break;
1250                case '>':
1251                        left = arg_num_eval(arg->op.left);
1252                        right = arg_num_eval(arg->op.right);
1253                        switch (arg->op.op[1]) {
1254                        case 0:
1255                                val = left > right;
1256                                break;
1257                        case '>':
1258                                val = left >> right;
1259                                break;
1260                        case '=':
1261                                val = left >= right;
1262                                break;
1263                        default:
1264                                die("unknown op '%s'", arg->op.op);
1265                        }
1266                        break;
1267                case '=':
1268                        left = arg_num_eval(arg->op.left);
1269                        right = arg_num_eval(arg->op.right);
1270
1271                        if (arg->op.op[1] != '=')
1272                                die("unknown op '%s'", arg->op.op);
1273
1274                        val = left == right;
1275                        break;
1276                case '!':
1277                        left = arg_num_eval(arg->op.left);
1278                        right = arg_num_eval(arg->op.right);
1279
1280                        switch (arg->op.op[1]) {
1281                        case '=':
1282                                val = left != right;
1283                                break;
1284                        default:
1285                                die("unknown op '%s'", arg->op.op);
1286                        }
1287                        break;
1288                default:
1289                        die("unknown op '%s'", arg->op.op);
1290                }
1291                break;
1292
1293        case PRINT_NULL:
1294        case PRINT_FIELD ... PRINT_SYMBOL:
1295        case PRINT_STRING:
1296        default:
1297                die("invalid eval type %d", arg->type);
1298
1299        }
1300        return val;
1301}
1302
1303static char *arg_eval (struct print_arg *arg)
1304{
1305        long long val;
1306        static char buf[20];
1307
1308        switch (arg->type) {
1309        case PRINT_ATOM:
1310                return arg->atom.atom;
1311        case PRINT_TYPE:
1312                return arg_eval(arg->typecast.item);
1313        case PRINT_OP:
1314                val = arg_num_eval(arg);
1315                sprintf(buf, "%lld", val);
1316                return buf;
1317
1318        case PRINT_NULL:
1319        case PRINT_FIELD ... PRINT_SYMBOL:
1320        case PRINT_STRING:
1321        default:
1322                die("invalid eval type %d", arg->type);
1323                break;
1324        }
1325
1326        return NULL;
1327}
1328
1329static enum event_type
1330process_fields(struct event *event, struct print_flag_sym **list, char **tok)
1331{
1332        enum event_type type;
1333        struct print_arg *arg = NULL;
1334        struct print_flag_sym *field;
1335        char *token = NULL;
1336        char *value;
1337
1338        do {
1339                free_token(token);
1340                type = read_token_item(&token);
1341                if (test_type_token(type, token, EVENT_OP, (char *)"{"))
1342                        break;
1343
1344                arg = malloc_or_die(sizeof(*arg));
1345
1346                free_token(token);
1347                type = process_arg(event, arg, &token);
1348                if (test_type_token(type, token, EVENT_DELIM, (char *)","))
1349                        goto out_free;
1350
1351                field = malloc_or_die(sizeof(*field));
1352                memset(field, 0, sizeof(field));
1353
1354                value = arg_eval(arg);
1355                field->value = strdup(value);
1356
1357                free_token(token);
1358                type = process_arg(event, arg, &token);
1359                if (test_type_token(type, token, EVENT_OP, (char *)"}"))
1360                        goto out_free;
1361
1362                value = arg_eval(arg);
1363                field->str = strdup(value);
1364                free_arg(arg);
1365                arg = NULL;
1366
1367                *list = field;
1368                list = &field->next;
1369
1370                free_token(token);
1371                type = read_token_item(&token);
1372        } while (type == EVENT_DELIM && strcmp(token, ",") == 0);
1373
1374        *tok = token;
1375        return type;
1376
1377out_free:
1378        free_arg(arg);
1379        free_token(token);
1380
1381        return EVENT_ERROR;
1382}
1383
1384static enum event_type
1385process_flags(struct event *event, struct print_arg *arg, char **tok)
1386{
1387        struct print_arg *field;
1388        enum event_type type;
1389        char *token;
1390
1391        memset(arg, 0, sizeof(*arg));
1392        arg->type = PRINT_FLAGS;
1393
1394        if (read_expected_item(EVENT_DELIM, (char *)"(") < 0)
1395                return EVENT_ERROR;
1396
1397        field = malloc_or_die(sizeof(*field));
1398
1399        type = process_arg(event, field, &token);
1400        if (test_type_token(type, token, EVENT_DELIM, (char *)","))
1401                goto out_free;
1402
1403        arg->flags.field = field;
1404
1405        type = read_token_item(&token);
1406        if (event_item_type(type)) {
1407                arg->flags.delim = token;
1408                type = read_token_item(&token);
1409        }
1410
1411        if (test_type_token(type, token, EVENT_DELIM, (char *)","))
1412                goto out_free;
1413
1414        type = process_fields(event, &arg->flags.flags, &token);
1415        if (test_type_token(type, token, EVENT_DELIM, (char *)")"))
1416                goto out_free;
1417
1418        free_token(token);
1419        type = read_token_item(tok);
1420        return type;
1421
1422out_free:
1423        free_token(token);
1424        return EVENT_ERROR;
1425}
1426
1427static enum event_type
1428process_symbols(struct event *event, struct print_arg *arg, char **tok)
1429{
1430        struct print_arg *field;
1431        enum event_type type;
1432        char *token;
1433
1434        memset(arg, 0, sizeof(*arg));
1435        arg->type = PRINT_SYMBOL;
1436
1437        if (read_expected_item(EVENT_DELIM, (char *)"(") < 0)
1438                return EVENT_ERROR;
1439
1440        field = malloc_or_die(sizeof(*field));
1441
1442        type = process_arg(event, field, &token);
1443        if (test_type_token(type, token, EVENT_DELIM, (char *)","))
1444                goto out_free;
1445
1446        arg->symbol.field = field;
1447
1448        type = process_fields(event, &arg->symbol.symbols, &token);
1449        if (test_type_token(type, token, EVENT_DELIM, (char *)")"))
1450                goto out_free;
1451
1452        free_token(token);
1453        type = read_token_item(tok);
1454        return type;
1455
1456out_free:
1457        free_token(token);
1458        return EVENT_ERROR;
1459}
1460
1461static enum event_type
1462process_paren(struct event *event, struct print_arg *arg, char **tok)
1463{
1464        struct print_arg *item_arg;
1465        enum event_type type;
1466        int ptr_cast = 0;
1467        char *token;
1468
1469        type = process_arg(event, arg, &token);
1470
1471        if (type == EVENT_ERROR)
1472                return EVENT_ERROR;
1473
1474        if (type == EVENT_OP) {
1475                /* handle the ptr casts */
1476                if (!strcmp(token, "*")) {
1477                        /*
1478                         * FIXME: should we zapp whitespaces before ')' ?
1479                         * (may require a peek_token_item())
1480                         */
1481                        if (__peek_char() == ')') {
1482                                ptr_cast = 1;
1483                                free_token(token);
1484                                type = read_token_item(&token);
1485                        }
1486                }
1487                if (!ptr_cast) {
1488                        type = process_op(event, arg, &token);
1489
1490                        if (type == EVENT_ERROR)
1491                                return EVENT_ERROR;
1492                }
1493        }
1494
1495        if (test_type_token(type, token, EVENT_DELIM, (char *)")")) {
1496                free_token(token);
1497                return EVENT_ERROR;
1498        }
1499
1500        free_token(token);
1501        type = read_token_item(&token);
1502
1503        /*
1504         * If the next token is an item or another open paren, then
1505         * this was a typecast.
1506         */
1507        if (event_item_type(type) ||
1508            (type == EVENT_DELIM && strcmp(token, "(") == 0)) {
1509
1510                /* make this a typecast and contine */
1511
1512                /* prevous must be an atom */
1513                if (arg->type != PRINT_ATOM)
1514                        die("previous needed to be PRINT_ATOM");
1515
1516                item_arg = malloc_or_die(sizeof(*item_arg));
1517
1518                arg->type = PRINT_TYPE;
1519                if (ptr_cast) {
1520                        char *old = arg->atom.atom;
1521
1522                        arg->atom.atom = malloc_or_die(strlen(old + 3));
1523                        sprintf(arg->atom.atom, "%s *", old);
1524                        free(old);
1525                }
1526                arg->typecast.type = arg->atom.atom;
1527                arg->typecast.item = item_arg;
1528                type = process_arg_token(event, item_arg, &token, type);
1529
1530        }
1531
1532        *tok = token;
1533        return type;
1534}
1535
1536
1537static enum event_type
1538process_str(struct event *event __unused, struct print_arg *arg, char **tok)
1539{
1540        enum event_type type;
1541        char *token;
1542
1543        if (read_expected(EVENT_DELIM, (char *)"(") < 0)
1544                return EVENT_ERROR;
1545
1546        if (read_expect_type(EVENT_ITEM, &token) < 0)
1547                goto fail;
1548
1549        arg->type = PRINT_STRING;
1550        arg->string.string = token;
1551        arg->string.offset = -1;
1552
1553        if (read_expected(EVENT_DELIM, (char *)")") < 0)
1554                return EVENT_ERROR;
1555
1556        type = read_token(&token);
1557        *tok = token;
1558
1559        return type;
1560fail:
1561        free_token(token);
1562        return EVENT_ERROR;
1563}
1564
1565enum event_type
1566process_arg_token(struct event *event, struct print_arg *arg,
1567                  char **tok, enum event_type type)
1568{
1569        char *token;
1570        char *atom;
1571
1572        token = *tok;
1573
1574        switch (type) {
1575        case EVENT_ITEM:
1576                if (strcmp(token, "REC") == 0) {
1577                        free_token(token);
1578                        type = process_entry(event, arg, &token);
1579                } else if (strcmp(token, "__print_flags") == 0) {
1580                        free_token(token);
1581                        type = process_flags(event, arg, &token);
1582                } else if (strcmp(token, "__print_symbolic") == 0) {
1583                        free_token(token);
1584                        type = process_symbols(event, arg, &token);
1585                } else if (strcmp(token, "__get_str") == 0) {
1586                        free_token(token);
1587                        type = process_str(event, arg, &token);
1588                } else {
1589                        atom = token;
1590                        /* test the next token */
1591                        type = read_token_item(&token);
1592
1593                        /* atoms can be more than one token long */
1594                        while (type == EVENT_ITEM) {
1595                                atom = realloc(atom, strlen(atom) + strlen(token) + 2);
1596                                strcat(atom, " ");
1597                                strcat(atom, token);
1598                                free_token(token);
1599                                type = read_token_item(&token);
1600                        }
1601
1602                        /* todo, test for function */
1603
1604                        arg->type = PRINT_ATOM;
1605                        arg->atom.atom = atom;
1606                }
1607                break;
1608        case EVENT_DQUOTE:
1609        case EVENT_SQUOTE:
1610                arg->type = PRINT_ATOM;
1611                arg->atom.atom = token;
1612                type = read_token_item(&token);
1613                break;
1614        case EVENT_DELIM:
1615                if (strcmp(token, "(") == 0) {
1616                        free_token(token);
1617                        type = process_paren(event, arg, &token);
1618                        break;
1619                }
1620        case EVENT_OP:
1621                /* handle single ops */
1622                arg->type = PRINT_OP;
1623                arg->op.op = token;
1624                arg->op.left = NULL;
1625                type = process_op(event, arg, &token);
1626
1627                break;
1628
1629        case EVENT_ERROR ... EVENT_NEWLINE:
1630        default:
1631                die("unexpected type %d", type);
1632        }
1633        *tok = token;
1634
1635        return type;
1636}
1637
1638static int event_read_print_args(struct event *event, struct print_arg **list)
1639{
1640        enum event_type type;
1641        struct print_arg *arg;
1642        char *token;
1643        int args = 0;
1644
1645        do {
1646                arg = malloc_or_die(sizeof(*arg));
1647                memset(arg, 0, sizeof(*arg));
1648
1649                type = process_arg(event, arg, &token);
1650
1651                if (type == EVENT_ERROR) {
1652                        free_arg(arg);
1653                        return -1;
1654                }
1655
1656                *list = arg;
1657                args++;
1658
1659                if (type == EVENT_OP) {
1660                        type = process_op(event, arg, &token);
1661                        list = &arg->next;
1662                        continue;
1663                }
1664
1665                if (type == EVENT_DELIM && strcmp(token, ",") == 0) {
1666                        free_token(token);
1667                        *list = arg;
1668                        list = &arg->next;
1669                        continue;
1670                }
1671                break;
1672        } while (type != EVENT_NONE);
1673
1674        if (type != EVENT_NONE)
1675                free_token(token);
1676
1677        return args;
1678}
1679
1680static int event_read_print(struct event *event)
1681{
1682        enum event_type type;
1683        char *token;
1684        int ret;
1685
1686        if (read_expected_item(EVENT_ITEM, (char *)"print") < 0)
1687                return -1;
1688
1689        if (read_expected(EVENT_ITEM, (char *)"fmt") < 0)
1690                return -1;
1691
1692        if (read_expected(EVENT_OP, (char *)":") < 0)
1693                return -1;
1694
1695        if (read_expect_type(EVENT_DQUOTE, &token) < 0)
1696                goto fail;
1697
1698        event->print_fmt.format = token;
1699        event->print_fmt.args = NULL;
1700
1701        /* ok to have no arg */
1702        type = read_token_item(&token);
1703
1704        if (type == EVENT_NONE)
1705                return 0;
1706
1707        if (test_type_token(type, token, EVENT_DELIM, (char *)","))
1708                goto fail;
1709
1710        free_token(token);
1711
1712        ret = event_read_print_args(event, &event->print_fmt.args);
1713        if (ret < 0)
1714                return -1;
1715
1716        return 0;
1717
1718 fail:
1719        free_token(token);
1720        return -1;
1721}
1722
1723static struct format_field *
1724find_common_field(struct event *event, const char *name)
1725{
1726        struct format_field *format;
1727
1728        for (format = event->format.common_fields;
1729             format; format = format->next) {
1730                if (strcmp(format->name, name) == 0)
1731                        break;
1732        }
1733
1734        return format;
1735}
1736
1737static struct format_field *
1738find_field(struct event *event, const char *name)
1739{
1740        struct format_field *format;
1741
1742        for (format = event->format.fields;
1743             format; format = format->next) {
1744                if (strcmp(format->name, name) == 0)
1745                        break;
1746        }
1747
1748        return format;
1749}
1750
1751static struct format_field *
1752find_any_field(struct event *event, const char *name)
1753{
1754        struct format_field *format;
1755
1756        format = find_common_field(event, name);
1757        if (format)
1758                return format;
1759        return find_field(event, name);
1760}
1761
1762static unsigned long long read_size(void *ptr, int size)
1763{
1764        switch (size) {
1765        case 1:
1766                return *(unsigned char *)ptr;
1767        case 2:
1768                return data2host2(ptr);
1769        case 4:
1770                return data2host4(ptr);
1771        case 8:
1772                return data2host8(ptr);
1773        default:
1774                /* BUG! */
1775                return 0;
1776        }
1777}
1778
1779unsigned long long
1780raw_field_value(struct event *event, const char *name, void *data)
1781{
1782        struct format_field *field;
1783
1784        field = find_any_field(event, name);
1785        if (!field)
1786                return 0ULL;
1787
1788        return read_size(data + field->offset, field->size);
1789}
1790
1791void *raw_field_ptr(struct event *event, const char *name, void *data)
1792{
1793        struct format_field *field;
1794
1795        field = find_any_field(event, name);
1796        if (!field)
1797                return NULL;
1798
1799        return data + field->offset;
1800}
1801
1802static int get_common_info(const char *type, int *offset, int *size)
1803{
1804        struct event *event;
1805        struct format_field *field;
1806
1807        /*
1808         * All events should have the same common elements.
1809         * Pick any event to find where the type is;
1810         */
1811        if (!event_list)
1812                die("no event_list!");
1813
1814        event = event_list;
1815        field = find_common_field(event, type);
1816        if (!field)
1817                die("field '%s' not found", type);
1818
1819        *offset = field->offset;
1820        *size = field->size;
1821
1822        return 0;
1823}
1824
1825int trace_parse_common_type(void *data)
1826{
1827        static int type_offset;
1828        static int type_size;
1829        int ret;
1830
1831        if (!type_size) {
1832                ret = get_common_info("common_type",
1833                                      &type_offset,
1834                                      &type_size);
1835                if (ret < 0)
1836                        return ret;
1837        }
1838        return read_size(data + type_offset, type_size);
1839}
1840
1841static int parse_common_pid(void *data)
1842{
1843        static int pid_offset;
1844        static int pid_size;
1845        int ret;
1846
1847        if (!pid_size) {
1848                ret = get_common_info("common_pid",
1849                                      &pid_offset,
1850                                      &pid_size);
1851                if (ret < 0)
1852                        return ret;
1853        }
1854
1855        return read_size(data + pid_offset, pid_size);
1856}
1857
1858struct event *trace_find_event(int id)
1859{
1860        struct event *event;
1861
1862        for (event = event_list; event; event = event->next) {
1863                if (event->id == id)
1864                        break;
1865        }
1866        return event;
1867}
1868
1869static unsigned long long eval_num_arg(void *data, int size,
1870                                   struct event *event, struct print_arg *arg)
1871{
1872        unsigned long long val = 0;
1873        unsigned long long left, right;
1874
1875        switch (arg->type) {
1876        case PRINT_NULL:
1877                /* ?? */
1878                return 0;
1879        case PRINT_ATOM:
1880                return strtoull(arg->atom.atom, NULL, 0);
1881        case PRINT_FIELD:
1882                if (!arg->field.field) {
1883                        arg->field.field = find_any_field(event, arg->field.name);
1884                        if (!arg->field.field)
1885                                die("field %s not found", arg->field.name);
1886                }
1887                /* must be a number */
1888                val = read_size(data + arg->field.field->offset,
1889                                arg->field.field->size);
1890                break;
1891        case PRINT_FLAGS:
1892        case PRINT_SYMBOL:
1893                break;
1894        case PRINT_TYPE:
1895                return eval_num_arg(data, size, event, arg->typecast.item);
1896        case PRINT_STRING:
1897                return 0;
1898                break;
1899        case PRINT_OP:
1900                left = eval_num_arg(data, size, event, arg->op.left);
1901                right = eval_num_arg(data, size, event, arg->op.right);
1902                switch (arg->op.op[0]) {
1903                case '|':
1904                        if (arg->op.op[1])
1905                                val = left || right;
1906                        else
1907                                val = left | right;
1908                        break;
1909                case '&':
1910                        if (arg->op.op[1])
1911                                val = left && right;
1912                        else
1913                                val = left & right;
1914                        break;
1915                case '<':
1916                        switch (arg->op.op[1]) {
1917                        case 0:
1918                                val = left < right;
1919                                break;
1920                        case '<':
1921                                val = left << right;
1922                                break;
1923                        case '=':
1924                                val = left <= right;
1925                                break;
1926                        default:
1927                                die("unknown op '%s'", arg->op.op);
1928                        }
1929                        break;
1930                case '>':
1931                        switch (arg->op.op[1]) {
1932                        case 0:
1933                                val = left > right;
1934                                break;
1935                        case '>':
1936                                val = left >> right;
1937                                break;
1938                        case '=':
1939                                val = left >= right;
1940                                break;
1941                        default:
1942                                die("unknown op '%s'", arg->op.op);
1943                        }
1944                        break;
1945                case '=':
1946                        if (arg->op.op[1] != '=')
1947                                die("unknown op '%s'", arg->op.op);
1948                        val = left == right;
1949                        break;
1950                default:
1951                        die("unknown op '%s'", arg->op.op);
1952                }
1953                break;
1954        default: /* not sure what to do there */
1955                return 0;
1956        }
1957        return val;
1958}
1959
1960struct flag {
1961        const char *name;
1962        unsigned long long value;
1963};
1964
1965static const struct flag flags[] = {
1966        { "HI_SOFTIRQ", 0 },
1967        { "TIMER_SOFTIRQ", 1 },
1968        { "NET_TX_SOFTIRQ", 2 },
1969        { "NET_RX_SOFTIRQ", 3 },
1970        { "BLOCK_SOFTIRQ", 4 },
1971        { "BLOCK_IOPOLL_SOFTIRQ", 5 },
1972        { "TASKLET_SOFTIRQ", 6 },
1973        { "SCHED_SOFTIRQ", 7 },
1974        { "HRTIMER_SOFTIRQ", 8 },
1975        { "RCU_SOFTIRQ", 9 },
1976
1977        { "HRTIMER_NORESTART", 0 },
1978        { "HRTIMER_RESTART", 1 },
1979};
1980
1981static unsigned long long eval_flag(const char *flag)
1982{
1983        int i;
1984
1985        /*
1986         * Some flags in the format files do not get converted.
1987         * If the flag is not numeric, see if it is something that
1988         * we already know about.
1989         */
1990        if (isdigit(flag[0]))
1991                return strtoull(flag, NULL, 0);
1992
1993        for (i = 0; i < (int)(sizeof(flags)/sizeof(flags[0])); i++)
1994                if (strcmp(flags[i].name, flag) == 0)
1995                        return flags[i].value;
1996
1997        return 0;
1998}
1999
2000static void print_str_arg(void *data, int size,
2001                          struct event *event, struct print_arg *arg)
2002{
2003        struct print_flag_sym *flag;
2004        unsigned long long val, fval;
2005        char *str;
2006        int print;
2007
2008        switch (arg->type) {
2009        case PRINT_NULL:
2010                /* ?? */
2011                return;
2012        case PRINT_ATOM:
2013                printf("%s", arg->atom.atom);
2014                return;
2015        case PRINT_FIELD:
2016                if (!arg->field.field) {
2017                        arg->field.field = find_any_field(event, arg->field.name);
2018                        if (!arg->field.field)
2019                                die("field %s not found", arg->field.name);
2020                }
2021                str = malloc_or_die(arg->field.field->size + 1);
2022                memcpy(str, data + arg->field.field->offset,
2023                       arg->field.field->size);
2024                str[arg->field.field->size] = 0;
2025                printf("%s", str);
2026                free(str);
2027                break;
2028        case PRINT_FLAGS:
2029                val = eval_num_arg(data, size, event, arg->flags.field);
2030                print = 0;
2031                for (flag = arg->flags.flags; flag; flag = flag->next) {
2032                        fval = eval_flag(flag->value);
2033                        if (!val && !fval) {
2034                                printf("%s", flag->str);
2035                                break;
2036                        }
2037                        if (fval && (val & fval) == fval) {
2038                                if (print && arg->flags.delim)
2039                                        printf("%s", arg->flags.delim);
2040                                printf("%s", flag->str);
2041                                print = 1;
2042                                val &= ~fval;
2043                        }
2044                }
2045                break;
2046        case PRINT_SYMBOL:
2047                val = eval_num_arg(data, size, event, arg->symbol.field);
2048                for (flag = arg->symbol.symbols; flag; flag = flag->next) {
2049                        fval = eval_flag(flag->value);
2050                        if (val == fval) {
2051                                printf("%s", flag->str);
2052                                break;
2053                        }
2054                }
2055                break;
2056
2057        case PRINT_TYPE:
2058                break;
2059        case PRINT_STRING: {
2060                int str_offset;
2061
2062                if (arg->string.offset == -1) {
2063                        struct format_field *f;
2064
2065                        f = find_any_field(event, arg->string.string);
2066                        arg->string.offset = f->offset;
2067                }
2068                str_offset = *(int *)(data + arg->string.offset);
2069                str_offset &= 0xffff;
2070                printf("%s", ((char *)data) + str_offset);
2071                break;
2072        }
2073        case PRINT_OP:
2074                /*
2075                 * The only op for string should be ? :
2076                 */
2077                if (arg->op.op[0] != '?')
2078                        return;
2079                val = eval_num_arg(data, size, event, arg->op.left);
2080                if (val)
2081                        print_str_arg(data, size, event, arg->op.right->op.left);
2082                else
2083                        print_str_arg(data, size, event, arg->op.right->op.right);
2084                break;
2085        default:
2086                /* well... */
2087                break;
2088        }
2089}
2090
2091static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struct event *event)
2092{
2093        static struct format_field *field, *ip_field;
2094        struct print_arg *args, *arg, **next;
2095        unsigned long long ip, val;
2096        char *ptr;
2097        void *bptr;
2098
2099        if (!field) {
2100                field = find_field(event, "buf");
2101                if (!field)
2102                        die("can't find buffer field for binary printk");
2103                ip_field = find_field(event, "ip");
2104                if (!ip_field)
2105                        die("can't find ip field for binary printk");
2106        }
2107
2108        ip = read_size(data + ip_field->offset, ip_field->size);
2109
2110        /*
2111         * The first arg is the IP pointer.
2112         */
2113        args = malloc_or_die(sizeof(*args));
2114        arg = args;
2115        arg->next = NULL;
2116        next = &arg->next;
2117
2118        arg->type = PRINT_ATOM;
2119        arg->atom.atom = malloc_or_die(32);
2120        sprintf(arg->atom.atom, "%lld", ip);
2121
2122        /* skip the first "%pf : " */
2123        for (ptr = fmt + 6, bptr = data + field->offset;
2124             bptr < data + size && *ptr; ptr++) {
2125                int ls = 0;
2126
2127                if (*ptr == '%') {
2128 process_again:
2129                        ptr++;
2130                        switch (*ptr) {
2131                        case '%':
2132                                break;
2133                        case 'l':
2134                                ls++;
2135                                goto process_again;
2136                        case 'L':
2137                                ls = 2;
2138                                goto process_again;
2139                        case '0' ... '9':
2140                                goto process_again;
2141                        case 'p':
2142                                ls = 1;
2143                                /* fall through */
2144                        case 'd':
2145                        case 'u':
2146                        case 'x':
2147                        case 'i':
2148                                bptr = (void *)(((unsigned long)bptr + (long_size - 1)) &
2149                                                ~(long_size - 1));
2150                                switch (ls) {
2151                                case 0:
2152                                case 1:
2153                                        ls = long_size;
2154                                        break;
2155                                case 2:
2156                                        ls = 8;
2157                                default:
2158                                        break;
2159                                }
2160                                val = read_size(bptr, ls);
2161                                bptr += ls;
2162                                arg = malloc_or_die(sizeof(*arg));
2163                                arg->next = NULL;
2164                                arg->type = PRINT_ATOM;
2165                                arg->atom.atom = malloc_or_die(32);
2166                                sprintf(arg->atom.atom, "%lld", val);
2167                                *next = arg;
2168                                next = &arg->next;
2169                                break;
2170                        case 's':
2171                                arg = malloc_or_die(sizeof(*arg));
2172                                arg->next = NULL;
2173                                arg->type = PRINT_STRING;
2174                                arg->string.string = strdup(bptr);
2175                                bptr += strlen(bptr) + 1;
2176                                *next = arg;
2177                                next = &arg->next;
2178                        default:
2179                                break;
2180                        }
2181                }
2182        }
2183
2184        return args;
2185}
2186
2187static void free_args(struct print_arg *args)
2188{
2189        struct print_arg *next;
2190
2191        while (args) {
2192                next = args->next;
2193
2194                if (args->type == PRINT_ATOM)
2195                        free(args->atom.atom);
2196                else
2197                        free(args->string.string);
2198                free(args);
2199                args = next;
2200        }
2201}
2202
2203static char *get_bprint_format(void *data, int size __unused, struct event *event)
2204{
2205        unsigned long long addr;
2206        static struct format_field *field;
2207        struct printk_map *printk;
2208        char *format;
2209        char *p;
2210
2211        if (!field) {
2212                field = find_field(event, "fmt");
2213                if (!field)
2214                        die("can't find format field for binary printk");
2215                printf("field->offset = %d size=%d\n", field->offset, field->size);
2216        }
2217
2218        addr = read_size(data + field->offset, field->size);
2219
2220        printk = find_printk(addr);
2221        if (!printk) {
2222                format = malloc_or_die(45);
2223                sprintf(format, "%%pf : (NO FORMAT FOUND at %llx)\n",
2224                        addr);
2225                return format;
2226        }
2227
2228        p = printk->printk;
2229        /* Remove any quotes. */
2230        if (*p == '"')
2231                p++;
2232        format = malloc_or_die(strlen(p) + 10);
2233        sprintf(format, "%s : %s", "%pf", p);
2234        /* remove ending quotes and new line since we will add one too */
2235        p = format + strlen(format) - 1;
2236        if (*p == '"')
2237                *p = 0;
2238
2239        p -= 2;
2240        if (strcmp(p, "\\n") == 0)
2241                *p = 0;
2242
2243        return format;
2244}
2245
2246static void pretty_print(void *data, int size, struct event *event)
2247{
2248        struct print_fmt *print_fmt = &event->print_fmt;
2249        struct print_arg *arg = print_fmt->args;
2250        struct print_arg *args = NULL;
2251        const char *ptr = print_fmt->format;
2252        unsigned long long val;
2253        struct func_map *func;
2254        const char *saveptr;
2255        char *bprint_fmt = NULL;
2256        char format[32];
2257        int show_func;
2258        int len;
2259        int ls;
2260
2261        if (event->flags & EVENT_FL_ISFUNC)
2262                ptr = " %pF <-- %pF";
2263
2264        if (event->flags & EVENT_FL_ISBPRINT) {
2265                bprint_fmt = get_bprint_format(data, size, event);
2266                args = make_bprint_args(bprint_fmt, data, size, event);
2267                arg = args;
2268                ptr = bprint_fmt;
2269        }
2270
2271        for (; *ptr; ptr++) {
2272                ls = 0;
2273                if (*ptr == '%') {
2274                        saveptr = ptr;
2275                        show_func = 0;
2276 cont_process:
2277                        ptr++;
2278                        switch (*ptr) {
2279                        case '%':
2280                                printf("%%");
2281                                break;
2282                        case 'l':
2283                                ls++;
2284                                goto cont_process;
2285                        case 'L':
2286                                ls = 2;
2287                                goto cont_process;
2288                        case 'z':
2289                        case 'Z':
2290                        case '0' ... '9':
2291                                goto cont_process;
2292                        case 'p':
2293                                if (long_size == 4)
2294                                        ls = 1;
2295                                else
2296                                        ls = 2;
2297
2298                                if (*(ptr+1) == 'F' ||
2299                                    *(ptr+1) == 'f') {
2300                                        ptr++;
2301                                        show_func = *ptr;
2302                                }
2303
2304                                /* fall through */
2305                        case 'd':
2306                        case 'i':
2307                        case 'x':
2308                        case 'X':
2309                        case 'u':
2310                                if (!arg)
2311                                        die("no argument match");
2312
2313                                len = ((unsigned long)ptr + 1) -
2314                                        (unsigned long)saveptr;
2315
2316                                /* should never happen */
2317                                if (len > 32)
2318                                        die("bad format!");
2319
2320                                memcpy(format, saveptr, len);
2321                                format[len] = 0;
2322
2323                                val = eval_num_arg(data, size, event, arg);
2324                                arg = arg->next;
2325
2326                                if (show_func) {
2327                                        func = find_func(val);
2328                                        if (func) {
2329                                                printf("%s", func->func);
2330                                                if (show_func == 'F')
2331                                                        printf("+0x%llx",
2332                                                               val - func->addr);
2333                                                break;
2334                                        }
2335                                }
2336                                switch (ls) {
2337                                case 0:
2338                                        printf(format, (int)val);
2339                                        break;
2340                                case 1:
2341                                        printf(format, (long)val);
2342                                        break;
2343                                case 2:
2344                                        printf(format, (long long)val);
2345                                        break;
2346                                default:
2347                                        die("bad count (%d)", ls);
2348                                }
2349                                break;
2350                        case 's':
2351                                if (!arg)
2352                                        die("no matching argument");
2353
2354                                print_str_arg(data, size, event, arg);
2355                                arg = arg->next;
2356                                break;
2357                        default:
2358                                printf(">%c<", *ptr);
2359
2360                        }
2361                } else
2362                        printf("%c", *ptr);
2363        }
2364
2365        if (args) {
2366                free_args(args);
2367                free(bprint_fmt);
2368        }
2369}
2370
2371static inline int log10_cpu(int nb)
2372{
2373        if (nb / 100)
2374                return 3;
2375        if (nb / 10)
2376                return 2;
2377        return 1;
2378}
2379
2380/* taken from Linux, written by Frederic Weisbecker */
2381static void print_graph_cpu(int cpu)
2382{
2383        int i;
2384        int log10_this = log10_cpu(cpu);
2385        int log10_all = log10_cpu(cpus);
2386
2387
2388        /*
2389         * Start with a space character - to make it stand out
2390         * to the right a bit when trace output is pasted into
2391         * email:
2392         */
2393        printf(" ");
2394
2395        /*
2396         * Tricky - we space the CPU field according to the max
2397         * number of online CPUs. On a 2-cpu system it would take
2398         * a maximum of 1 digit - on a 128 cpu system it would
2399         * take up to 3 digits:
2400         */
2401        for (i = 0; i < log10_all - log10_this; i++)
2402                printf(" ");
2403
2404        printf("%d) ", cpu);
2405}
2406
2407#define TRACE_GRAPH_PROCINFO_LENGTH     14
2408#define TRACE_GRAPH_INDENT      2
2409
2410static void print_graph_proc(int pid, const char *comm)
2411{
2412        /* sign + log10(MAX_INT) + '\0' */
2413        char pid_str[11];
2414        int spaces = 0;
2415        int len;
2416        int i;
2417
2418        sprintf(pid_str, "%d", pid);
2419
2420        /* 1 stands for the "-" character */
2421        len = strlen(comm) + strlen(pid_str) + 1;
2422
2423        if (len < TRACE_GRAPH_PROCINFO_LENGTH)
2424                spaces = TRACE_GRAPH_PROCINFO_LENGTH - len;
2425
2426        /* First spaces to align center */
2427        for (i = 0; i < spaces / 2; i++)
2428                printf(" ");
2429
2430        printf("%s-%s", comm, pid_str);
2431
2432        /* Last spaces to align center */
2433        for (i = 0; i < spaces - (spaces / 2); i++)
2434                printf(" ");
2435}
2436
2437static struct record *
2438get_return_for_leaf(int cpu, int cur_pid, unsigned long long cur_func,
2439                    struct record *next)
2440{
2441        struct format_field *field;
2442        struct event *event;
2443        unsigned long val;
2444        int type;
2445        int pid;
2446
2447        type = trace_parse_common_type(next->data);
2448        event = trace_find_event(type);
2449        if (!event)
2450                return NULL;
2451
2452        if (!(event->flags & EVENT_FL_ISFUNCRET))
2453                return NULL;
2454
2455        pid = parse_common_pid(next->data);
2456        field = find_field(event, "func");
2457        if (!field)
2458                die("function return does not have field func");
2459
2460        val = read_size(next->data + field->offset, field->size);
2461
2462        if (cur_pid != pid || cur_func != val)
2463                return NULL;
2464
2465        /* this is a leaf, now advance the iterator */
2466        return trace_read_data(cpu);
2467}
2468
2469/* Signal a overhead of time execution to the output */
2470static void print_graph_overhead(unsigned long long duration)
2471{
2472        /* Non nested entry or return */
2473        if (duration == ~0ULL)
2474                return (void)printf("  ");
2475
2476        /* Duration exceeded 100 msecs */
2477        if (duration > 100000ULL)
2478                return (void)printf("! ");
2479
2480        /* Duration exceeded 10 msecs */
2481        if (duration > 10000ULL)
2482                return (void)printf("+ ");
2483
2484        printf("  ");
2485}
2486
2487static void print_graph_duration(unsigned long long duration)
2488{
2489        unsigned long usecs = duration / 1000;
2490        unsigned long nsecs_rem = duration % 1000;
2491        /* log10(ULONG_MAX) + '\0' */
2492        char msecs_str[21];
2493        char nsecs_str[5];
2494        int len;
2495        int i;
2496
2497        sprintf(msecs_str, "%lu", usecs);
2498
2499        /* Print msecs */
2500        len = printf("%lu", usecs);
2501
2502        /* Print nsecs (we don't want to exceed 7 numbers) */
2503        if (len < 7) {
2504                snprintf(nsecs_str, 8 - len, "%03lu", nsecs_rem);
2505                len += printf(".%s", nsecs_str);
2506        }
2507
2508        printf(" us ");
2509
2510        /* Print remaining spaces to fit the row's width */
2511        for (i = len; i < 7; i++)
2512                printf(" ");
2513
2514        printf("|  ");
2515}
2516
2517static void
2518print_graph_entry_leaf(struct event *event, void *data, struct record *ret_rec)
2519{
2520        unsigned long long rettime, calltime;
2521        unsigned long long duration, depth;
2522        unsigned long long val;
2523        struct format_field *field;
2524        struct func_map *func;
2525        struct event *ret_event;
2526        int type;
2527        int i;
2528
2529        type = trace_parse_common_type(ret_rec->data);
2530        ret_event = trace_find_event(type);
2531
2532        field = find_field(ret_event, "rettime");
2533        if (!field)
2534                die("can't find rettime in return graph");
2535        rettime = read_size(ret_rec->data + field->offset, field->size);
2536
2537        field = find_field(ret_event, "calltime");
2538        if (!field)
2539                die("can't find rettime in return graph");
2540        calltime = read_size(ret_rec->data + field->offset, field->size);
2541
2542        duration = rettime - calltime;
2543
2544        /* Overhead */
2545        print_graph_overhead(duration);
2546
2547        /* Duration */
2548        print_graph_duration(duration);
2549
2550        field = find_field(event, "depth");
2551        if (!field)
2552                die("can't find depth in entry graph");
2553        depth = read_size(data + field->offset, field->size);
2554
2555        /* Function */
2556        for (i = 0; i < (int)(depth * TRACE_GRAPH_INDENT); i++)
2557                printf(" ");
2558
2559        field = find_field(event, "func");
2560        if (!field)
2561                die("can't find func in entry graph");
2562        val = read_size(data + field->offset, field->size);
2563        func = find_func(val);
2564
2565        if (func)
2566                printf("%s();", func->func);
2567        else
2568                printf("%llx();", val);
2569}
2570
2571static void print_graph_nested(struct event *event, void *data)
2572{
2573        struct format_field *field;
2574        unsigned long long depth;
2575        unsigned long long val;
2576        struct func_map *func;
2577        int i;
2578
2579        /* No overhead */
2580        print_graph_overhead(-1);
2581
2582        /* No time */
2583        printf("           |  ");
2584
2585        field = find_field(event, "depth");
2586        if (!field)
2587                die("can't find depth in entry graph");
2588        depth = read_size(data + field->offset, field->size);
2589
2590        /* Function */
2591        for (i = 0; i < (int)(depth * TRACE_GRAPH_INDENT); i++)
2592                printf(" ");
2593
2594        field = find_field(event, "func");
2595        if (!field)
2596                die("can't find func in entry graph");
2597        val = read_size(data + field->offset, field->size);
2598        func = find_func(val);
2599
2600        if (func)
2601                printf("%s() {", func->func);
2602        else
2603                printf("%llx() {", val);
2604}
2605
2606static void
2607pretty_print_func_ent(void *data, int size, struct event *event,
2608                      int cpu, int pid, const char *comm,
2609                      unsigned long secs, unsigned long usecs)
2610{
2611        struct format_field *field;
2612        struct record *rec;
2613        void *copy_data;
2614        unsigned long val;
2615
2616        printf("%5lu.%06lu |  ", secs, usecs);
2617
2618        print_graph_cpu(cpu);
2619        print_graph_proc(pid, comm);
2620
2621        printf(" | ");
2622
2623        field = find_field(event, "func");
2624        if (!field)
2625                die("function entry does not have func field");
2626
2627        val = read_size(data + field->offset, field->size);
2628
2629        /*
2630         * peek_data may unmap the data pointer. Copy it first.
2631         */
2632        copy_data = malloc_or_die(size);
2633        memcpy(copy_data, data, size);
2634        data = copy_data;
2635
2636        rec = trace_peek_data(cpu);
2637        if (rec) {
2638                rec = get_return_for_leaf(cpu, pid, val, rec);
2639                if (rec) {
2640                        print_graph_entry_leaf(event, data, rec);
2641                        goto out_free;
2642                }
2643        }
2644        print_graph_nested(event, data);
2645out_free:
2646        free(data);
2647}
2648
2649static void
2650pretty_print_func_ret(void *data, int size __unused, struct event *event,
2651                      int cpu, int pid, const char *comm,
2652                      unsigned long secs, unsigned long usecs)
2653{
2654        unsigned long long rettime, calltime;
2655        unsigned long long duration, depth;
2656        struct format_field *field;
2657        int i;
2658
2659        printf("%5lu.%06lu |  ", secs, usecs);
2660
2661        print_graph_cpu(cpu);
2662        print_graph_proc(pid, comm);
2663
2664        printf(" | ");
2665
2666        field = find_field(event, "rettime");
2667        if (!field)
2668                die("can't find rettime in return graph");
2669        rettime = read_size(data + field->offset, field->size);
2670
2671        field = find_field(event, "calltime");
2672        if (!field)
2673                die("can't find calltime in return graph");
2674        calltime = read_size(data + field->offset, field->size);
2675
2676        duration = rettime - calltime;
2677
2678        /* Overhead */
2679        print_graph_overhead(duration);
2680
2681        /* Duration */
2682        print_graph_duration(duration);
2683
2684        field = find_field(event, "depth");
2685        if (!field)
2686                die("can't find depth in entry graph");
2687        depth = read_size(data + field->offset, field->size);
2688
2689        /* Function */
2690        for (i = 0; i < (int)(depth * TRACE_GRAPH_INDENT); i++)
2691                printf(" ");
2692
2693        printf("}");
2694}
2695
2696static void
2697pretty_print_func_graph(void *data, int size, struct event *event,
2698                        int cpu, int pid, const char *comm,
2699                        unsigned long secs, unsigned long usecs)
2700{
2701        if (event->flags & EVENT_FL_ISFUNCENT)
2702                pretty_print_func_ent(data, size, event,
2703                                      cpu, pid, comm, secs, usecs);
2704        else if (event->flags & EVENT_FL_ISFUNCRET)
2705                pretty_print_func_ret(data, size, event,
2706                                      cpu, pid, comm, secs, usecs);
2707        printf("\n");
2708}
2709
2710void print_event(int cpu, void *data, int size, unsigned long long nsecs,
2711                  char *comm)
2712{
2713        struct event *event;
2714        unsigned long secs;
2715        unsigned long usecs;
2716        int type;
2717        int pid;
2718
2719        secs = nsecs / NSECS_PER_SEC;
2720        nsecs -= secs * NSECS_PER_SEC;
2721        usecs = nsecs / NSECS_PER_USEC;
2722
2723        type = trace_parse_common_type(data);
2724
2725        event = trace_find_event(type);
2726        if (!event) {
2727                printf("ug! no event found for type %d\n", type);
2728                return;
2729        }
2730
2731        pid = parse_common_pid(data);
2732
2733        if (event->flags & (EVENT_FL_ISFUNCENT | EVENT_FL_ISFUNCRET))
2734                return pretty_print_func_graph(data, size, event, cpu,
2735                                               pid, comm, secs, usecs);
2736
2737        printf("%16s-%-5d [%03d] %5lu.%09Lu: %s: ",
2738               comm, pid,  cpu,
2739               secs, nsecs, event->name);
2740
2741        pretty_print(data, size, event);
2742        printf("\n");
2743}
2744
2745static void print_fields(struct print_flag_sym *field)
2746{
2747        printf("{ %s, %s }", field->value, field->str);
2748        if (field->next) {
2749                printf(", ");
2750                print_fields(field->next);
2751        }
2752}
2753
2754static void print_args(struct print_arg *args)
2755{
2756        int print_paren = 1;
2757
2758        switch (args->type) {
2759        case PRINT_NULL:
2760                printf("null");
2761                break;
2762        case PRINT_ATOM:
2763                printf("%s", args->atom.atom);
2764                break;
2765        case PRINT_FIELD:
2766                printf("REC->%s", args->field.name);
2767                break;
2768        case PRINT_FLAGS:
2769                printf("__print_flags(");
2770                print_args(args->flags.field);
2771                printf(", %s, ", args->flags.delim);
2772                print_fields(args->flags.flags);
2773                printf(")");
2774                break;
2775        case PRINT_SYMBOL:
2776                printf("__print_symbolic(");
2777                print_args(args->symbol.field);
2778                printf(", ");
2779                print_fields(args->symbol.symbols);
2780                printf(")");
2781                break;
2782        case PRINT_STRING:
2783                printf("__get_str(%s)", args->string.string);
2784                break;
2785        case PRINT_TYPE:
2786                printf("(%s)", args->typecast.type);
2787                print_args(args->typecast.item);
2788                break;
2789        case PRINT_OP:
2790                if (strcmp(args->op.op, ":") == 0)
2791                        print_paren = 0;
2792                if (print_paren)
2793                        printf("(");
2794                print_args(args->op.left);
2795                printf(" %s ", args->op.op);
2796                print_args(args->op.right);
2797                if (print_paren)
2798                        printf(")");
2799                break;
2800        default:
2801                /* we should warn... */
2802                return;
2803        }
2804        if (args->next) {
2805                printf("\n");
2806                print_args(args->next);
2807        }
2808}
2809
2810static void parse_header_field(char *type,
2811                               int *offset, int *size)
2812{
2813        char *token;
2814
2815        if (read_expected(EVENT_ITEM, (char *)"field") < 0)
2816                return;
2817        if (read_expected(EVENT_OP, (char *)":") < 0)
2818                return;
2819        /* type */
2820        if (read_expect_type(EVENT_ITEM, &token) < 0)
2821                return;
2822        free_token(token);
2823
2824        if (read_expected(EVENT_ITEM, type) < 0)
2825                return;
2826        if (read_expected(EVENT_OP, (char *)";") < 0)
2827                return;
2828        if (read_expected(EVENT_ITEM, (char *)"offset") < 0)
2829                return;
2830        if (read_expected(EVENT_OP, (char *)":") < 0)
2831                return;
2832        if (read_expect_type(EVENT_ITEM, &token) < 0)
2833                return;
2834        *offset = atoi(token);
2835        free_token(token);
2836        if (read_expected(EVENT_OP, (char *)";") < 0)
2837                return;
2838        if (read_expected(EVENT_ITEM, (char *)"size") < 0)
2839                return;
2840        if (read_expected(EVENT_OP, (char *)":") < 0)
2841                return;
2842        if (read_expect_type(EVENT_ITEM, &token) < 0)
2843                return;
2844        *size = atoi(token);
2845        free_token(token);
2846        if (read_expected(EVENT_OP, (char *)";") < 0)
2847                return;
2848        if (read_expect_type(EVENT_NEWLINE, &token) < 0)
2849                return;
2850        free_token(token);
2851}
2852
2853int parse_header_page(char *buf, unsigned long size)
2854{
2855        init_input_buf(buf, size);
2856
2857        parse_header_field((char *)"timestamp", &header_page_ts_offset,
2858                           &header_page_ts_size);
2859        parse_header_field((char *)"commit", &header_page_size_offset,
2860                           &header_page_size_size);
2861        parse_header_field((char *)"data", &header_page_data_offset,
2862                           &header_page_data_size);
2863
2864        return 0;
2865}
2866
2867int parse_ftrace_file(char *buf, unsigned long size)
2868{
2869        struct format_field *field;
2870        struct print_arg *arg, **list;
2871        struct event *event;
2872        int ret;
2873
2874        init_input_buf(buf, size);
2875
2876        event = alloc_event();
2877        if (!event)
2878                return -ENOMEM;
2879
2880        event->flags |= EVENT_FL_ISFTRACE;
2881
2882        event->name = event_read_name();
2883        if (!event->name)
2884                die("failed to read ftrace event name");
2885
2886        if (strcmp(event->name, "function") == 0)
2887                event->flags |= EVENT_FL_ISFUNC;
2888
2889        else if (strcmp(event->name, "funcgraph_entry") == 0)
2890                event->flags |= EVENT_FL_ISFUNCENT;
2891
2892        else if (strcmp(event->name, "funcgraph_exit") == 0)
2893                event->flags |= EVENT_FL_ISFUNCRET;
2894
2895        else if (strcmp(event->name, "bprint") == 0)
2896                event->flags |= EVENT_FL_ISBPRINT;
2897
2898        event->id = event_read_id();
2899        if (event->id < 0)
2900                die("failed to read ftrace event id");
2901
2902        add_event(event);
2903
2904        ret = event_read_format(event);
2905        if (ret < 0)
2906                die("failed to read ftrace event format");
2907
2908        ret = event_read_print(event);
2909        if (ret < 0)
2910                die("failed to read ftrace event print fmt");
2911
2912        /*
2913         * The arguments for ftrace files are parsed by the fields.
2914         * Set up the fields as their arguments.
2915         */
2916        list = &event->print_fmt.args;
2917        for (field = event->format.fields; field; field = field->next) {
2918                arg = malloc_or_die(sizeof(*arg));
2919                memset(arg, 0, sizeof(*arg));
2920                *list = arg;
2921                list = &arg->next;
2922                arg->type = PRINT_FIELD;
2923                arg->field.name = field->name;
2924                arg->field.field = field;
2925        }
2926        return 0;
2927}
2928
2929int parse_event_file(char *buf, unsigned long size, char *system__unused __unused)
2930{
2931        struct event *event;
2932        int ret;
2933
2934        init_input_buf(buf, size);
2935
2936        event = alloc_event();
2937        if (!event)
2938                return -ENOMEM;
2939
2940        event->name = event_read_name();
2941        if (!event->name)
2942                die("failed to read event name");
2943
2944        event->id = event_read_id();
2945        if (event->id < 0)
2946                die("failed to read event id");
2947
2948        ret = event_read_format(event);
2949        if (ret < 0)
2950                die("failed to read event format");
2951
2952        ret = event_read_print(event);
2953        if (ret < 0)
2954                die("failed to read event print fmt");
2955
2956#define PRINT_ARGS 0
2957        if (PRINT_ARGS && event->print_fmt.args)
2958                print_args(event->print_fmt.args);
2959
2960        add_event(event);
2961        return 0;
2962}
2963
2964void parse_set_info(int nr_cpus, int long_sz)
2965{
2966        cpus = nr_cpus;
2967        long_size = long_sz;
2968}
2969