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