at v3.6-rc2 5270 lines 114 kB view raw
1/* 2 * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com> 3 * 4 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; 8 * version 2.1 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 Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 20 * 21 * The parts for function graph printing was taken and modified from the 22 * Linux Kernel that were written by 23 * - Copyright (C) 2009 Frederic Weisbecker, 24 * Frederic Weisbecker gave his permission to relicense the code to 25 * the Lesser General Public License. 26 */ 27#define _GNU_SOURCE 28#include <stdio.h> 29#include <stdlib.h> 30#include <string.h> 31#include <stdarg.h> 32#include <ctype.h> 33#include <errno.h> 34 35#include "event-parse.h" 36#include "event-utils.h" 37 38static const char *input_buf; 39static unsigned long long input_buf_ptr; 40static unsigned long long input_buf_siz; 41 42static int is_flag_field; 43static int is_symbolic_field; 44 45static int show_warning = 1; 46 47#define do_warning(fmt, ...) \ 48 do { \ 49 if (show_warning) \ 50 warning(fmt, ##__VA_ARGS__); \ 51 } while (0) 52 53static void init_input_buf(const char *buf, unsigned long long size) 54{ 55 input_buf = buf; 56 input_buf_siz = size; 57 input_buf_ptr = 0; 58} 59 60const char *pevent_get_input_buf(void) 61{ 62 return input_buf; 63} 64 65unsigned long long pevent_get_input_buf_ptr(void) 66{ 67 return input_buf_ptr; 68} 69 70struct event_handler { 71 struct event_handler *next; 72 int id; 73 const char *sys_name; 74 const char *event_name; 75 pevent_event_handler_func func; 76 void *context; 77}; 78 79struct pevent_func_params { 80 struct pevent_func_params *next; 81 enum pevent_func_arg_type type; 82}; 83 84struct pevent_function_handler { 85 struct pevent_function_handler *next; 86 enum pevent_func_arg_type ret_type; 87 char *name; 88 pevent_func_handler func; 89 struct pevent_func_params *params; 90 int nr_args; 91}; 92 93static unsigned long long 94process_defined_func(struct trace_seq *s, void *data, int size, 95 struct event_format *event, struct print_arg *arg); 96 97static void free_func_handle(struct pevent_function_handler *func); 98 99/** 100 * pevent_buffer_init - init buffer for parsing 101 * @buf: buffer to parse 102 * @size: the size of the buffer 103 * 104 * For use with pevent_read_token(), this initializes the internal 105 * buffer that pevent_read_token() will parse. 106 */ 107void pevent_buffer_init(const char *buf, unsigned long long size) 108{ 109 init_input_buf(buf, size); 110} 111 112void breakpoint(void) 113{ 114 static int x; 115 x++; 116} 117 118struct print_arg *alloc_arg(void) 119{ 120 struct print_arg *arg; 121 122 arg = malloc_or_die(sizeof(*arg)); 123 if (!arg) 124 return NULL; 125 memset(arg, 0, sizeof(*arg)); 126 127 return arg; 128} 129 130struct cmdline { 131 char *comm; 132 int pid; 133}; 134 135static int cmdline_cmp(const void *a, const void *b) 136{ 137 const struct cmdline *ca = a; 138 const struct cmdline *cb = b; 139 140 if (ca->pid < cb->pid) 141 return -1; 142 if (ca->pid > cb->pid) 143 return 1; 144 145 return 0; 146} 147 148struct cmdline_list { 149 struct cmdline_list *next; 150 char *comm; 151 int pid; 152}; 153 154static int cmdline_init(struct pevent *pevent) 155{ 156 struct cmdline_list *cmdlist = pevent->cmdlist; 157 struct cmdline_list *item; 158 struct cmdline *cmdlines; 159 int i; 160 161 cmdlines = malloc_or_die(sizeof(*cmdlines) * pevent->cmdline_count); 162 163 i = 0; 164 while (cmdlist) { 165 cmdlines[i].pid = cmdlist->pid; 166 cmdlines[i].comm = cmdlist->comm; 167 i++; 168 item = cmdlist; 169 cmdlist = cmdlist->next; 170 free(item); 171 } 172 173 qsort(cmdlines, pevent->cmdline_count, sizeof(*cmdlines), cmdline_cmp); 174 175 pevent->cmdlines = cmdlines; 176 pevent->cmdlist = NULL; 177 178 return 0; 179} 180 181static char *find_cmdline(struct pevent *pevent, int pid) 182{ 183 const struct cmdline *comm; 184 struct cmdline key; 185 186 if (!pid) 187 return "<idle>"; 188 189 if (!pevent->cmdlines) 190 cmdline_init(pevent); 191 192 key.pid = pid; 193 194 comm = bsearch(&key, pevent->cmdlines, pevent->cmdline_count, 195 sizeof(*pevent->cmdlines), cmdline_cmp); 196 197 if (comm) 198 return comm->comm; 199 return "<...>"; 200} 201 202/** 203 * pevent_pid_is_registered - return if a pid has a cmdline registered 204 * @pevent: handle for the pevent 205 * @pid: The pid to check if it has a cmdline registered with. 206 * 207 * Returns 1 if the pid has a cmdline mapped to it 208 * 0 otherwise. 209 */ 210int pevent_pid_is_registered(struct pevent *pevent, int pid) 211{ 212 const struct cmdline *comm; 213 struct cmdline key; 214 215 if (!pid) 216 return 1; 217 218 if (!pevent->cmdlines) 219 cmdline_init(pevent); 220 221 key.pid = pid; 222 223 comm = bsearch(&key, pevent->cmdlines, pevent->cmdline_count, 224 sizeof(*pevent->cmdlines), cmdline_cmp); 225 226 if (comm) 227 return 1; 228 return 0; 229} 230 231/* 232 * If the command lines have been converted to an array, then 233 * we must add this pid. This is much slower than when cmdlines 234 * are added before the array is initialized. 235 */ 236static int add_new_comm(struct pevent *pevent, const char *comm, int pid) 237{ 238 struct cmdline *cmdlines = pevent->cmdlines; 239 const struct cmdline *cmdline; 240 struct cmdline key; 241 242 if (!pid) 243 return 0; 244 245 /* avoid duplicates */ 246 key.pid = pid; 247 248 cmdline = bsearch(&key, pevent->cmdlines, pevent->cmdline_count, 249 sizeof(*pevent->cmdlines), cmdline_cmp); 250 if (cmdline) { 251 errno = EEXIST; 252 return -1; 253 } 254 255 cmdlines = realloc(cmdlines, sizeof(*cmdlines) * (pevent->cmdline_count + 1)); 256 if (!cmdlines) { 257 errno = ENOMEM; 258 return -1; 259 } 260 261 cmdlines[pevent->cmdline_count].pid = pid; 262 cmdlines[pevent->cmdline_count].comm = strdup(comm); 263 if (!cmdlines[pevent->cmdline_count].comm) 264 die("malloc comm"); 265 266 if (cmdlines[pevent->cmdline_count].comm) 267 pevent->cmdline_count++; 268 269 qsort(cmdlines, pevent->cmdline_count, sizeof(*cmdlines), cmdline_cmp); 270 pevent->cmdlines = cmdlines; 271 272 return 0; 273} 274 275/** 276 * pevent_register_comm - register a pid / comm mapping 277 * @pevent: handle for the pevent 278 * @comm: the command line to register 279 * @pid: the pid to map the command line to 280 * 281 * This adds a mapping to search for command line names with 282 * a given pid. The comm is duplicated. 283 */ 284int pevent_register_comm(struct pevent *pevent, const char *comm, int pid) 285{ 286 struct cmdline_list *item; 287 288 if (pevent->cmdlines) 289 return add_new_comm(pevent, comm, pid); 290 291 item = malloc_or_die(sizeof(*item)); 292 item->comm = strdup(comm); 293 if (!item->comm) 294 die("malloc comm"); 295 item->pid = pid; 296 item->next = pevent->cmdlist; 297 298 pevent->cmdlist = item; 299 pevent->cmdline_count++; 300 301 return 0; 302} 303 304struct func_map { 305 unsigned long long addr; 306 char *func; 307 char *mod; 308}; 309 310struct func_list { 311 struct func_list *next; 312 unsigned long long addr; 313 char *func; 314 char *mod; 315}; 316 317static int func_cmp(const void *a, const void *b) 318{ 319 const struct func_map *fa = a; 320 const struct func_map *fb = b; 321 322 if (fa->addr < fb->addr) 323 return -1; 324 if (fa->addr > fb->addr) 325 return 1; 326 327 return 0; 328} 329 330/* 331 * We are searching for a record in between, not an exact 332 * match. 333 */ 334static int func_bcmp(const void *a, const void *b) 335{ 336 const struct func_map *fa = a; 337 const struct func_map *fb = b; 338 339 if ((fa->addr == fb->addr) || 340 341 (fa->addr > fb->addr && 342 fa->addr < (fb+1)->addr)) 343 return 0; 344 345 if (fa->addr < fb->addr) 346 return -1; 347 348 return 1; 349} 350 351static int func_map_init(struct pevent *pevent) 352{ 353 struct func_list *funclist; 354 struct func_list *item; 355 struct func_map *func_map; 356 int i; 357 358 func_map = malloc_or_die(sizeof(*func_map) * (pevent->func_count + 1)); 359 funclist = pevent->funclist; 360 361 i = 0; 362 while (funclist) { 363 func_map[i].func = funclist->func; 364 func_map[i].addr = funclist->addr; 365 func_map[i].mod = funclist->mod; 366 i++; 367 item = funclist; 368 funclist = funclist->next; 369 free(item); 370 } 371 372 qsort(func_map, pevent->func_count, sizeof(*func_map), func_cmp); 373 374 /* 375 * Add a special record at the end. 376 */ 377 func_map[pevent->func_count].func = NULL; 378 func_map[pevent->func_count].addr = 0; 379 func_map[pevent->func_count].mod = NULL; 380 381 pevent->func_map = func_map; 382 pevent->funclist = NULL; 383 384 return 0; 385} 386 387static struct func_map * 388find_func(struct pevent *pevent, unsigned long long addr) 389{ 390 struct func_map *func; 391 struct func_map key; 392 393 if (!pevent->func_map) 394 func_map_init(pevent); 395 396 key.addr = addr; 397 398 func = bsearch(&key, pevent->func_map, pevent->func_count, 399 sizeof(*pevent->func_map), func_bcmp); 400 401 return func; 402} 403 404/** 405 * pevent_find_function - find a function by a given address 406 * @pevent: handle for the pevent 407 * @addr: the address to find the function with 408 * 409 * Returns a pointer to the function stored that has the given 410 * address. Note, the address does not have to be exact, it 411 * will select the function that would contain the address. 412 */ 413const char *pevent_find_function(struct pevent *pevent, unsigned long long addr) 414{ 415 struct func_map *map; 416 417 map = find_func(pevent, addr); 418 if (!map) 419 return NULL; 420 421 return map->func; 422} 423 424/** 425 * pevent_find_function_address - find a function address by a given address 426 * @pevent: handle for the pevent 427 * @addr: the address to find the function with 428 * 429 * Returns the address the function starts at. This can be used in 430 * conjunction with pevent_find_function to print both the function 431 * name and the function offset. 432 */ 433unsigned long long 434pevent_find_function_address(struct pevent *pevent, unsigned long long addr) 435{ 436 struct func_map *map; 437 438 map = find_func(pevent, addr); 439 if (!map) 440 return 0; 441 442 return map->addr; 443} 444 445/** 446 * pevent_register_function - register a function with a given address 447 * @pevent: handle for the pevent 448 * @function: the function name to register 449 * @addr: the address the function starts at 450 * @mod: the kernel module the function may be in (NULL for none) 451 * 452 * This registers a function name with an address and module. 453 * The @func passed in is duplicated. 454 */ 455int pevent_register_function(struct pevent *pevent, char *func, 456 unsigned long long addr, char *mod) 457{ 458 struct func_list *item; 459 460 item = malloc_or_die(sizeof(*item)); 461 462 item->next = pevent->funclist; 463 item->func = strdup(func); 464 if (mod) 465 item->mod = strdup(mod); 466 else 467 item->mod = NULL; 468 item->addr = addr; 469 470 if (!item->func || (mod && !item->mod)) 471 die("malloc func"); 472 473 pevent->funclist = item; 474 pevent->func_count++; 475 476 return 0; 477} 478 479/** 480 * pevent_print_funcs - print out the stored functions 481 * @pevent: handle for the pevent 482 * 483 * This prints out the stored functions. 484 */ 485void pevent_print_funcs(struct pevent *pevent) 486{ 487 int i; 488 489 if (!pevent->func_map) 490 func_map_init(pevent); 491 492 for (i = 0; i < (int)pevent->func_count; i++) { 493 printf("%016llx %s", 494 pevent->func_map[i].addr, 495 pevent->func_map[i].func); 496 if (pevent->func_map[i].mod) 497 printf(" [%s]\n", pevent->func_map[i].mod); 498 else 499 printf("\n"); 500 } 501} 502 503struct printk_map { 504 unsigned long long addr; 505 char *printk; 506}; 507 508struct printk_list { 509 struct printk_list *next; 510 unsigned long long addr; 511 char *printk; 512}; 513 514static int printk_cmp(const void *a, const void *b) 515{ 516 const struct printk_map *pa = a; 517 const struct printk_map *pb = b; 518 519 if (pa->addr < pb->addr) 520 return -1; 521 if (pa->addr > pb->addr) 522 return 1; 523 524 return 0; 525} 526 527static void printk_map_init(struct pevent *pevent) 528{ 529 struct printk_list *printklist; 530 struct printk_list *item; 531 struct printk_map *printk_map; 532 int i; 533 534 printk_map = malloc_or_die(sizeof(*printk_map) * (pevent->printk_count + 1)); 535 536 printklist = pevent->printklist; 537 538 i = 0; 539 while (printklist) { 540 printk_map[i].printk = printklist->printk; 541 printk_map[i].addr = printklist->addr; 542 i++; 543 item = printklist; 544 printklist = printklist->next; 545 free(item); 546 } 547 548 qsort(printk_map, pevent->printk_count, sizeof(*printk_map), printk_cmp); 549 550 pevent->printk_map = printk_map; 551 pevent->printklist = NULL; 552} 553 554static struct printk_map * 555find_printk(struct pevent *pevent, unsigned long long addr) 556{ 557 struct printk_map *printk; 558 struct printk_map key; 559 560 if (!pevent->printk_map) 561 printk_map_init(pevent); 562 563 key.addr = addr; 564 565 printk = bsearch(&key, pevent->printk_map, pevent->printk_count, 566 sizeof(*pevent->printk_map), printk_cmp); 567 568 return printk; 569} 570 571/** 572 * pevent_register_print_string - register a string by its address 573 * @pevent: handle for the pevent 574 * @fmt: the string format to register 575 * @addr: the address the string was located at 576 * 577 * This registers a string by the address it was stored in the kernel. 578 * The @fmt passed in is duplicated. 579 */ 580int pevent_register_print_string(struct pevent *pevent, char *fmt, 581 unsigned long long addr) 582{ 583 struct printk_list *item; 584 585 item = malloc_or_die(sizeof(*item)); 586 587 item->next = pevent->printklist; 588 item->printk = strdup(fmt); 589 item->addr = addr; 590 591 if (!item->printk) 592 die("malloc fmt"); 593 594 pevent->printklist = item; 595 pevent->printk_count++; 596 597 return 0; 598} 599 600/** 601 * pevent_print_printk - print out the stored strings 602 * @pevent: handle for the pevent 603 * 604 * This prints the string formats that were stored. 605 */ 606void pevent_print_printk(struct pevent *pevent) 607{ 608 int i; 609 610 if (!pevent->printk_map) 611 printk_map_init(pevent); 612 613 for (i = 0; i < (int)pevent->printk_count; i++) { 614 printf("%016llx %s\n", 615 pevent->printk_map[i].addr, 616 pevent->printk_map[i].printk); 617 } 618} 619 620static struct event_format *alloc_event(void) 621{ 622 struct event_format *event; 623 624 event = malloc(sizeof(*event)); 625 if (!event) 626 return NULL; 627 memset(event, 0, sizeof(*event)); 628 629 return event; 630} 631 632static void add_event(struct pevent *pevent, struct event_format *event) 633{ 634 int i; 635 636 pevent->events = realloc(pevent->events, sizeof(event) * 637 (pevent->nr_events + 1)); 638 if (!pevent->events) 639 die("Can not allocate events"); 640 641 for (i = 0; i < pevent->nr_events; i++) { 642 if (pevent->events[i]->id > event->id) 643 break; 644 } 645 if (i < pevent->nr_events) 646 memmove(&pevent->events[i + 1], 647 &pevent->events[i], 648 sizeof(event) * (pevent->nr_events - i)); 649 650 pevent->events[i] = event; 651 pevent->nr_events++; 652 653 event->pevent = pevent; 654} 655 656static int event_item_type(enum event_type type) 657{ 658 switch (type) { 659 case EVENT_ITEM ... EVENT_SQUOTE: 660 return 1; 661 case EVENT_ERROR ... EVENT_DELIM: 662 default: 663 return 0; 664 } 665} 666 667static void free_flag_sym(struct print_flag_sym *fsym) 668{ 669 struct print_flag_sym *next; 670 671 while (fsym) { 672 next = fsym->next; 673 free(fsym->value); 674 free(fsym->str); 675 free(fsym); 676 fsym = next; 677 } 678} 679 680static void free_arg(struct print_arg *arg) 681{ 682 struct print_arg *farg; 683 684 if (!arg) 685 return; 686 687 switch (arg->type) { 688 case PRINT_ATOM: 689 free(arg->atom.atom); 690 break; 691 case PRINT_FIELD: 692 free(arg->field.name); 693 break; 694 case PRINT_FLAGS: 695 free_arg(arg->flags.field); 696 free(arg->flags.delim); 697 free_flag_sym(arg->flags.flags); 698 break; 699 case PRINT_SYMBOL: 700 free_arg(arg->symbol.field); 701 free_flag_sym(arg->symbol.symbols); 702 break; 703 case PRINT_HEX: 704 free_arg(arg->hex.field); 705 free_arg(arg->hex.size); 706 break; 707 case PRINT_TYPE: 708 free(arg->typecast.type); 709 free_arg(arg->typecast.item); 710 break; 711 case PRINT_STRING: 712 case PRINT_BSTRING: 713 free(arg->string.string); 714 break; 715 case PRINT_DYNAMIC_ARRAY: 716 free(arg->dynarray.index); 717 break; 718 case PRINT_OP: 719 free(arg->op.op); 720 free_arg(arg->op.left); 721 free_arg(arg->op.right); 722 break; 723 case PRINT_FUNC: 724 while (arg->func.args) { 725 farg = arg->func.args; 726 arg->func.args = farg->next; 727 free_arg(farg); 728 } 729 break; 730 731 case PRINT_NULL: 732 default: 733 break; 734 } 735 736 free(arg); 737} 738 739static enum event_type get_type(int ch) 740{ 741 if (ch == '\n') 742 return EVENT_NEWLINE; 743 if (isspace(ch)) 744 return EVENT_SPACE; 745 if (isalnum(ch) || ch == '_') 746 return EVENT_ITEM; 747 if (ch == '\'') 748 return EVENT_SQUOTE; 749 if (ch == '"') 750 return EVENT_DQUOTE; 751 if (!isprint(ch)) 752 return EVENT_NONE; 753 if (ch == '(' || ch == ')' || ch == ',') 754 return EVENT_DELIM; 755 756 return EVENT_OP; 757} 758 759static int __read_char(void) 760{ 761 if (input_buf_ptr >= input_buf_siz) 762 return -1; 763 764 return input_buf[input_buf_ptr++]; 765} 766 767static int __peek_char(void) 768{ 769 if (input_buf_ptr >= input_buf_siz) 770 return -1; 771 772 return input_buf[input_buf_ptr]; 773} 774 775/** 776 * pevent_peek_char - peek at the next character that will be read 777 * 778 * Returns the next character read, or -1 if end of buffer. 779 */ 780int pevent_peek_char(void) 781{ 782 return __peek_char(); 783} 784 785static int extend_token(char **tok, char *buf, int size) 786{ 787 char *newtok = realloc(*tok, size); 788 789 if (!newtok) { 790 free(*tok); 791 *tok = NULL; 792 return -1; 793 } 794 795 if (!*tok) 796 strcpy(newtok, buf); 797 else 798 strcat(newtok, buf); 799 *tok = newtok; 800 801 return 0; 802} 803 804static enum event_type force_token(const char *str, char **tok); 805 806static enum event_type __read_token(char **tok) 807{ 808 char buf[BUFSIZ]; 809 int ch, last_ch, quote_ch, next_ch; 810 int i = 0; 811 int tok_size = 0; 812 enum event_type type; 813 814 *tok = NULL; 815 816 817 ch = __read_char(); 818 if (ch < 0) 819 return EVENT_NONE; 820 821 type = get_type(ch); 822 if (type == EVENT_NONE) 823 return type; 824 825 buf[i++] = ch; 826 827 switch (type) { 828 case EVENT_NEWLINE: 829 case EVENT_DELIM: 830 *tok = malloc_or_die(2); 831 (*tok)[0] = ch; 832 (*tok)[1] = 0; 833 return type; 834 835 case EVENT_OP: 836 switch (ch) { 837 case '-': 838 next_ch = __peek_char(); 839 if (next_ch == '>') { 840 buf[i++] = __read_char(); 841 break; 842 } 843 /* fall through */ 844 case '+': 845 case '|': 846 case '&': 847 case '>': 848 case '<': 849 last_ch = ch; 850 ch = __peek_char(); 851 if (ch != last_ch) 852 goto test_equal; 853 buf[i++] = __read_char(); 854 switch (last_ch) { 855 case '>': 856 case '<': 857 goto test_equal; 858 default: 859 break; 860 } 861 break; 862 case '!': 863 case '=': 864 goto test_equal; 865 default: /* what should we do instead? */ 866 break; 867 } 868 buf[i] = 0; 869 *tok = strdup(buf); 870 return type; 871 872 test_equal: 873 ch = __peek_char(); 874 if (ch == '=') 875 buf[i++] = __read_char(); 876 goto out; 877 878 case EVENT_DQUOTE: 879 case EVENT_SQUOTE: 880 /* don't keep quotes */ 881 i--; 882 quote_ch = ch; 883 last_ch = 0; 884 concat: 885 do { 886 if (i == (BUFSIZ - 1)) { 887 buf[i] = 0; 888 tok_size += BUFSIZ; 889 890 if (extend_token(tok, buf, tok_size) < 0) 891 return EVENT_NONE; 892 i = 0; 893 } 894 last_ch = ch; 895 ch = __read_char(); 896 buf[i++] = ch; 897 /* the '\' '\' will cancel itself */ 898 if (ch == '\\' && last_ch == '\\') 899 last_ch = 0; 900 } while (ch != quote_ch || last_ch == '\\'); 901 /* remove the last quote */ 902 i--; 903 904 /* 905 * For strings (double quotes) check the next token. 906 * If it is another string, concatinate the two. 907 */ 908 if (type == EVENT_DQUOTE) { 909 unsigned long long save_input_buf_ptr = input_buf_ptr; 910 911 do { 912 ch = __read_char(); 913 } while (isspace(ch)); 914 if (ch == '"') 915 goto concat; 916 input_buf_ptr = save_input_buf_ptr; 917 } 918 919 goto out; 920 921 case EVENT_ERROR ... EVENT_SPACE: 922 case EVENT_ITEM: 923 default: 924 break; 925 } 926 927 while (get_type(__peek_char()) == type) { 928 if (i == (BUFSIZ - 1)) { 929 buf[i] = 0; 930 tok_size += BUFSIZ; 931 932 if (extend_token(tok, buf, tok_size) < 0) 933 return EVENT_NONE; 934 i = 0; 935 } 936 ch = __read_char(); 937 buf[i++] = ch; 938 } 939 940 out: 941 buf[i] = 0; 942 if (extend_token(tok, buf, tok_size + i + 1) < 0) 943 return EVENT_NONE; 944 945 if (type == EVENT_ITEM) { 946 /* 947 * Older versions of the kernel has a bug that 948 * creates invalid symbols and will break the mac80211 949 * parsing. This is a work around to that bug. 950 * 951 * See Linux kernel commit: 952 * 811cb50baf63461ce0bdb234927046131fc7fa8b 953 */ 954 if (strcmp(*tok, "LOCAL_PR_FMT") == 0) { 955 free(*tok); 956 *tok = NULL; 957 return force_token("\"\%s\" ", tok); 958 } else if (strcmp(*tok, "STA_PR_FMT") == 0) { 959 free(*tok); 960 *tok = NULL; 961 return force_token("\" sta:%pM\" ", tok); 962 } else if (strcmp(*tok, "VIF_PR_FMT") == 0) { 963 free(*tok); 964 *tok = NULL; 965 return force_token("\" vif:%p(%d)\" ", tok); 966 } 967 } 968 969 return type; 970} 971 972static enum event_type force_token(const char *str, char **tok) 973{ 974 const char *save_input_buf; 975 unsigned long long save_input_buf_ptr; 976 unsigned long long save_input_buf_siz; 977 enum event_type type; 978 979 /* save off the current input pointers */ 980 save_input_buf = input_buf; 981 save_input_buf_ptr = input_buf_ptr; 982 save_input_buf_siz = input_buf_siz; 983 984 init_input_buf(str, strlen(str)); 985 986 type = __read_token(tok); 987 988 /* reset back to original token */ 989 input_buf = save_input_buf; 990 input_buf_ptr = save_input_buf_ptr; 991 input_buf_siz = save_input_buf_siz; 992 993 return type; 994} 995 996static void free_token(char *tok) 997{ 998 if (tok) 999 free(tok); 1000} 1001 1002static enum event_type read_token(char **tok) 1003{ 1004 enum event_type type; 1005 1006 for (;;) { 1007 type = __read_token(tok); 1008 if (type != EVENT_SPACE) 1009 return type; 1010 1011 free_token(*tok); 1012 } 1013 1014 /* not reached */ 1015 *tok = NULL; 1016 return EVENT_NONE; 1017} 1018 1019/** 1020 * pevent_read_token - access to utilites to use the pevent parser 1021 * @tok: The token to return 1022 * 1023 * This will parse tokens from the string given by 1024 * pevent_init_data(). 1025 * 1026 * Returns the token type. 1027 */ 1028enum event_type pevent_read_token(char **tok) 1029{ 1030 return read_token(tok); 1031} 1032 1033/** 1034 * pevent_free_token - free a token returned by pevent_read_token 1035 * @token: the token to free 1036 */ 1037void pevent_free_token(char *token) 1038{ 1039 free_token(token); 1040} 1041 1042/* no newline */ 1043static enum event_type read_token_item(char **tok) 1044{ 1045 enum event_type type; 1046 1047 for (;;) { 1048 type = __read_token(tok); 1049 if (type != EVENT_SPACE && type != EVENT_NEWLINE) 1050 return type; 1051 free_token(*tok); 1052 *tok = NULL; 1053 } 1054 1055 /* not reached */ 1056 *tok = NULL; 1057 return EVENT_NONE; 1058} 1059 1060static int test_type(enum event_type type, enum event_type expect) 1061{ 1062 if (type != expect) { 1063 do_warning("Error: expected type %d but read %d", 1064 expect, type); 1065 return -1; 1066 } 1067 return 0; 1068} 1069 1070static int test_type_token(enum event_type type, const char *token, 1071 enum event_type expect, const char *expect_tok) 1072{ 1073 if (type != expect) { 1074 do_warning("Error: expected type %d but read %d", 1075 expect, type); 1076 return -1; 1077 } 1078 1079 if (strcmp(token, expect_tok) != 0) { 1080 do_warning("Error: expected '%s' but read '%s'", 1081 expect_tok, token); 1082 return -1; 1083 } 1084 return 0; 1085} 1086 1087static int __read_expect_type(enum event_type expect, char **tok, int newline_ok) 1088{ 1089 enum event_type type; 1090 1091 if (newline_ok) 1092 type = read_token(tok); 1093 else 1094 type = read_token_item(tok); 1095 return test_type(type, expect); 1096} 1097 1098static int read_expect_type(enum event_type expect, char **tok) 1099{ 1100 return __read_expect_type(expect, tok, 1); 1101} 1102 1103static int __read_expected(enum event_type expect, const char *str, 1104 int newline_ok) 1105{ 1106 enum event_type type; 1107 char *token; 1108 int ret; 1109 1110 if (newline_ok) 1111 type = read_token(&token); 1112 else 1113 type = read_token_item(&token); 1114 1115 ret = test_type_token(type, token, expect, str); 1116 1117 free_token(token); 1118 1119 return ret; 1120} 1121 1122static int read_expected(enum event_type expect, const char *str) 1123{ 1124 return __read_expected(expect, str, 1); 1125} 1126 1127static int read_expected_item(enum event_type expect, const char *str) 1128{ 1129 return __read_expected(expect, str, 0); 1130} 1131 1132static char *event_read_name(void) 1133{ 1134 char *token; 1135 1136 if (read_expected(EVENT_ITEM, "name") < 0) 1137 return NULL; 1138 1139 if (read_expected(EVENT_OP, ":") < 0) 1140 return NULL; 1141 1142 if (read_expect_type(EVENT_ITEM, &token) < 0) 1143 goto fail; 1144 1145 return token; 1146 1147 fail: 1148 free_token(token); 1149 return NULL; 1150} 1151 1152static int event_read_id(void) 1153{ 1154 char *token; 1155 int id; 1156 1157 if (read_expected_item(EVENT_ITEM, "ID") < 0) 1158 return -1; 1159 1160 if (read_expected(EVENT_OP, ":") < 0) 1161 return -1; 1162 1163 if (read_expect_type(EVENT_ITEM, &token) < 0) 1164 goto fail; 1165 1166 id = strtoul(token, NULL, 0); 1167 free_token(token); 1168 return id; 1169 1170 fail: 1171 free_token(token); 1172 return -1; 1173} 1174 1175static int field_is_string(struct format_field *field) 1176{ 1177 if ((field->flags & FIELD_IS_ARRAY) && 1178 (strstr(field->type, "char") || strstr(field->type, "u8") || 1179 strstr(field->type, "s8"))) 1180 return 1; 1181 1182 return 0; 1183} 1184 1185static int field_is_dynamic(struct format_field *field) 1186{ 1187 if (strncmp(field->type, "__data_loc", 10) == 0) 1188 return 1; 1189 1190 return 0; 1191} 1192 1193static int field_is_long(struct format_field *field) 1194{ 1195 /* includes long long */ 1196 if (strstr(field->type, "long")) 1197 return 1; 1198 1199 return 0; 1200} 1201 1202static int event_read_fields(struct event_format *event, struct format_field **fields) 1203{ 1204 struct format_field *field = NULL; 1205 enum event_type type; 1206 char *token; 1207 char *last_token; 1208 int count = 0; 1209 1210 do { 1211 type = read_token(&token); 1212 if (type == EVENT_NEWLINE) { 1213 free_token(token); 1214 return count; 1215 } 1216 1217 count++; 1218 1219 if (test_type_token(type, token, EVENT_ITEM, "field")) 1220 goto fail; 1221 free_token(token); 1222 1223 type = read_token(&token); 1224 /* 1225 * The ftrace fields may still use the "special" name. 1226 * Just ignore it. 1227 */ 1228 if (event->flags & EVENT_FL_ISFTRACE && 1229 type == EVENT_ITEM && strcmp(token, "special") == 0) { 1230 free_token(token); 1231 type = read_token(&token); 1232 } 1233 1234 if (test_type_token(type, token, EVENT_OP, ":") < 0) 1235 goto fail; 1236 1237 free_token(token); 1238 if (read_expect_type(EVENT_ITEM, &token) < 0) 1239 goto fail; 1240 1241 last_token = token; 1242 1243 field = malloc_or_die(sizeof(*field)); 1244 memset(field, 0, sizeof(*field)); 1245 field->event = event; 1246 1247 /* read the rest of the type */ 1248 for (;;) { 1249 type = read_token(&token); 1250 if (type == EVENT_ITEM || 1251 (type == EVENT_OP && strcmp(token, "*") == 0) || 1252 /* 1253 * Some of the ftrace fields are broken and have 1254 * an illegal "." in them. 1255 */ 1256 (event->flags & EVENT_FL_ISFTRACE && 1257 type == EVENT_OP && strcmp(token, ".") == 0)) { 1258 1259 if (strcmp(token, "*") == 0) 1260 field->flags |= FIELD_IS_POINTER; 1261 1262 if (field->type) { 1263 char *new_type; 1264 new_type = realloc(field->type, 1265 strlen(field->type) + 1266 strlen(last_token) + 2); 1267 if (!new_type) { 1268 free(last_token); 1269 goto fail; 1270 } 1271 field->type = new_type; 1272 strcat(field->type, " "); 1273 strcat(field->type, last_token); 1274 free(last_token); 1275 } else 1276 field->type = last_token; 1277 last_token = token; 1278 continue; 1279 } 1280 1281 break; 1282 } 1283 1284 if (!field->type) { 1285 die("no type found"); 1286 goto fail; 1287 } 1288 field->name = last_token; 1289 1290 if (test_type(type, EVENT_OP)) 1291 goto fail; 1292 1293 if (strcmp(token, "[") == 0) { 1294 enum event_type last_type = type; 1295 char *brackets = token; 1296 char *new_brackets; 1297 int len; 1298 1299 field->flags |= FIELD_IS_ARRAY; 1300 1301 type = read_token(&token); 1302 1303 if (type == EVENT_ITEM) 1304 field->arraylen = strtoul(token, NULL, 0); 1305 else 1306 field->arraylen = 0; 1307 1308 while (strcmp(token, "]") != 0) { 1309 if (last_type == EVENT_ITEM && 1310 type == EVENT_ITEM) 1311 len = 2; 1312 else 1313 len = 1; 1314 last_type = type; 1315 1316 new_brackets = realloc(brackets, 1317 strlen(brackets) + 1318 strlen(token) + len); 1319 if (!new_brackets) { 1320 free(brackets); 1321 goto fail; 1322 } 1323 brackets = new_brackets; 1324 if (len == 2) 1325 strcat(brackets, " "); 1326 strcat(brackets, token); 1327 /* We only care about the last token */ 1328 field->arraylen = strtoul(token, NULL, 0); 1329 free_token(token); 1330 type = read_token(&token); 1331 if (type == EVENT_NONE) { 1332 die("failed to find token"); 1333 goto fail; 1334 } 1335 } 1336 1337 free_token(token); 1338 1339 new_brackets = realloc(brackets, strlen(brackets) + 2); 1340 if (!new_brackets) { 1341 free(brackets); 1342 goto fail; 1343 } 1344 brackets = new_brackets; 1345 strcat(brackets, "]"); 1346 1347 /* add brackets to type */ 1348 1349 type = read_token(&token); 1350 /* 1351 * If the next token is not an OP, then it is of 1352 * the format: type [] item; 1353 */ 1354 if (type == EVENT_ITEM) { 1355 char *new_type; 1356 new_type = realloc(field->type, 1357 strlen(field->type) + 1358 strlen(field->name) + 1359 strlen(brackets) + 2); 1360 if (!new_type) { 1361 free(brackets); 1362 goto fail; 1363 } 1364 field->type = new_type; 1365 strcat(field->type, " "); 1366 strcat(field->type, field->name); 1367 free_token(field->name); 1368 strcat(field->type, brackets); 1369 field->name = token; 1370 type = read_token(&token); 1371 } else { 1372 char *new_type; 1373 new_type = realloc(field->type, 1374 strlen(field->type) + 1375 strlen(brackets) + 1); 1376 if (!new_type) { 1377 free(brackets); 1378 goto fail; 1379 } 1380 field->type = new_type; 1381 strcat(field->type, brackets); 1382 } 1383 free(brackets); 1384 } 1385 1386 if (field_is_string(field)) 1387 field->flags |= FIELD_IS_STRING; 1388 if (field_is_dynamic(field)) 1389 field->flags |= FIELD_IS_DYNAMIC; 1390 if (field_is_long(field)) 1391 field->flags |= FIELD_IS_LONG; 1392 1393 if (test_type_token(type, token, EVENT_OP, ";")) 1394 goto fail; 1395 free_token(token); 1396 1397 if (read_expected(EVENT_ITEM, "offset") < 0) 1398 goto fail_expect; 1399 1400 if (read_expected(EVENT_OP, ":") < 0) 1401 goto fail_expect; 1402 1403 if (read_expect_type(EVENT_ITEM, &token)) 1404 goto fail; 1405 field->offset = strtoul(token, NULL, 0); 1406 free_token(token); 1407 1408 if (read_expected(EVENT_OP, ";") < 0) 1409 goto fail_expect; 1410 1411 if (read_expected(EVENT_ITEM, "size") < 0) 1412 goto fail_expect; 1413 1414 if (read_expected(EVENT_OP, ":") < 0) 1415 goto fail_expect; 1416 1417 if (read_expect_type(EVENT_ITEM, &token)) 1418 goto fail; 1419 field->size = strtoul(token, NULL, 0); 1420 free_token(token); 1421 1422 if (read_expected(EVENT_OP, ";") < 0) 1423 goto fail_expect; 1424 1425 type = read_token(&token); 1426 if (type != EVENT_NEWLINE) { 1427 /* newer versions of the kernel have a "signed" type */ 1428 if (test_type_token(type, token, EVENT_ITEM, "signed")) 1429 goto fail; 1430 1431 free_token(token); 1432 1433 if (read_expected(EVENT_OP, ":") < 0) 1434 goto fail_expect; 1435 1436 if (read_expect_type(EVENT_ITEM, &token)) 1437 goto fail; 1438 1439 /* add signed type */ 1440 1441 free_token(token); 1442 if (read_expected(EVENT_OP, ";") < 0) 1443 goto fail_expect; 1444 1445 if (read_expect_type(EVENT_NEWLINE, &token)) 1446 goto fail; 1447 } 1448 1449 free_token(token); 1450 1451 if (field->flags & FIELD_IS_ARRAY) { 1452 if (field->arraylen) 1453 field->elementsize = field->size / field->arraylen; 1454 else if (field->flags & FIELD_IS_STRING) 1455 field->elementsize = 1; 1456 else 1457 field->elementsize = event->pevent->long_size; 1458 } else 1459 field->elementsize = field->size; 1460 1461 *fields = field; 1462 fields = &field->next; 1463 1464 } while (1); 1465 1466 return 0; 1467 1468fail: 1469 free_token(token); 1470fail_expect: 1471 if (field) { 1472 free(field->type); 1473 free(field->name); 1474 free(field); 1475 } 1476 return -1; 1477} 1478 1479static int event_read_format(struct event_format *event) 1480{ 1481 char *token; 1482 int ret; 1483 1484 if (read_expected_item(EVENT_ITEM, "format") < 0) 1485 return -1; 1486 1487 if (read_expected(EVENT_OP, ":") < 0) 1488 return -1; 1489 1490 if (read_expect_type(EVENT_NEWLINE, &token)) 1491 goto fail; 1492 free_token(token); 1493 1494 ret = event_read_fields(event, &event->format.common_fields); 1495 if (ret < 0) 1496 return ret; 1497 event->format.nr_common = ret; 1498 1499 ret = event_read_fields(event, &event->format.fields); 1500 if (ret < 0) 1501 return ret; 1502 event->format.nr_fields = ret; 1503 1504 return 0; 1505 1506 fail: 1507 free_token(token); 1508 return -1; 1509} 1510 1511static enum event_type 1512process_arg_token(struct event_format *event, struct print_arg *arg, 1513 char **tok, enum event_type type); 1514 1515static enum event_type 1516process_arg(struct event_format *event, struct print_arg *arg, char **tok) 1517{ 1518 enum event_type type; 1519 char *token; 1520 1521 type = read_token(&token); 1522 *tok = token; 1523 1524 return process_arg_token(event, arg, tok, type); 1525} 1526 1527static enum event_type 1528process_op(struct event_format *event, struct print_arg *arg, char **tok); 1529 1530static enum event_type 1531process_cond(struct event_format *event, struct print_arg *top, char **tok) 1532{ 1533 struct print_arg *arg, *left, *right; 1534 enum event_type type; 1535 char *token = NULL; 1536 1537 arg = alloc_arg(); 1538 left = alloc_arg(); 1539 right = alloc_arg(); 1540 1541 arg->type = PRINT_OP; 1542 arg->op.left = left; 1543 arg->op.right = right; 1544 1545 *tok = NULL; 1546 type = process_arg(event, left, &token); 1547 1548 again: 1549 /* Handle other operations in the arguments */ 1550 if (type == EVENT_OP && strcmp(token, ":") != 0) { 1551 type = process_op(event, left, &token); 1552 goto again; 1553 } 1554 1555 if (test_type_token(type, token, EVENT_OP, ":")) 1556 goto out_free; 1557 1558 arg->op.op = token; 1559 1560 type = process_arg(event, right, &token); 1561 1562 top->op.right = arg; 1563 1564 *tok = token; 1565 return type; 1566 1567out_free: 1568 /* Top may point to itself */ 1569 top->op.right = NULL; 1570 free_token(token); 1571 free_arg(arg); 1572 return EVENT_ERROR; 1573} 1574 1575static enum event_type 1576process_array(struct event_format *event, struct print_arg *top, char **tok) 1577{ 1578 struct print_arg *arg; 1579 enum event_type type; 1580 char *token = NULL; 1581 1582 arg = alloc_arg(); 1583 1584 *tok = NULL; 1585 type = process_arg(event, arg, &token); 1586 if (test_type_token(type, token, EVENT_OP, "]")) 1587 goto out_free; 1588 1589 top->op.right = arg; 1590 1591 free_token(token); 1592 type = read_token_item(&token); 1593 *tok = token; 1594 1595 return type; 1596 1597out_free: 1598 free_token(*tok); 1599 *tok = NULL; 1600 free_arg(arg); 1601 return EVENT_ERROR; 1602} 1603 1604static int get_op_prio(char *op) 1605{ 1606 if (!op[1]) { 1607 switch (op[0]) { 1608 case '~': 1609 case '!': 1610 return 4; 1611 case '*': 1612 case '/': 1613 case '%': 1614 return 6; 1615 case '+': 1616 case '-': 1617 return 7; 1618 /* '>>' and '<<' are 8 */ 1619 case '<': 1620 case '>': 1621 return 9; 1622 /* '==' and '!=' are 10 */ 1623 case '&': 1624 return 11; 1625 case '^': 1626 return 12; 1627 case '|': 1628 return 13; 1629 case '?': 1630 return 16; 1631 default: 1632 do_warning("unknown op '%c'", op[0]); 1633 return -1; 1634 } 1635 } else { 1636 if (strcmp(op, "++") == 0 || 1637 strcmp(op, "--") == 0) { 1638 return 3; 1639 } else if (strcmp(op, ">>") == 0 || 1640 strcmp(op, "<<") == 0) { 1641 return 8; 1642 } else if (strcmp(op, ">=") == 0 || 1643 strcmp(op, "<=") == 0) { 1644 return 9; 1645 } else if (strcmp(op, "==") == 0 || 1646 strcmp(op, "!=") == 0) { 1647 return 10; 1648 } else if (strcmp(op, "&&") == 0) { 1649 return 14; 1650 } else if (strcmp(op, "||") == 0) { 1651 return 15; 1652 } else { 1653 do_warning("unknown op '%s'", op); 1654 return -1; 1655 } 1656 } 1657} 1658 1659static int set_op_prio(struct print_arg *arg) 1660{ 1661 1662 /* single ops are the greatest */ 1663 if (!arg->op.left || arg->op.left->type == PRINT_NULL) 1664 arg->op.prio = 0; 1665 else 1666 arg->op.prio = get_op_prio(arg->op.op); 1667 1668 return arg->op.prio; 1669} 1670 1671/* Note, *tok does not get freed, but will most likely be saved */ 1672static enum event_type 1673process_op(struct event_format *event, struct print_arg *arg, char **tok) 1674{ 1675 struct print_arg *left, *right = NULL; 1676 enum event_type type; 1677 char *token; 1678 1679 /* the op is passed in via tok */ 1680 token = *tok; 1681 1682 if (arg->type == PRINT_OP && !arg->op.left) { 1683 /* handle single op */ 1684 if (token[1]) { 1685 die("bad op token %s", token); 1686 goto out_free; 1687 } 1688 switch (token[0]) { 1689 case '~': 1690 case '!': 1691 case '+': 1692 case '-': 1693 break; 1694 default: 1695 do_warning("bad op token %s", token); 1696 goto out_free; 1697 1698 } 1699 1700 /* make an empty left */ 1701 left = alloc_arg(); 1702 left->type = PRINT_NULL; 1703 arg->op.left = left; 1704 1705 right = alloc_arg(); 1706 arg->op.right = right; 1707 1708 /* do not free the token, it belongs to an op */ 1709 *tok = NULL; 1710 type = process_arg(event, right, tok); 1711 1712 } else if (strcmp(token, "?") == 0) { 1713 1714 left = alloc_arg(); 1715 /* copy the top arg to the left */ 1716 *left = *arg; 1717 1718 arg->type = PRINT_OP; 1719 arg->op.op = token; 1720 arg->op.left = left; 1721 arg->op.prio = 0; 1722 1723 type = process_cond(event, arg, tok); 1724 1725 } else if (strcmp(token, ">>") == 0 || 1726 strcmp(token, "<<") == 0 || 1727 strcmp(token, "&") == 0 || 1728 strcmp(token, "|") == 0 || 1729 strcmp(token, "&&") == 0 || 1730 strcmp(token, "||") == 0 || 1731 strcmp(token, "-") == 0 || 1732 strcmp(token, "+") == 0 || 1733 strcmp(token, "*") == 0 || 1734 strcmp(token, "^") == 0 || 1735 strcmp(token, "/") == 0 || 1736 strcmp(token, "<") == 0 || 1737 strcmp(token, ">") == 0 || 1738 strcmp(token, "==") == 0 || 1739 strcmp(token, "!=") == 0) { 1740 1741 left = alloc_arg(); 1742 1743 /* copy the top arg to the left */ 1744 *left = *arg; 1745 1746 arg->type = PRINT_OP; 1747 arg->op.op = token; 1748 arg->op.left = left; 1749 1750 if (set_op_prio(arg) == -1) { 1751 event->flags |= EVENT_FL_FAILED; 1752 /* arg->op.op (= token) will be freed at out_free */ 1753 arg->op.op = NULL; 1754 goto out_free; 1755 } 1756 1757 type = read_token_item(&token); 1758 *tok = token; 1759 1760 /* could just be a type pointer */ 1761 if ((strcmp(arg->op.op, "*") == 0) && 1762 type == EVENT_DELIM && (strcmp(token, ")") == 0)) { 1763 char *new_atom; 1764 1765 if (left->type != PRINT_ATOM) 1766 die("bad pointer type"); 1767 new_atom = realloc(left->atom.atom, 1768 strlen(left->atom.atom) + 3); 1769 if (!new_atom) 1770 goto out_free; 1771 1772 left->atom.atom = new_atom; 1773 strcat(left->atom.atom, " *"); 1774 free(arg->op.op); 1775 *arg = *left; 1776 free(left); 1777 1778 return type; 1779 } 1780 1781 right = alloc_arg(); 1782 type = process_arg_token(event, right, tok, type); 1783 arg->op.right = right; 1784 1785 } else if (strcmp(token, "[") == 0) { 1786 1787 left = alloc_arg(); 1788 *left = *arg; 1789 1790 arg->type = PRINT_OP; 1791 arg->op.op = token; 1792 arg->op.left = left; 1793 1794 arg->op.prio = 0; 1795 1796 type = process_array(event, arg, tok); 1797 1798 } else { 1799 do_warning("unknown op '%s'", token); 1800 event->flags |= EVENT_FL_FAILED; 1801 /* the arg is now the left side */ 1802 goto out_free; 1803 } 1804 1805 if (type == EVENT_OP && strcmp(*tok, ":") != 0) { 1806 int prio; 1807 1808 /* higher prios need to be closer to the root */ 1809 prio = get_op_prio(*tok); 1810 1811 if (prio > arg->op.prio) 1812 return process_op(event, arg, tok); 1813 1814 return process_op(event, right, tok); 1815 } 1816 1817 return type; 1818 1819 out_free: 1820 free_token(token); 1821 *tok = NULL; 1822 return EVENT_ERROR; 1823} 1824 1825static enum event_type 1826process_entry(struct event_format *event __unused, struct print_arg *arg, 1827 char **tok) 1828{ 1829 enum event_type type; 1830 char *field; 1831 char *token; 1832 1833 if (read_expected(EVENT_OP, "->") < 0) 1834 goto out_err; 1835 1836 if (read_expect_type(EVENT_ITEM, &token) < 0) 1837 goto out_free; 1838 field = token; 1839 1840 arg->type = PRINT_FIELD; 1841 arg->field.name = field; 1842 1843 if (is_flag_field) { 1844 arg->field.field = pevent_find_any_field(event, arg->field.name); 1845 arg->field.field->flags |= FIELD_IS_FLAG; 1846 is_flag_field = 0; 1847 } else if (is_symbolic_field) { 1848 arg->field.field = pevent_find_any_field(event, arg->field.name); 1849 arg->field.field->flags |= FIELD_IS_SYMBOLIC; 1850 is_symbolic_field = 0; 1851 } 1852 1853 type = read_token(&token); 1854 *tok = token; 1855 1856 return type; 1857 1858 out_free: 1859 free_token(token); 1860 out_err: 1861 *tok = NULL; 1862 return EVENT_ERROR; 1863} 1864 1865static char *arg_eval (struct print_arg *arg); 1866 1867static unsigned long long 1868eval_type_str(unsigned long long val, const char *type, int pointer) 1869{ 1870 int sign = 0; 1871 char *ref; 1872 int len; 1873 1874 len = strlen(type); 1875 1876 if (pointer) { 1877 1878 if (type[len-1] != '*') { 1879 do_warning("pointer expected with non pointer type"); 1880 return val; 1881 } 1882 1883 ref = malloc_or_die(len); 1884 memcpy(ref, type, len); 1885 1886 /* chop off the " *" */ 1887 ref[len - 2] = 0; 1888 1889 val = eval_type_str(val, ref, 0); 1890 free(ref); 1891 return val; 1892 } 1893 1894 /* check if this is a pointer */ 1895 if (type[len - 1] == '*') 1896 return val; 1897 1898 /* Try to figure out the arg size*/ 1899 if (strncmp(type, "struct", 6) == 0) 1900 /* all bets off */ 1901 return val; 1902 1903 if (strcmp(type, "u8") == 0) 1904 return val & 0xff; 1905 1906 if (strcmp(type, "u16") == 0) 1907 return val & 0xffff; 1908 1909 if (strcmp(type, "u32") == 0) 1910 return val & 0xffffffff; 1911 1912 if (strcmp(type, "u64") == 0 || 1913 strcmp(type, "s64")) 1914 return val; 1915 1916 if (strcmp(type, "s8") == 0) 1917 return (unsigned long long)(char)val & 0xff; 1918 1919 if (strcmp(type, "s16") == 0) 1920 return (unsigned long long)(short)val & 0xffff; 1921 1922 if (strcmp(type, "s32") == 0) 1923 return (unsigned long long)(int)val & 0xffffffff; 1924 1925 if (strncmp(type, "unsigned ", 9) == 0) { 1926 sign = 0; 1927 type += 9; 1928 } 1929 1930 if (strcmp(type, "char") == 0) { 1931 if (sign) 1932 return (unsigned long long)(char)val & 0xff; 1933 else 1934 return val & 0xff; 1935 } 1936 1937 if (strcmp(type, "short") == 0) { 1938 if (sign) 1939 return (unsigned long long)(short)val & 0xffff; 1940 else 1941 return val & 0xffff; 1942 } 1943 1944 if (strcmp(type, "int") == 0) { 1945 if (sign) 1946 return (unsigned long long)(int)val & 0xffffffff; 1947 else 1948 return val & 0xffffffff; 1949 } 1950 1951 return val; 1952} 1953 1954/* 1955 * Try to figure out the type. 1956 */ 1957static unsigned long long 1958eval_type(unsigned long long val, struct print_arg *arg, int pointer) 1959{ 1960 if (arg->type != PRINT_TYPE) 1961 die("expected type argument"); 1962 1963 return eval_type_str(val, arg->typecast.type, pointer); 1964} 1965 1966static int arg_num_eval(struct print_arg *arg, long long *val) 1967{ 1968 long long left, right; 1969 int ret = 1; 1970 1971 switch (arg->type) { 1972 case PRINT_ATOM: 1973 *val = strtoll(arg->atom.atom, NULL, 0); 1974 break; 1975 case PRINT_TYPE: 1976 ret = arg_num_eval(arg->typecast.item, val); 1977 if (!ret) 1978 break; 1979 *val = eval_type(*val, arg, 0); 1980 break; 1981 case PRINT_OP: 1982 switch (arg->op.op[0]) { 1983 case '|': 1984 ret = arg_num_eval(arg->op.left, &left); 1985 if (!ret) 1986 break; 1987 ret = arg_num_eval(arg->op.right, &right); 1988 if (!ret) 1989 break; 1990 if (arg->op.op[1]) 1991 *val = left || right; 1992 else 1993 *val = left | right; 1994 break; 1995 case '&': 1996 ret = arg_num_eval(arg->op.left, &left); 1997 if (!ret) 1998 break; 1999 ret = arg_num_eval(arg->op.right, &right); 2000 if (!ret) 2001 break; 2002 if (arg->op.op[1]) 2003 *val = left && right; 2004 else 2005 *val = left & right; 2006 break; 2007 case '<': 2008 ret = arg_num_eval(arg->op.left, &left); 2009 if (!ret) 2010 break; 2011 ret = arg_num_eval(arg->op.right, &right); 2012 if (!ret) 2013 break; 2014 switch (arg->op.op[1]) { 2015 case 0: 2016 *val = left < right; 2017 break; 2018 case '<': 2019 *val = left << right; 2020 break; 2021 case '=': 2022 *val = left <= right; 2023 break; 2024 default: 2025 do_warning("unknown op '%s'", arg->op.op); 2026 ret = 0; 2027 } 2028 break; 2029 case '>': 2030 ret = arg_num_eval(arg->op.left, &left); 2031 if (!ret) 2032 break; 2033 ret = arg_num_eval(arg->op.right, &right); 2034 if (!ret) 2035 break; 2036 switch (arg->op.op[1]) { 2037 case 0: 2038 *val = left > right; 2039 break; 2040 case '>': 2041 *val = left >> right; 2042 break; 2043 case '=': 2044 *val = left >= right; 2045 break; 2046 default: 2047 do_warning("unknown op '%s'", arg->op.op); 2048 ret = 0; 2049 } 2050 break; 2051 case '=': 2052 ret = arg_num_eval(arg->op.left, &left); 2053 if (!ret) 2054 break; 2055 ret = arg_num_eval(arg->op.right, &right); 2056 if (!ret) 2057 break; 2058 2059 if (arg->op.op[1] != '=') { 2060 do_warning("unknown op '%s'", arg->op.op); 2061 ret = 0; 2062 } else 2063 *val = left == right; 2064 break; 2065 case '!': 2066 ret = arg_num_eval(arg->op.left, &left); 2067 if (!ret) 2068 break; 2069 ret = arg_num_eval(arg->op.right, &right); 2070 if (!ret) 2071 break; 2072 2073 switch (arg->op.op[1]) { 2074 case '=': 2075 *val = left != right; 2076 break; 2077 default: 2078 do_warning("unknown op '%s'", arg->op.op); 2079 ret = 0; 2080 } 2081 break; 2082 case '-': 2083 /* check for negative */ 2084 if (arg->op.left->type == PRINT_NULL) 2085 left = 0; 2086 else 2087 ret = arg_num_eval(arg->op.left, &left); 2088 if (!ret) 2089 break; 2090 ret = arg_num_eval(arg->op.right, &right); 2091 if (!ret) 2092 break; 2093 *val = left - right; 2094 break; 2095 case '+': 2096 if (arg->op.left->type == PRINT_NULL) 2097 left = 0; 2098 else 2099 ret = arg_num_eval(arg->op.left, &left); 2100 if (!ret) 2101 break; 2102 ret = arg_num_eval(arg->op.right, &right); 2103 if (!ret) 2104 break; 2105 *val = left + right; 2106 break; 2107 default: 2108 do_warning("unknown op '%s'", arg->op.op); 2109 ret = 0; 2110 } 2111 break; 2112 2113 case PRINT_NULL: 2114 case PRINT_FIELD ... PRINT_SYMBOL: 2115 case PRINT_STRING: 2116 case PRINT_BSTRING: 2117 default: 2118 do_warning("invalid eval type %d", arg->type); 2119 ret = 0; 2120 2121 } 2122 return ret; 2123} 2124 2125static char *arg_eval (struct print_arg *arg) 2126{ 2127 long long val; 2128 static char buf[20]; 2129 2130 switch (arg->type) { 2131 case PRINT_ATOM: 2132 return arg->atom.atom; 2133 case PRINT_TYPE: 2134 return arg_eval(arg->typecast.item); 2135 case PRINT_OP: 2136 if (!arg_num_eval(arg, &val)) 2137 break; 2138 sprintf(buf, "%lld", val); 2139 return buf; 2140 2141 case PRINT_NULL: 2142 case PRINT_FIELD ... PRINT_SYMBOL: 2143 case PRINT_STRING: 2144 case PRINT_BSTRING: 2145 default: 2146 die("invalid eval type %d", arg->type); 2147 break; 2148 } 2149 2150 return NULL; 2151} 2152 2153static enum event_type 2154process_fields(struct event_format *event, struct print_flag_sym **list, char **tok) 2155{ 2156 enum event_type type; 2157 struct print_arg *arg = NULL; 2158 struct print_flag_sym *field; 2159 char *token = *tok; 2160 char *value; 2161 2162 do { 2163 free_token(token); 2164 type = read_token_item(&token); 2165 if (test_type_token(type, token, EVENT_OP, "{")) 2166 break; 2167 2168 arg = alloc_arg(); 2169 2170 free_token(token); 2171 type = process_arg(event, arg, &token); 2172 2173 if (type == EVENT_OP) 2174 type = process_op(event, arg, &token); 2175 2176 if (type == EVENT_ERROR) 2177 goto out_free; 2178 2179 if (test_type_token(type, token, EVENT_DELIM, ",")) 2180 goto out_free; 2181 2182 field = malloc_or_die(sizeof(*field)); 2183 memset(field, 0, sizeof(*field)); 2184 2185 value = arg_eval(arg); 2186 if (value == NULL) 2187 goto out_free; 2188 field->value = strdup(value); 2189 if (field->value == NULL) 2190 goto out_free; 2191 2192 free_arg(arg); 2193 arg = alloc_arg(); 2194 2195 free_token(token); 2196 type = process_arg(event, arg, &token); 2197 if (test_type_token(type, token, EVENT_OP, "}")) 2198 goto out_free; 2199 2200 value = arg_eval(arg); 2201 if (value == NULL) 2202 goto out_free; 2203 field->str = strdup(value); 2204 if (field->str == NULL) 2205 goto out_free; 2206 free_arg(arg); 2207 arg = NULL; 2208 2209 *list = field; 2210 list = &field->next; 2211 2212 free_token(token); 2213 type = read_token_item(&token); 2214 } while (type == EVENT_DELIM && strcmp(token, ",") == 0); 2215 2216 *tok = token; 2217 return type; 2218 2219out_free: 2220 free_arg(arg); 2221 free_token(token); 2222 *tok = NULL; 2223 2224 return EVENT_ERROR; 2225} 2226 2227static enum event_type 2228process_flags(struct event_format *event, struct print_arg *arg, char **tok) 2229{ 2230 struct print_arg *field; 2231 enum event_type type; 2232 char *token; 2233 2234 memset(arg, 0, sizeof(*arg)); 2235 arg->type = PRINT_FLAGS; 2236 2237 field = alloc_arg(); 2238 2239 type = process_arg(event, field, &token); 2240 2241 /* Handle operations in the first argument */ 2242 while (type == EVENT_OP) 2243 type = process_op(event, field, &token); 2244 2245 if (test_type_token(type, token, EVENT_DELIM, ",")) 2246 goto out_free; 2247 free_token(token); 2248 2249 arg->flags.field = field; 2250 2251 type = read_token_item(&token); 2252 if (event_item_type(type)) { 2253 arg->flags.delim = token; 2254 type = read_token_item(&token); 2255 } 2256 2257 if (test_type_token(type, token, EVENT_DELIM, ",")) 2258 goto out_free; 2259 2260 type = process_fields(event, &arg->flags.flags, &token); 2261 if (test_type_token(type, token, EVENT_DELIM, ")")) 2262 goto out_free; 2263 2264 free_token(token); 2265 type = read_token_item(tok); 2266 return type; 2267 2268 out_free: 2269 free_token(token); 2270 *tok = NULL; 2271 return EVENT_ERROR; 2272} 2273 2274static enum event_type 2275process_symbols(struct event_format *event, struct print_arg *arg, char **tok) 2276{ 2277 struct print_arg *field; 2278 enum event_type type; 2279 char *token; 2280 2281 memset(arg, 0, sizeof(*arg)); 2282 arg->type = PRINT_SYMBOL; 2283 2284 field = alloc_arg(); 2285 2286 type = process_arg(event, field, &token); 2287 if (test_type_token(type, token, EVENT_DELIM, ",")) 2288 goto out_free; 2289 2290 arg->symbol.field = field; 2291 2292 type = process_fields(event, &arg->symbol.symbols, &token); 2293 if (test_type_token(type, token, EVENT_DELIM, ")")) 2294 goto out_free; 2295 2296 free_token(token); 2297 type = read_token_item(tok); 2298 return type; 2299 2300 out_free: 2301 free_token(token); 2302 *tok = NULL; 2303 return EVENT_ERROR; 2304} 2305 2306static enum event_type 2307process_hex(struct event_format *event, struct print_arg *arg, char **tok) 2308{ 2309 struct print_arg *field; 2310 enum event_type type; 2311 char *token; 2312 2313 memset(arg, 0, sizeof(*arg)); 2314 arg->type = PRINT_HEX; 2315 2316 field = alloc_arg(); 2317 type = process_arg(event, field, &token); 2318 2319 if (test_type_token(type, token, EVENT_DELIM, ",")) 2320 goto out_free; 2321 2322 arg->hex.field = field; 2323 2324 free_token(token); 2325 2326 field = alloc_arg(); 2327 type = process_arg(event, field, &token); 2328 2329 if (test_type_token(type, token, EVENT_DELIM, ")")) 2330 goto out_free; 2331 2332 arg->hex.size = field; 2333 2334 free_token(token); 2335 type = read_token_item(tok); 2336 return type; 2337 2338 out_free: 2339 free_arg(field); 2340 free_token(token); 2341 *tok = NULL; 2342 return EVENT_ERROR; 2343} 2344 2345static enum event_type 2346process_dynamic_array(struct event_format *event, struct print_arg *arg, char **tok) 2347{ 2348 struct format_field *field; 2349 enum event_type type; 2350 char *token; 2351 2352 memset(arg, 0, sizeof(*arg)); 2353 arg->type = PRINT_DYNAMIC_ARRAY; 2354 2355 /* 2356 * The item within the parenthesis is another field that holds 2357 * the index into where the array starts. 2358 */ 2359 type = read_token(&token); 2360 *tok = token; 2361 if (type != EVENT_ITEM) 2362 goto out_free; 2363 2364 /* Find the field */ 2365 2366 field = pevent_find_field(event, token); 2367 if (!field) 2368 goto out_free; 2369 2370 arg->dynarray.field = field; 2371 arg->dynarray.index = 0; 2372 2373 if (read_expected(EVENT_DELIM, ")") < 0) 2374 goto out_free; 2375 2376 free_token(token); 2377 type = read_token_item(&token); 2378 *tok = token; 2379 if (type != EVENT_OP || strcmp(token, "[") != 0) 2380 return type; 2381 2382 free_token(token); 2383 arg = alloc_arg(); 2384 type = process_arg(event, arg, &token); 2385 if (type == EVENT_ERROR) 2386 goto out_free_arg; 2387 2388 if (!test_type_token(type, token, EVENT_OP, "]")) 2389 goto out_free_arg; 2390 2391 free_token(token); 2392 type = read_token_item(tok); 2393 return type; 2394 2395 out_free_arg: 2396 free_arg(arg); 2397 out_free: 2398 free_token(token); 2399 *tok = NULL; 2400 return EVENT_ERROR; 2401} 2402 2403static enum event_type 2404process_paren(struct event_format *event, struct print_arg *arg, char **tok) 2405{ 2406 struct print_arg *item_arg; 2407 enum event_type type; 2408 char *token; 2409 2410 type = process_arg(event, arg, &token); 2411 2412 if (type == EVENT_ERROR) 2413 goto out_free; 2414 2415 if (type == EVENT_OP) 2416 type = process_op(event, arg, &token); 2417 2418 if (type == EVENT_ERROR) 2419 goto out_free; 2420 2421 if (test_type_token(type, token, EVENT_DELIM, ")")) 2422 goto out_free; 2423 2424 free_token(token); 2425 type = read_token_item(&token); 2426 2427 /* 2428 * If the next token is an item or another open paren, then 2429 * this was a typecast. 2430 */ 2431 if (event_item_type(type) || 2432 (type == EVENT_DELIM && strcmp(token, "(") == 0)) { 2433 2434 /* make this a typecast and contine */ 2435 2436 /* prevous must be an atom */ 2437 if (arg->type != PRINT_ATOM) 2438 die("previous needed to be PRINT_ATOM"); 2439 2440 item_arg = alloc_arg(); 2441 2442 arg->type = PRINT_TYPE; 2443 arg->typecast.type = arg->atom.atom; 2444 arg->typecast.item = item_arg; 2445 type = process_arg_token(event, item_arg, &token, type); 2446 2447 } 2448 2449 *tok = token; 2450 return type; 2451 2452 out_free: 2453 free_token(token); 2454 *tok = NULL; 2455 return EVENT_ERROR; 2456} 2457 2458 2459static enum event_type 2460process_str(struct event_format *event __unused, struct print_arg *arg, char **tok) 2461{ 2462 enum event_type type; 2463 char *token; 2464 2465 if (read_expect_type(EVENT_ITEM, &token) < 0) 2466 goto out_free; 2467 2468 arg->type = PRINT_STRING; 2469 arg->string.string = token; 2470 arg->string.offset = -1; 2471 2472 if (read_expected(EVENT_DELIM, ")") < 0) 2473 goto out_err; 2474 2475 type = read_token(&token); 2476 *tok = token; 2477 2478 return type; 2479 2480 out_free: 2481 free_token(token); 2482 out_err: 2483 *tok = NULL; 2484 return EVENT_ERROR; 2485} 2486 2487static struct pevent_function_handler * 2488find_func_handler(struct pevent *pevent, char *func_name) 2489{ 2490 struct pevent_function_handler *func; 2491 2492 for (func = pevent->func_handlers; func; func = func->next) { 2493 if (strcmp(func->name, func_name) == 0) 2494 break; 2495 } 2496 2497 return func; 2498} 2499 2500static void remove_func_handler(struct pevent *pevent, char *func_name) 2501{ 2502 struct pevent_function_handler *func; 2503 struct pevent_function_handler **next; 2504 2505 next = &pevent->func_handlers; 2506 while ((func = *next)) { 2507 if (strcmp(func->name, func_name) == 0) { 2508 *next = func->next; 2509 free_func_handle(func); 2510 break; 2511 } 2512 next = &func->next; 2513 } 2514} 2515 2516static enum event_type 2517process_func_handler(struct event_format *event, struct pevent_function_handler *func, 2518 struct print_arg *arg, char **tok) 2519{ 2520 struct print_arg **next_arg; 2521 struct print_arg *farg; 2522 enum event_type type; 2523 char *token; 2524 char *test; 2525 int i; 2526 2527 arg->type = PRINT_FUNC; 2528 arg->func.func = func; 2529 2530 *tok = NULL; 2531 2532 next_arg = &(arg->func.args); 2533 for (i = 0; i < func->nr_args; i++) { 2534 farg = alloc_arg(); 2535 type = process_arg(event, farg, &token); 2536 if (i < (func->nr_args - 1)) 2537 test = ","; 2538 else 2539 test = ")"; 2540 2541 if (test_type_token(type, token, EVENT_DELIM, test)) { 2542 free_arg(farg); 2543 free_token(token); 2544 return EVENT_ERROR; 2545 } 2546 2547 *next_arg = farg; 2548 next_arg = &(farg->next); 2549 free_token(token); 2550 } 2551 2552 type = read_token(&token); 2553 *tok = token; 2554 2555 return type; 2556} 2557 2558static enum event_type 2559process_function(struct event_format *event, struct print_arg *arg, 2560 char *token, char **tok) 2561{ 2562 struct pevent_function_handler *func; 2563 2564 if (strcmp(token, "__print_flags") == 0) { 2565 free_token(token); 2566 is_flag_field = 1; 2567 return process_flags(event, arg, tok); 2568 } 2569 if (strcmp(token, "__print_symbolic") == 0) { 2570 free_token(token); 2571 is_symbolic_field = 1; 2572 return process_symbols(event, arg, tok); 2573 } 2574 if (strcmp(token, "__print_hex") == 0) { 2575 free_token(token); 2576 return process_hex(event, arg, tok); 2577 } 2578 if (strcmp(token, "__get_str") == 0) { 2579 free_token(token); 2580 return process_str(event, arg, tok); 2581 } 2582 if (strcmp(token, "__get_dynamic_array") == 0) { 2583 free_token(token); 2584 return process_dynamic_array(event, arg, tok); 2585 } 2586 2587 func = find_func_handler(event->pevent, token); 2588 if (func) { 2589 free_token(token); 2590 return process_func_handler(event, func, arg, tok); 2591 } 2592 2593 do_warning("function %s not defined", token); 2594 free_token(token); 2595 return EVENT_ERROR; 2596} 2597 2598static enum event_type 2599process_arg_token(struct event_format *event, struct print_arg *arg, 2600 char **tok, enum event_type type) 2601{ 2602 char *token; 2603 char *atom; 2604 2605 token = *tok; 2606 2607 switch (type) { 2608 case EVENT_ITEM: 2609 if (strcmp(token, "REC") == 0) { 2610 free_token(token); 2611 type = process_entry(event, arg, &token); 2612 break; 2613 } 2614 atom = token; 2615 /* test the next token */ 2616 type = read_token_item(&token); 2617 2618 /* 2619 * If the next token is a parenthesis, then this 2620 * is a function. 2621 */ 2622 if (type == EVENT_DELIM && strcmp(token, "(") == 0) { 2623 free_token(token); 2624 token = NULL; 2625 /* this will free atom. */ 2626 type = process_function(event, arg, atom, &token); 2627 break; 2628 } 2629 /* atoms can be more than one token long */ 2630 while (type == EVENT_ITEM) { 2631 char *new_atom; 2632 new_atom = realloc(atom, 2633 strlen(atom) + strlen(token) + 2); 2634 if (!new_atom) { 2635 free(atom); 2636 *tok = NULL; 2637 free_token(token); 2638 return EVENT_ERROR; 2639 } 2640 atom = new_atom; 2641 strcat(atom, " "); 2642 strcat(atom, token); 2643 free_token(token); 2644 type = read_token_item(&token); 2645 } 2646 2647 arg->type = PRINT_ATOM; 2648 arg->atom.atom = atom; 2649 break; 2650 2651 case EVENT_DQUOTE: 2652 case EVENT_SQUOTE: 2653 arg->type = PRINT_ATOM; 2654 arg->atom.atom = token; 2655 type = read_token_item(&token); 2656 break; 2657 case EVENT_DELIM: 2658 if (strcmp(token, "(") == 0) { 2659 free_token(token); 2660 type = process_paren(event, arg, &token); 2661 break; 2662 } 2663 case EVENT_OP: 2664 /* handle single ops */ 2665 arg->type = PRINT_OP; 2666 arg->op.op = token; 2667 arg->op.left = NULL; 2668 type = process_op(event, arg, &token); 2669 2670 /* On error, the op is freed */ 2671 if (type == EVENT_ERROR) 2672 arg->op.op = NULL; 2673 2674 /* return error type if errored */ 2675 break; 2676 2677 case EVENT_ERROR ... EVENT_NEWLINE: 2678 default: 2679 die("unexpected type %d", type); 2680 } 2681 *tok = token; 2682 2683 return type; 2684} 2685 2686static int event_read_print_args(struct event_format *event, struct print_arg **list) 2687{ 2688 enum event_type type = EVENT_ERROR; 2689 struct print_arg *arg; 2690 char *token; 2691 int args = 0; 2692 2693 do { 2694 if (type == EVENT_NEWLINE) { 2695 type = read_token_item(&token); 2696 continue; 2697 } 2698 2699 arg = alloc_arg(); 2700 2701 type = process_arg(event, arg, &token); 2702 2703 if (type == EVENT_ERROR) { 2704 free_token(token); 2705 free_arg(arg); 2706 return -1; 2707 } 2708 2709 *list = arg; 2710 args++; 2711 2712 if (type == EVENT_OP) { 2713 type = process_op(event, arg, &token); 2714 free_token(token); 2715 if (type == EVENT_ERROR) { 2716 *list = NULL; 2717 free_arg(arg); 2718 return -1; 2719 } 2720 list = &arg->next; 2721 continue; 2722 } 2723 2724 if (type == EVENT_DELIM && strcmp(token, ",") == 0) { 2725 free_token(token); 2726 *list = arg; 2727 list = &arg->next; 2728 continue; 2729 } 2730 break; 2731 } while (type != EVENT_NONE); 2732 2733 if (type != EVENT_NONE && type != EVENT_ERROR) 2734 free_token(token); 2735 2736 return args; 2737} 2738 2739static int event_read_print(struct event_format *event) 2740{ 2741 enum event_type type; 2742 char *token; 2743 int ret; 2744 2745 if (read_expected_item(EVENT_ITEM, "print") < 0) 2746 return -1; 2747 2748 if (read_expected(EVENT_ITEM, "fmt") < 0) 2749 return -1; 2750 2751 if (read_expected(EVENT_OP, ":") < 0) 2752 return -1; 2753 2754 if (read_expect_type(EVENT_DQUOTE, &token) < 0) 2755 goto fail; 2756 2757 concat: 2758 event->print_fmt.format = token; 2759 event->print_fmt.args = NULL; 2760 2761 /* ok to have no arg */ 2762 type = read_token_item(&token); 2763 2764 if (type == EVENT_NONE) 2765 return 0; 2766 2767 /* Handle concatenation of print lines */ 2768 if (type == EVENT_DQUOTE) { 2769 char *cat; 2770 2771 cat = malloc_or_die(strlen(event->print_fmt.format) + 2772 strlen(token) + 1); 2773 strcpy(cat, event->print_fmt.format); 2774 strcat(cat, token); 2775 free_token(token); 2776 free_token(event->print_fmt.format); 2777 event->print_fmt.format = NULL; 2778 token = cat; 2779 goto concat; 2780 } 2781 2782 if (test_type_token(type, token, EVENT_DELIM, ",")) 2783 goto fail; 2784 2785 free_token(token); 2786 2787 ret = event_read_print_args(event, &event->print_fmt.args); 2788 if (ret < 0) 2789 return -1; 2790 2791 return ret; 2792 2793 fail: 2794 free_token(token); 2795 return -1; 2796} 2797 2798/** 2799 * pevent_find_common_field - return a common field by event 2800 * @event: handle for the event 2801 * @name: the name of the common field to return 2802 * 2803 * Returns a common field from the event by the given @name. 2804 * This only searchs the common fields and not all field. 2805 */ 2806struct format_field * 2807pevent_find_common_field(struct event_format *event, const char *name) 2808{ 2809 struct format_field *format; 2810 2811 for (format = event->format.common_fields; 2812 format; format = format->next) { 2813 if (strcmp(format->name, name) == 0) 2814 break; 2815 } 2816 2817 return format; 2818} 2819 2820/** 2821 * pevent_find_field - find a non-common field 2822 * @event: handle for the event 2823 * @name: the name of the non-common field 2824 * 2825 * Returns a non-common field by the given @name. 2826 * This does not search common fields. 2827 */ 2828struct format_field * 2829pevent_find_field(struct event_format *event, const char *name) 2830{ 2831 struct format_field *format; 2832 2833 for (format = event->format.fields; 2834 format; format = format->next) { 2835 if (strcmp(format->name, name) == 0) 2836 break; 2837 } 2838 2839 return format; 2840} 2841 2842/** 2843 * pevent_find_any_field - find any field by name 2844 * @event: handle for the event 2845 * @name: the name of the field 2846 * 2847 * Returns a field by the given @name. 2848 * This searchs the common field names first, then 2849 * the non-common ones if a common one was not found. 2850 */ 2851struct format_field * 2852pevent_find_any_field(struct event_format *event, const char *name) 2853{ 2854 struct format_field *format; 2855 2856 format = pevent_find_common_field(event, name); 2857 if (format) 2858 return format; 2859 return pevent_find_field(event, name); 2860} 2861 2862/** 2863 * pevent_read_number - read a number from data 2864 * @pevent: handle for the pevent 2865 * @ptr: the raw data 2866 * @size: the size of the data that holds the number 2867 * 2868 * Returns the number (converted to host) from the 2869 * raw data. 2870 */ 2871unsigned long long pevent_read_number(struct pevent *pevent, 2872 const void *ptr, int size) 2873{ 2874 switch (size) { 2875 case 1: 2876 return *(unsigned char *)ptr; 2877 case 2: 2878 return data2host2(pevent, ptr); 2879 case 4: 2880 return data2host4(pevent, ptr); 2881 case 8: 2882 return data2host8(pevent, ptr); 2883 default: 2884 /* BUG! */ 2885 return 0; 2886 } 2887} 2888 2889/** 2890 * pevent_read_number_field - read a number from data 2891 * @field: a handle to the field 2892 * @data: the raw data to read 2893 * @value: the value to place the number in 2894 * 2895 * Reads raw data according to a field offset and size, 2896 * and translates it into @value. 2897 * 2898 * Returns 0 on success, -1 otherwise. 2899 */ 2900int pevent_read_number_field(struct format_field *field, const void *data, 2901 unsigned long long *value) 2902{ 2903 if (!field) 2904 return -1; 2905 switch (field->size) { 2906 case 1: 2907 case 2: 2908 case 4: 2909 case 8: 2910 *value = pevent_read_number(field->event->pevent, 2911 data + field->offset, field->size); 2912 return 0; 2913 default: 2914 return -1; 2915 } 2916} 2917 2918static int get_common_info(struct pevent *pevent, 2919 const char *type, int *offset, int *size) 2920{ 2921 struct event_format *event; 2922 struct format_field *field; 2923 2924 /* 2925 * All events should have the same common elements. 2926 * Pick any event to find where the type is; 2927 */ 2928 if (!pevent->events) 2929 die("no event_list!"); 2930 2931 event = pevent->events[0]; 2932 field = pevent_find_common_field(event, type); 2933 if (!field) 2934 return -1; 2935 2936 *offset = field->offset; 2937 *size = field->size; 2938 2939 return 0; 2940} 2941 2942static int __parse_common(struct pevent *pevent, void *data, 2943 int *size, int *offset, const char *name) 2944{ 2945 int ret; 2946 2947 if (!*size) { 2948 ret = get_common_info(pevent, name, offset, size); 2949 if (ret < 0) 2950 return ret; 2951 } 2952 return pevent_read_number(pevent, data + *offset, *size); 2953} 2954 2955static int trace_parse_common_type(struct pevent *pevent, void *data) 2956{ 2957 return __parse_common(pevent, data, 2958 &pevent->type_size, &pevent->type_offset, 2959 "common_type"); 2960} 2961 2962static int parse_common_pid(struct pevent *pevent, void *data) 2963{ 2964 return __parse_common(pevent, data, 2965 &pevent->pid_size, &pevent->pid_offset, 2966 "common_pid"); 2967} 2968 2969static int parse_common_pc(struct pevent *pevent, void *data) 2970{ 2971 return __parse_common(pevent, data, 2972 &pevent->pc_size, &pevent->pc_offset, 2973 "common_preempt_count"); 2974} 2975 2976static int parse_common_flags(struct pevent *pevent, void *data) 2977{ 2978 return __parse_common(pevent, data, 2979 &pevent->flags_size, &pevent->flags_offset, 2980 "common_flags"); 2981} 2982 2983static int parse_common_lock_depth(struct pevent *pevent, void *data) 2984{ 2985 return __parse_common(pevent, data, 2986 &pevent->ld_size, &pevent->ld_offset, 2987 "common_lock_depth"); 2988} 2989 2990static int parse_common_migrate_disable(struct pevent *pevent, void *data) 2991{ 2992 return __parse_common(pevent, data, 2993 &pevent->ld_size, &pevent->ld_offset, 2994 "common_migrate_disable"); 2995} 2996 2997static int events_id_cmp(const void *a, const void *b); 2998 2999/** 3000 * pevent_find_event - find an event by given id 3001 * @pevent: a handle to the pevent 3002 * @id: the id of the event 3003 * 3004 * Returns an event that has a given @id. 3005 */ 3006struct event_format *pevent_find_event(struct pevent *pevent, int id) 3007{ 3008 struct event_format **eventptr; 3009 struct event_format key; 3010 struct event_format *pkey = &key; 3011 3012 /* Check cache first */ 3013 if (pevent->last_event && pevent->last_event->id == id) 3014 return pevent->last_event; 3015 3016 key.id = id; 3017 3018 eventptr = bsearch(&pkey, pevent->events, pevent->nr_events, 3019 sizeof(*pevent->events), events_id_cmp); 3020 3021 if (eventptr) { 3022 pevent->last_event = *eventptr; 3023 return *eventptr; 3024 } 3025 3026 return NULL; 3027} 3028 3029/** 3030 * pevent_find_event_by_name - find an event by given name 3031 * @pevent: a handle to the pevent 3032 * @sys: the system name to search for 3033 * @name: the name of the event to search for 3034 * 3035 * This returns an event with a given @name and under the system 3036 * @sys. If @sys is NULL the first event with @name is returned. 3037 */ 3038struct event_format * 3039pevent_find_event_by_name(struct pevent *pevent, 3040 const char *sys, const char *name) 3041{ 3042 struct event_format *event; 3043 int i; 3044 3045 if (pevent->last_event && 3046 strcmp(pevent->last_event->name, name) == 0 && 3047 (!sys || strcmp(pevent->last_event->system, sys) == 0)) 3048 return pevent->last_event; 3049 3050 for (i = 0; i < pevent->nr_events; i++) { 3051 event = pevent->events[i]; 3052 if (strcmp(event->name, name) == 0) { 3053 if (!sys) 3054 break; 3055 if (strcmp(event->system, sys) == 0) 3056 break; 3057 } 3058 } 3059 if (i == pevent->nr_events) 3060 event = NULL; 3061 3062 pevent->last_event = event; 3063 return event; 3064} 3065 3066static unsigned long long 3067eval_num_arg(void *data, int size, struct event_format *event, struct print_arg *arg) 3068{ 3069 struct pevent *pevent = event->pevent; 3070 unsigned long long val = 0; 3071 unsigned long long left, right; 3072 struct print_arg *typearg = NULL; 3073 struct print_arg *larg; 3074 unsigned long offset; 3075 unsigned int field_size; 3076 3077 switch (arg->type) { 3078 case PRINT_NULL: 3079 /* ?? */ 3080 return 0; 3081 case PRINT_ATOM: 3082 return strtoull(arg->atom.atom, NULL, 0); 3083 case PRINT_FIELD: 3084 if (!arg->field.field) { 3085 arg->field.field = pevent_find_any_field(event, arg->field.name); 3086 if (!arg->field.field) 3087 die("field %s not found", arg->field.name); 3088 } 3089 /* must be a number */ 3090 val = pevent_read_number(pevent, data + arg->field.field->offset, 3091 arg->field.field->size); 3092 break; 3093 case PRINT_FLAGS: 3094 case PRINT_SYMBOL: 3095 case PRINT_HEX: 3096 break; 3097 case PRINT_TYPE: 3098 val = eval_num_arg(data, size, event, arg->typecast.item); 3099 return eval_type(val, arg, 0); 3100 case PRINT_STRING: 3101 case PRINT_BSTRING: 3102 return 0; 3103 case PRINT_FUNC: { 3104 struct trace_seq s; 3105 trace_seq_init(&s); 3106 val = process_defined_func(&s, data, size, event, arg); 3107 trace_seq_destroy(&s); 3108 return val; 3109 } 3110 case PRINT_OP: 3111 if (strcmp(arg->op.op, "[") == 0) { 3112 /* 3113 * Arrays are special, since we don't want 3114 * to read the arg as is. 3115 */ 3116 right = eval_num_arg(data, size, event, arg->op.right); 3117 3118 /* handle typecasts */ 3119 larg = arg->op.left; 3120 while (larg->type == PRINT_TYPE) { 3121 if (!typearg) 3122 typearg = larg; 3123 larg = larg->typecast.item; 3124 } 3125 3126 /* Default to long size */ 3127 field_size = pevent->long_size; 3128 3129 switch (larg->type) { 3130 case PRINT_DYNAMIC_ARRAY: 3131 offset = pevent_read_number(pevent, 3132 data + larg->dynarray.field->offset, 3133 larg->dynarray.field->size); 3134 if (larg->dynarray.field->elementsize) 3135 field_size = larg->dynarray.field->elementsize; 3136 /* 3137 * The actual length of the dynamic array is stored 3138 * in the top half of the field, and the offset 3139 * is in the bottom half of the 32 bit field. 3140 */ 3141 offset &= 0xffff; 3142 offset += right; 3143 break; 3144 case PRINT_FIELD: 3145 if (!larg->field.field) { 3146 larg->field.field = 3147 pevent_find_any_field(event, larg->field.name); 3148 if (!larg->field.field) 3149 die("field %s not found", larg->field.name); 3150 } 3151 field_size = larg->field.field->elementsize; 3152 offset = larg->field.field->offset + 3153 right * larg->field.field->elementsize; 3154 break; 3155 default: 3156 goto default_op; /* oops, all bets off */ 3157 } 3158 val = pevent_read_number(pevent, 3159 data + offset, field_size); 3160 if (typearg) 3161 val = eval_type(val, typearg, 1); 3162 break; 3163 } else if (strcmp(arg->op.op, "?") == 0) { 3164 left = eval_num_arg(data, size, event, arg->op.left); 3165 arg = arg->op.right; 3166 if (left) 3167 val = eval_num_arg(data, size, event, arg->op.left); 3168 else 3169 val = eval_num_arg(data, size, event, arg->op.right); 3170 break; 3171 } 3172 default_op: 3173 left = eval_num_arg(data, size, event, arg->op.left); 3174 right = eval_num_arg(data, size, event, arg->op.right); 3175 switch (arg->op.op[0]) { 3176 case '!': 3177 switch (arg->op.op[1]) { 3178 case 0: 3179 val = !right; 3180 break; 3181 case '=': 3182 val = left != right; 3183 break; 3184 default: 3185 die("unknown op '%s'", arg->op.op); 3186 } 3187 break; 3188 case '~': 3189 val = ~right; 3190 break; 3191 case '|': 3192 if (arg->op.op[1]) 3193 val = left || right; 3194 else 3195 val = left | right; 3196 break; 3197 case '&': 3198 if (arg->op.op[1]) 3199 val = left && right; 3200 else 3201 val = left & right; 3202 break; 3203 case '<': 3204 switch (arg->op.op[1]) { 3205 case 0: 3206 val = left < right; 3207 break; 3208 case '<': 3209 val = left << right; 3210 break; 3211 case '=': 3212 val = left <= right; 3213 break; 3214 default: 3215 die("unknown op '%s'", arg->op.op); 3216 } 3217 break; 3218 case '>': 3219 switch (arg->op.op[1]) { 3220 case 0: 3221 val = left > right; 3222 break; 3223 case '>': 3224 val = left >> right; 3225 break; 3226 case '=': 3227 val = left >= right; 3228 break; 3229 default: 3230 die("unknown op '%s'", arg->op.op); 3231 } 3232 break; 3233 case '=': 3234 if (arg->op.op[1] != '=') 3235 die("unknown op '%s'", arg->op.op); 3236 val = left == right; 3237 break; 3238 case '-': 3239 val = left - right; 3240 break; 3241 case '+': 3242 val = left + right; 3243 break; 3244 case '/': 3245 val = left / right; 3246 break; 3247 case '*': 3248 val = left * right; 3249 break; 3250 default: 3251 die("unknown op '%s'", arg->op.op); 3252 } 3253 break; 3254 default: /* not sure what to do there */ 3255 return 0; 3256 } 3257 return val; 3258} 3259 3260struct flag { 3261 const char *name; 3262 unsigned long long value; 3263}; 3264 3265static const struct flag flags[] = { 3266 { "HI_SOFTIRQ", 0 }, 3267 { "TIMER_SOFTIRQ", 1 }, 3268 { "NET_TX_SOFTIRQ", 2 }, 3269 { "NET_RX_SOFTIRQ", 3 }, 3270 { "BLOCK_SOFTIRQ", 4 }, 3271 { "BLOCK_IOPOLL_SOFTIRQ", 5 }, 3272 { "TASKLET_SOFTIRQ", 6 }, 3273 { "SCHED_SOFTIRQ", 7 }, 3274 { "HRTIMER_SOFTIRQ", 8 }, 3275 { "RCU_SOFTIRQ", 9 }, 3276 3277 { "HRTIMER_NORESTART", 0 }, 3278 { "HRTIMER_RESTART", 1 }, 3279}; 3280 3281static unsigned long long eval_flag(const char *flag) 3282{ 3283 int i; 3284 3285 /* 3286 * Some flags in the format files do not get converted. 3287 * If the flag is not numeric, see if it is something that 3288 * we already know about. 3289 */ 3290 if (isdigit(flag[0])) 3291 return strtoull(flag, NULL, 0); 3292 3293 for (i = 0; i < (int)(sizeof(flags)/sizeof(flags[0])); i++) 3294 if (strcmp(flags[i].name, flag) == 0) 3295 return flags[i].value; 3296 3297 return 0; 3298} 3299 3300static void print_str_to_seq(struct trace_seq *s, const char *format, 3301 int len_arg, const char *str) 3302{ 3303 if (len_arg >= 0) 3304 trace_seq_printf(s, format, len_arg, str); 3305 else 3306 trace_seq_printf(s, format, str); 3307} 3308 3309static void print_str_arg(struct trace_seq *s, void *data, int size, 3310 struct event_format *event, const char *format, 3311 int len_arg, struct print_arg *arg) 3312{ 3313 struct pevent *pevent = event->pevent; 3314 struct print_flag_sym *flag; 3315 struct format_field *field; 3316 unsigned long long val, fval; 3317 unsigned long addr; 3318 char *str; 3319 unsigned char *hex; 3320 int print; 3321 int i, len; 3322 3323 switch (arg->type) { 3324 case PRINT_NULL: 3325 /* ?? */ 3326 return; 3327 case PRINT_ATOM: 3328 print_str_to_seq(s, format, len_arg, arg->atom.atom); 3329 return; 3330 case PRINT_FIELD: 3331 field = arg->field.field; 3332 if (!field) { 3333 field = pevent_find_any_field(event, arg->field.name); 3334 if (!field) 3335 die("field %s not found", arg->field.name); 3336 arg->field.field = field; 3337 } 3338 /* Zero sized fields, mean the rest of the data */ 3339 len = field->size ? : size - field->offset; 3340 3341 /* 3342 * Some events pass in pointers. If this is not an array 3343 * and the size is the same as long_size, assume that it 3344 * is a pointer. 3345 */ 3346 if (!(field->flags & FIELD_IS_ARRAY) && 3347 field->size == pevent->long_size) { 3348 addr = *(unsigned long *)(data + field->offset); 3349 trace_seq_printf(s, "%lx", addr); 3350 break; 3351 } 3352 str = malloc_or_die(len + 1); 3353 memcpy(str, data + field->offset, len); 3354 str[len] = 0; 3355 print_str_to_seq(s, format, len_arg, str); 3356 free(str); 3357 break; 3358 case PRINT_FLAGS: 3359 val = eval_num_arg(data, size, event, arg->flags.field); 3360 print = 0; 3361 for (flag = arg->flags.flags; flag; flag = flag->next) { 3362 fval = eval_flag(flag->value); 3363 if (!val && !fval) { 3364 print_str_to_seq(s, format, len_arg, flag->str); 3365 break; 3366 } 3367 if (fval && (val & fval) == fval) { 3368 if (print && arg->flags.delim) 3369 trace_seq_puts(s, arg->flags.delim); 3370 print_str_to_seq(s, format, len_arg, flag->str); 3371 print = 1; 3372 val &= ~fval; 3373 } 3374 } 3375 break; 3376 case PRINT_SYMBOL: 3377 val = eval_num_arg(data, size, event, arg->symbol.field); 3378 for (flag = arg->symbol.symbols; flag; flag = flag->next) { 3379 fval = eval_flag(flag->value); 3380 if (val == fval) { 3381 print_str_to_seq(s, format, len_arg, flag->str); 3382 break; 3383 } 3384 } 3385 break; 3386 case PRINT_HEX: 3387 field = arg->hex.field->field.field; 3388 if (!field) { 3389 str = arg->hex.field->field.name; 3390 field = pevent_find_any_field(event, str); 3391 if (!field) 3392 die("field %s not found", str); 3393 arg->hex.field->field.field = field; 3394 } 3395 hex = data + field->offset; 3396 len = eval_num_arg(data, size, event, arg->hex.size); 3397 for (i = 0; i < len; i++) { 3398 if (i) 3399 trace_seq_putc(s, ' '); 3400 trace_seq_printf(s, "%02x", hex[i]); 3401 } 3402 break; 3403 3404 case PRINT_TYPE: 3405 break; 3406 case PRINT_STRING: { 3407 int str_offset; 3408 3409 if (arg->string.offset == -1) { 3410 struct format_field *f; 3411 3412 f = pevent_find_any_field(event, arg->string.string); 3413 arg->string.offset = f->offset; 3414 } 3415 str_offset = data2host4(pevent, data + arg->string.offset); 3416 str_offset &= 0xffff; 3417 print_str_to_seq(s, format, len_arg, ((char *)data) + str_offset); 3418 break; 3419 } 3420 case PRINT_BSTRING: 3421 print_str_to_seq(s, format, len_arg, arg->string.string); 3422 break; 3423 case PRINT_OP: 3424 /* 3425 * The only op for string should be ? : 3426 */ 3427 if (arg->op.op[0] != '?') 3428 return; 3429 val = eval_num_arg(data, size, event, arg->op.left); 3430 if (val) 3431 print_str_arg(s, data, size, event, 3432 format, len_arg, arg->op.right->op.left); 3433 else 3434 print_str_arg(s, data, size, event, 3435 format, len_arg, arg->op.right->op.right); 3436 break; 3437 case PRINT_FUNC: 3438 process_defined_func(s, data, size, event, arg); 3439 break; 3440 default: 3441 /* well... */ 3442 break; 3443 } 3444} 3445 3446static unsigned long long 3447process_defined_func(struct trace_seq *s, void *data, int size, 3448 struct event_format *event, struct print_arg *arg) 3449{ 3450 struct pevent_function_handler *func_handle = arg->func.func; 3451 struct pevent_func_params *param; 3452 unsigned long long *args; 3453 unsigned long long ret; 3454 struct print_arg *farg; 3455 struct trace_seq str; 3456 struct save_str { 3457 struct save_str *next; 3458 char *str; 3459 } *strings = NULL, *string; 3460 int i; 3461 3462 if (!func_handle->nr_args) { 3463 ret = (*func_handle->func)(s, NULL); 3464 goto out; 3465 } 3466 3467 farg = arg->func.args; 3468 param = func_handle->params; 3469 3470 args = malloc_or_die(sizeof(*args) * func_handle->nr_args); 3471 for (i = 0; i < func_handle->nr_args; i++) { 3472 switch (param->type) { 3473 case PEVENT_FUNC_ARG_INT: 3474 case PEVENT_FUNC_ARG_LONG: 3475 case PEVENT_FUNC_ARG_PTR: 3476 args[i] = eval_num_arg(data, size, event, farg); 3477 break; 3478 case PEVENT_FUNC_ARG_STRING: 3479 trace_seq_init(&str); 3480 print_str_arg(&str, data, size, event, "%s", -1, farg); 3481 trace_seq_terminate(&str); 3482 string = malloc_or_die(sizeof(*string)); 3483 string->next = strings; 3484 string->str = strdup(str.buffer); 3485 if (!string->str) 3486 die("malloc str"); 3487 3488 args[i] = (unsigned long long)string->str; 3489 strings = string; 3490 trace_seq_destroy(&str); 3491 break; 3492 default: 3493 /* 3494 * Something went totally wrong, this is not 3495 * an input error, something in this code broke. 3496 */ 3497 die("Unexpected end of arguments\n"); 3498 break; 3499 } 3500 farg = farg->next; 3501 param = param->next; 3502 } 3503 3504 ret = (*func_handle->func)(s, args); 3505 free(args); 3506 while (strings) { 3507 string = strings; 3508 strings = string->next; 3509 free(string->str); 3510 free(string); 3511 } 3512 3513 out: 3514 /* TBD : handle return type here */ 3515 return ret; 3516} 3517 3518static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struct event_format *event) 3519{ 3520 struct pevent *pevent = event->pevent; 3521 struct format_field *field, *ip_field; 3522 struct print_arg *args, *arg, **next; 3523 unsigned long long ip, val; 3524 char *ptr; 3525 void *bptr; 3526 int vsize; 3527 3528 field = pevent->bprint_buf_field; 3529 ip_field = pevent->bprint_ip_field; 3530 3531 if (!field) { 3532 field = pevent_find_field(event, "buf"); 3533 if (!field) 3534 die("can't find buffer field for binary printk"); 3535 ip_field = pevent_find_field(event, "ip"); 3536 if (!ip_field) 3537 die("can't find ip field for binary printk"); 3538 pevent->bprint_buf_field = field; 3539 pevent->bprint_ip_field = ip_field; 3540 } 3541 3542 ip = pevent_read_number(pevent, data + ip_field->offset, ip_field->size); 3543 3544 /* 3545 * The first arg is the IP pointer. 3546 */ 3547 args = alloc_arg(); 3548 arg = args; 3549 arg->next = NULL; 3550 next = &arg->next; 3551 3552 arg->type = PRINT_ATOM; 3553 arg->atom.atom = malloc_or_die(32); 3554 sprintf(arg->atom.atom, "%lld", ip); 3555 3556 /* skip the first "%pf : " */ 3557 for (ptr = fmt + 6, bptr = data + field->offset; 3558 bptr < data + size && *ptr; ptr++) { 3559 int ls = 0; 3560 3561 if (*ptr == '%') { 3562 process_again: 3563 ptr++; 3564 switch (*ptr) { 3565 case '%': 3566 break; 3567 case 'l': 3568 ls++; 3569 goto process_again; 3570 case 'L': 3571 ls = 2; 3572 goto process_again; 3573 case '0' ... '9': 3574 goto process_again; 3575 case '.': 3576 goto process_again; 3577 case 'p': 3578 ls = 1; 3579 /* fall through */ 3580 case 'd': 3581 case 'u': 3582 case 'x': 3583 case 'i': 3584 switch (ls) { 3585 case 0: 3586 vsize = 4; 3587 break; 3588 case 1: 3589 vsize = pevent->long_size; 3590 break; 3591 case 2: 3592 vsize = 8; 3593 break; 3594 default: 3595 vsize = ls; /* ? */ 3596 break; 3597 } 3598 /* fall through */ 3599 case '*': 3600 if (*ptr == '*') 3601 vsize = 4; 3602 3603 /* the pointers are always 4 bytes aligned */ 3604 bptr = (void *)(((unsigned long)bptr + 3) & 3605 ~3); 3606 val = pevent_read_number(pevent, bptr, vsize); 3607 bptr += vsize; 3608 arg = alloc_arg(); 3609 arg->next = NULL; 3610 arg->type = PRINT_ATOM; 3611 arg->atom.atom = malloc_or_die(32); 3612 sprintf(arg->atom.atom, "%lld", val); 3613 *next = arg; 3614 next = &arg->next; 3615 /* 3616 * The '*' case means that an arg is used as the length. 3617 * We need to continue to figure out for what. 3618 */ 3619 if (*ptr == '*') 3620 goto process_again; 3621 3622 break; 3623 case 's': 3624 arg = alloc_arg(); 3625 arg->next = NULL; 3626 arg->type = PRINT_BSTRING; 3627 arg->string.string = strdup(bptr); 3628 if (!arg->string.string) 3629 break; 3630 bptr += strlen(bptr) + 1; 3631 *next = arg; 3632 next = &arg->next; 3633 default: 3634 break; 3635 } 3636 } 3637 } 3638 3639 return args; 3640} 3641 3642static void free_args(struct print_arg *args) 3643{ 3644 struct print_arg *next; 3645 3646 while (args) { 3647 next = args->next; 3648 3649 free_arg(args); 3650 args = next; 3651 } 3652} 3653 3654static char * 3655get_bprint_format(void *data, int size __unused, struct event_format *event) 3656{ 3657 struct pevent *pevent = event->pevent; 3658 unsigned long long addr; 3659 struct format_field *field; 3660 struct printk_map *printk; 3661 char *format; 3662 char *p; 3663 3664 field = pevent->bprint_fmt_field; 3665 3666 if (!field) { 3667 field = pevent_find_field(event, "fmt"); 3668 if (!field) 3669 die("can't find format field for binary printk"); 3670 pevent->bprint_fmt_field = field; 3671 } 3672 3673 addr = pevent_read_number(pevent, data + field->offset, field->size); 3674 3675 printk = find_printk(pevent, addr); 3676 if (!printk) { 3677 format = malloc_or_die(45); 3678 sprintf(format, "%%pf : (NO FORMAT FOUND at %llx)\n", 3679 addr); 3680 return format; 3681 } 3682 3683 p = printk->printk; 3684 /* Remove any quotes. */ 3685 if (*p == '"') 3686 p++; 3687 format = malloc_or_die(strlen(p) + 10); 3688 sprintf(format, "%s : %s", "%pf", p); 3689 /* remove ending quotes and new line since we will add one too */ 3690 p = format + strlen(format) - 1; 3691 if (*p == '"') 3692 *p = 0; 3693 3694 p -= 2; 3695 if (strcmp(p, "\\n") == 0) 3696 *p = 0; 3697 3698 return format; 3699} 3700 3701static void print_mac_arg(struct trace_seq *s, int mac, void *data, int size, 3702 struct event_format *event, struct print_arg *arg) 3703{ 3704 unsigned char *buf; 3705 char *fmt = "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x"; 3706 3707 if (arg->type == PRINT_FUNC) { 3708 process_defined_func(s, data, size, event, arg); 3709 return; 3710 } 3711 3712 if (arg->type != PRINT_FIELD) { 3713 trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", 3714 arg->type); 3715 return; 3716 } 3717 3718 if (mac == 'm') 3719 fmt = "%.2x%.2x%.2x%.2x%.2x%.2x"; 3720 if (!arg->field.field) { 3721 arg->field.field = 3722 pevent_find_any_field(event, arg->field.name); 3723 if (!arg->field.field) 3724 die("field %s not found", arg->field.name); 3725 } 3726 if (arg->field.field->size != 6) { 3727 trace_seq_printf(s, "INVALIDMAC"); 3728 return; 3729 } 3730 buf = data + arg->field.field->offset; 3731 trace_seq_printf(s, fmt, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); 3732} 3733 3734static int is_printable_array(char *p, unsigned int len) 3735{ 3736 unsigned int i; 3737 3738 for (i = 0; i < len && p[i]; i++) 3739 if (!isprint(p[i])) 3740 return 0; 3741 return 1; 3742} 3743 3744static void print_event_fields(struct trace_seq *s, void *data, int size, 3745 struct event_format *event) 3746{ 3747 struct format_field *field; 3748 unsigned long long val; 3749 unsigned int offset, len, i; 3750 3751 field = event->format.fields; 3752 while (field) { 3753 trace_seq_printf(s, " %s=", field->name); 3754 if (field->flags & FIELD_IS_ARRAY) { 3755 offset = field->offset; 3756 len = field->size; 3757 if (field->flags & FIELD_IS_DYNAMIC) { 3758 val = pevent_read_number(event->pevent, data + offset, len); 3759 offset = val; 3760 len = offset >> 16; 3761 offset &= 0xffff; 3762 } 3763 if (field->flags & FIELD_IS_STRING && 3764 is_printable_array(data + offset, len)) { 3765 trace_seq_printf(s, "%s", (char *)data + offset); 3766 } else { 3767 trace_seq_puts(s, "ARRAY["); 3768 for (i = 0; i < len; i++) { 3769 if (i) 3770 trace_seq_puts(s, ", "); 3771 trace_seq_printf(s, "%02x", 3772 *((unsigned char *)data + offset + i)); 3773 } 3774 trace_seq_putc(s, ']'); 3775 field->flags &= ~FIELD_IS_STRING; 3776 } 3777 } else { 3778 val = pevent_read_number(event->pevent, data + field->offset, 3779 field->size); 3780 if (field->flags & FIELD_IS_POINTER) { 3781 trace_seq_printf(s, "0x%llx", val); 3782 } else if (field->flags & FIELD_IS_SIGNED) { 3783 switch (field->size) { 3784 case 4: 3785 /* 3786 * If field is long then print it in hex. 3787 * A long usually stores pointers. 3788 */ 3789 if (field->flags & FIELD_IS_LONG) 3790 trace_seq_printf(s, "0x%x", (int)val); 3791 else 3792 trace_seq_printf(s, "%d", (int)val); 3793 break; 3794 case 2: 3795 trace_seq_printf(s, "%2d", (short)val); 3796 break; 3797 case 1: 3798 trace_seq_printf(s, "%1d", (char)val); 3799 break; 3800 default: 3801 trace_seq_printf(s, "%lld", val); 3802 } 3803 } else { 3804 if (field->flags & FIELD_IS_LONG) 3805 trace_seq_printf(s, "0x%llx", val); 3806 else 3807 trace_seq_printf(s, "%llu", val); 3808 } 3809 } 3810 field = field->next; 3811 } 3812} 3813 3814static void pretty_print(struct trace_seq *s, void *data, int size, struct event_format *event) 3815{ 3816 struct pevent *pevent = event->pevent; 3817 struct print_fmt *print_fmt = &event->print_fmt; 3818 struct print_arg *arg = print_fmt->args; 3819 struct print_arg *args = NULL; 3820 const char *ptr = print_fmt->format; 3821 unsigned long long val; 3822 struct func_map *func; 3823 const char *saveptr; 3824 char *bprint_fmt = NULL; 3825 char format[32]; 3826 int show_func; 3827 int len_as_arg; 3828 int len_arg; 3829 int len; 3830 int ls; 3831 3832 if (event->flags & EVENT_FL_FAILED) { 3833 trace_seq_printf(s, "[FAILED TO PARSE]"); 3834 print_event_fields(s, data, size, event); 3835 return; 3836 } 3837 3838 if (event->flags & EVENT_FL_ISBPRINT) { 3839 bprint_fmt = get_bprint_format(data, size, event); 3840 args = make_bprint_args(bprint_fmt, data, size, event); 3841 arg = args; 3842 ptr = bprint_fmt; 3843 } 3844 3845 for (; *ptr; ptr++) { 3846 ls = 0; 3847 if (*ptr == '\\') { 3848 ptr++; 3849 switch (*ptr) { 3850 case 'n': 3851 trace_seq_putc(s, '\n'); 3852 break; 3853 case 't': 3854 trace_seq_putc(s, '\t'); 3855 break; 3856 case 'r': 3857 trace_seq_putc(s, '\r'); 3858 break; 3859 case '\\': 3860 trace_seq_putc(s, '\\'); 3861 break; 3862 default: 3863 trace_seq_putc(s, *ptr); 3864 break; 3865 } 3866 3867 } else if (*ptr == '%') { 3868 saveptr = ptr; 3869 show_func = 0; 3870 len_as_arg = 0; 3871 cont_process: 3872 ptr++; 3873 switch (*ptr) { 3874 case '%': 3875 trace_seq_putc(s, '%'); 3876 break; 3877 case '#': 3878 /* FIXME: need to handle properly */ 3879 goto cont_process; 3880 case 'h': 3881 ls--; 3882 goto cont_process; 3883 case 'l': 3884 ls++; 3885 goto cont_process; 3886 case 'L': 3887 ls = 2; 3888 goto cont_process; 3889 case '*': 3890 /* The argument is the length. */ 3891 if (!arg) 3892 die("no argument match"); 3893 len_arg = eval_num_arg(data, size, event, arg); 3894 len_as_arg = 1; 3895 arg = arg->next; 3896 goto cont_process; 3897 case '.': 3898 case 'z': 3899 case 'Z': 3900 case '0' ... '9': 3901 goto cont_process; 3902 case 'p': 3903 if (pevent->long_size == 4) 3904 ls = 1; 3905 else 3906 ls = 2; 3907 3908 if (*(ptr+1) == 'F' || 3909 *(ptr+1) == 'f') { 3910 ptr++; 3911 show_func = *ptr; 3912 } else if (*(ptr+1) == 'M' || *(ptr+1) == 'm') { 3913 print_mac_arg(s, *(ptr+1), data, size, event, arg); 3914 ptr++; 3915 arg = arg->next; 3916 break; 3917 } 3918 3919 /* fall through */ 3920 case 'd': 3921 case 'i': 3922 case 'x': 3923 case 'X': 3924 case 'u': 3925 if (!arg) 3926 die("no argument match"); 3927 3928 len = ((unsigned long)ptr + 1) - 3929 (unsigned long)saveptr; 3930 3931 /* should never happen */ 3932 if (len > 31) 3933 die("bad format!"); 3934 3935 memcpy(format, saveptr, len); 3936 format[len] = 0; 3937 3938 val = eval_num_arg(data, size, event, arg); 3939 arg = arg->next; 3940 3941 if (show_func) { 3942 func = find_func(pevent, val); 3943 if (func) { 3944 trace_seq_puts(s, func->func); 3945 if (show_func == 'F') 3946 trace_seq_printf(s, 3947 "+0x%llx", 3948 val - func->addr); 3949 break; 3950 } 3951 } 3952 if (pevent->long_size == 8 && ls && 3953 sizeof(long) != 8) { 3954 char *p; 3955 3956 ls = 2; 3957 /* make %l into %ll */ 3958 p = strchr(format, 'l'); 3959 if (p) 3960 memmove(p+1, p, strlen(p)+1); 3961 else if (strcmp(format, "%p") == 0) 3962 strcpy(format, "0x%llx"); 3963 } 3964 switch (ls) { 3965 case -2: 3966 if (len_as_arg) 3967 trace_seq_printf(s, format, len_arg, (char)val); 3968 else 3969 trace_seq_printf(s, format, (char)val); 3970 break; 3971 case -1: 3972 if (len_as_arg) 3973 trace_seq_printf(s, format, len_arg, (short)val); 3974 else 3975 trace_seq_printf(s, format, (short)val); 3976 break; 3977 case 0: 3978 if (len_as_arg) 3979 trace_seq_printf(s, format, len_arg, (int)val); 3980 else 3981 trace_seq_printf(s, format, (int)val); 3982 break; 3983 case 1: 3984 if (len_as_arg) 3985 trace_seq_printf(s, format, len_arg, (long)val); 3986 else 3987 trace_seq_printf(s, format, (long)val); 3988 break; 3989 case 2: 3990 if (len_as_arg) 3991 trace_seq_printf(s, format, len_arg, 3992 (long long)val); 3993 else 3994 trace_seq_printf(s, format, (long long)val); 3995 break; 3996 default: 3997 die("bad count (%d)", ls); 3998 } 3999 break; 4000 case 's': 4001 if (!arg) 4002 die("no matching argument"); 4003 4004 len = ((unsigned long)ptr + 1) - 4005 (unsigned long)saveptr; 4006 4007 /* should never happen */ 4008 if (len > 31) 4009 die("bad format!"); 4010 4011 memcpy(format, saveptr, len); 4012 format[len] = 0; 4013 if (!len_as_arg) 4014 len_arg = -1; 4015 print_str_arg(s, data, size, event, 4016 format, len_arg, arg); 4017 arg = arg->next; 4018 break; 4019 default: 4020 trace_seq_printf(s, ">%c<", *ptr); 4021 4022 } 4023 } else 4024 trace_seq_putc(s, *ptr); 4025 } 4026 4027 if (args) { 4028 free_args(args); 4029 free(bprint_fmt); 4030 } 4031} 4032 4033/** 4034 * pevent_data_lat_fmt - parse the data for the latency format 4035 * @pevent: a handle to the pevent 4036 * @s: the trace_seq to write to 4037 * @record: the record to read from 4038 * 4039 * This parses out the Latency format (interrupts disabled, 4040 * need rescheduling, in hard/soft interrupt, preempt count 4041 * and lock depth) and places it into the trace_seq. 4042 */ 4043void pevent_data_lat_fmt(struct pevent *pevent, 4044 struct trace_seq *s, struct pevent_record *record) 4045{ 4046 static int check_lock_depth = 1; 4047 static int check_migrate_disable = 1; 4048 static int lock_depth_exists; 4049 static int migrate_disable_exists; 4050 unsigned int lat_flags; 4051 unsigned int pc; 4052 int lock_depth; 4053 int migrate_disable; 4054 int hardirq; 4055 int softirq; 4056 void *data = record->data; 4057 4058 lat_flags = parse_common_flags(pevent, data); 4059 pc = parse_common_pc(pevent, data); 4060 /* lock_depth may not always exist */ 4061 if (lock_depth_exists) 4062 lock_depth = parse_common_lock_depth(pevent, data); 4063 else if (check_lock_depth) { 4064 lock_depth = parse_common_lock_depth(pevent, data); 4065 if (lock_depth < 0) 4066 check_lock_depth = 0; 4067 else 4068 lock_depth_exists = 1; 4069 } 4070 4071 /* migrate_disable may not always exist */ 4072 if (migrate_disable_exists) 4073 migrate_disable = parse_common_migrate_disable(pevent, data); 4074 else if (check_migrate_disable) { 4075 migrate_disable = parse_common_migrate_disable(pevent, data); 4076 if (migrate_disable < 0) 4077 check_migrate_disable = 0; 4078 else 4079 migrate_disable_exists = 1; 4080 } 4081 4082 hardirq = lat_flags & TRACE_FLAG_HARDIRQ; 4083 softirq = lat_flags & TRACE_FLAG_SOFTIRQ; 4084 4085 trace_seq_printf(s, "%c%c%c", 4086 (lat_flags & TRACE_FLAG_IRQS_OFF) ? 'd' : 4087 (lat_flags & TRACE_FLAG_IRQS_NOSUPPORT) ? 4088 'X' : '.', 4089 (lat_flags & TRACE_FLAG_NEED_RESCHED) ? 4090 'N' : '.', 4091 (hardirq && softirq) ? 'H' : 4092 hardirq ? 'h' : softirq ? 's' : '.'); 4093 4094 if (pc) 4095 trace_seq_printf(s, "%x", pc); 4096 else 4097 trace_seq_putc(s, '.'); 4098 4099 if (migrate_disable_exists) { 4100 if (migrate_disable < 0) 4101 trace_seq_putc(s, '.'); 4102 else 4103 trace_seq_printf(s, "%d", migrate_disable); 4104 } 4105 4106 if (lock_depth_exists) { 4107 if (lock_depth < 0) 4108 trace_seq_putc(s, '.'); 4109 else 4110 trace_seq_printf(s, "%d", lock_depth); 4111 } 4112 4113 trace_seq_terminate(s); 4114} 4115 4116/** 4117 * pevent_data_type - parse out the given event type 4118 * @pevent: a handle to the pevent 4119 * @rec: the record to read from 4120 * 4121 * This returns the event id from the @rec. 4122 */ 4123int pevent_data_type(struct pevent *pevent, struct pevent_record *rec) 4124{ 4125 return trace_parse_common_type(pevent, rec->data); 4126} 4127 4128/** 4129 * pevent_data_event_from_type - find the event by a given type 4130 * @pevent: a handle to the pevent 4131 * @type: the type of the event. 4132 * 4133 * This returns the event form a given @type; 4134 */ 4135struct event_format *pevent_data_event_from_type(struct pevent *pevent, int type) 4136{ 4137 return pevent_find_event(pevent, type); 4138} 4139 4140/** 4141 * pevent_data_pid - parse the PID from raw data 4142 * @pevent: a handle to the pevent 4143 * @rec: the record to parse 4144 * 4145 * This returns the PID from a raw data. 4146 */ 4147int pevent_data_pid(struct pevent *pevent, struct pevent_record *rec) 4148{ 4149 return parse_common_pid(pevent, rec->data); 4150} 4151 4152/** 4153 * pevent_data_comm_from_pid - return the command line from PID 4154 * @pevent: a handle to the pevent 4155 * @pid: the PID of the task to search for 4156 * 4157 * This returns a pointer to the command line that has the given 4158 * @pid. 4159 */ 4160const char *pevent_data_comm_from_pid(struct pevent *pevent, int pid) 4161{ 4162 const char *comm; 4163 4164 comm = find_cmdline(pevent, pid); 4165 return comm; 4166} 4167 4168/** 4169 * pevent_data_comm_from_pid - parse the data into the print format 4170 * @s: the trace_seq to write to 4171 * @event: the handle to the event 4172 * @record: the record to read from 4173 * 4174 * This parses the raw @data using the given @event information and 4175 * writes the print format into the trace_seq. 4176 */ 4177void pevent_event_info(struct trace_seq *s, struct event_format *event, 4178 struct pevent_record *record) 4179{ 4180 int print_pretty = 1; 4181 4182 if (event->pevent->print_raw) 4183 print_event_fields(s, record->data, record->size, event); 4184 else { 4185 4186 if (event->handler) 4187 print_pretty = event->handler(s, record, event, 4188 event->context); 4189 4190 if (print_pretty) 4191 pretty_print(s, record->data, record->size, event); 4192 } 4193 4194 trace_seq_terminate(s); 4195} 4196 4197void pevent_print_event(struct pevent *pevent, struct trace_seq *s, 4198 struct pevent_record *record) 4199{ 4200 static char *spaces = " "; /* 20 spaces */ 4201 struct event_format *event; 4202 unsigned long secs; 4203 unsigned long usecs; 4204 unsigned long nsecs; 4205 const char *comm; 4206 void *data = record->data; 4207 int type; 4208 int pid; 4209 int len; 4210 int p; 4211 4212 secs = record->ts / NSECS_PER_SEC; 4213 nsecs = record->ts - secs * NSECS_PER_SEC; 4214 4215 if (record->size < 0) { 4216 do_warning("ug! negative record size %d", record->size); 4217 return; 4218 } 4219 4220 type = trace_parse_common_type(pevent, data); 4221 4222 event = pevent_find_event(pevent, type); 4223 if (!event) { 4224 do_warning("ug! no event found for type %d", type); 4225 return; 4226 } 4227 4228 pid = parse_common_pid(pevent, data); 4229 comm = find_cmdline(pevent, pid); 4230 4231 if (pevent->latency_format) { 4232 trace_seq_printf(s, "%8.8s-%-5d %3d", 4233 comm, pid, record->cpu); 4234 pevent_data_lat_fmt(pevent, s, record); 4235 } else 4236 trace_seq_printf(s, "%16s-%-5d [%03d]", comm, pid, record->cpu); 4237 4238 if (pevent->flags & PEVENT_NSEC_OUTPUT) { 4239 usecs = nsecs; 4240 p = 9; 4241 } else { 4242 usecs = (nsecs + 500) / NSECS_PER_USEC; 4243 p = 6; 4244 } 4245 4246 trace_seq_printf(s, " %5lu.%0*lu: %s: ", secs, p, usecs, event->name); 4247 4248 /* Space out the event names evenly. */ 4249 len = strlen(event->name); 4250 if (len < 20) 4251 trace_seq_printf(s, "%.*s", 20 - len, spaces); 4252 4253 pevent_event_info(s, event, record); 4254} 4255 4256static int events_id_cmp(const void *a, const void *b) 4257{ 4258 struct event_format * const * ea = a; 4259 struct event_format * const * eb = b; 4260 4261 if ((*ea)->id < (*eb)->id) 4262 return -1; 4263 4264 if ((*ea)->id > (*eb)->id) 4265 return 1; 4266 4267 return 0; 4268} 4269 4270static int events_name_cmp(const void *a, const void *b) 4271{ 4272 struct event_format * const * ea = a; 4273 struct event_format * const * eb = b; 4274 int res; 4275 4276 res = strcmp((*ea)->name, (*eb)->name); 4277 if (res) 4278 return res; 4279 4280 res = strcmp((*ea)->system, (*eb)->system); 4281 if (res) 4282 return res; 4283 4284 return events_id_cmp(a, b); 4285} 4286 4287static int events_system_cmp(const void *a, const void *b) 4288{ 4289 struct event_format * const * ea = a; 4290 struct event_format * const * eb = b; 4291 int res; 4292 4293 res = strcmp((*ea)->system, (*eb)->system); 4294 if (res) 4295 return res; 4296 4297 res = strcmp((*ea)->name, (*eb)->name); 4298 if (res) 4299 return res; 4300 4301 return events_id_cmp(a, b); 4302} 4303 4304struct event_format **pevent_list_events(struct pevent *pevent, enum event_sort_type sort_type) 4305{ 4306 struct event_format **events; 4307 int (*sort)(const void *a, const void *b); 4308 4309 events = pevent->sort_events; 4310 4311 if (events && pevent->last_type == sort_type) 4312 return events; 4313 4314 if (!events) { 4315 events = malloc(sizeof(*events) * (pevent->nr_events + 1)); 4316 if (!events) 4317 return NULL; 4318 4319 memcpy(events, pevent->events, sizeof(*events) * pevent->nr_events); 4320 events[pevent->nr_events] = NULL; 4321 4322 pevent->sort_events = events; 4323 4324 /* the internal events are sorted by id */ 4325 if (sort_type == EVENT_SORT_ID) { 4326 pevent->last_type = sort_type; 4327 return events; 4328 } 4329 } 4330 4331 switch (sort_type) { 4332 case EVENT_SORT_ID: 4333 sort = events_id_cmp; 4334 break; 4335 case EVENT_SORT_NAME: 4336 sort = events_name_cmp; 4337 break; 4338 case EVENT_SORT_SYSTEM: 4339 sort = events_system_cmp; 4340 break; 4341 default: 4342 return events; 4343 } 4344 4345 qsort(events, pevent->nr_events, sizeof(*events), sort); 4346 pevent->last_type = sort_type; 4347 4348 return events; 4349} 4350 4351static struct format_field ** 4352get_event_fields(const char *type, const char *name, 4353 int count, struct format_field *list) 4354{ 4355 struct format_field **fields; 4356 struct format_field *field; 4357 int i = 0; 4358 4359 fields = malloc_or_die(sizeof(*fields) * (count + 1)); 4360 for (field = list; field; field = field->next) { 4361 fields[i++] = field; 4362 if (i == count + 1) { 4363 do_warning("event %s has more %s fields than specified", 4364 name, type); 4365 i--; 4366 break; 4367 } 4368 } 4369 4370 if (i != count) 4371 do_warning("event %s has less %s fields than specified", 4372 name, type); 4373 4374 fields[i] = NULL; 4375 4376 return fields; 4377} 4378 4379/** 4380 * pevent_event_common_fields - return a list of common fields for an event 4381 * @event: the event to return the common fields of. 4382 * 4383 * Returns an allocated array of fields. The last item in the array is NULL. 4384 * The array must be freed with free(). 4385 */ 4386struct format_field **pevent_event_common_fields(struct event_format *event) 4387{ 4388 return get_event_fields("common", event->name, 4389 event->format.nr_common, 4390 event->format.common_fields); 4391} 4392 4393/** 4394 * pevent_event_fields - return a list of event specific fields for an event 4395 * @event: the event to return the fields of. 4396 * 4397 * Returns an allocated array of fields. The last item in the array is NULL. 4398 * The array must be freed with free(). 4399 */ 4400struct format_field **pevent_event_fields(struct event_format *event) 4401{ 4402 return get_event_fields("event", event->name, 4403 event->format.nr_fields, 4404 event->format.fields); 4405} 4406 4407static void print_fields(struct trace_seq *s, struct print_flag_sym *field) 4408{ 4409 trace_seq_printf(s, "{ %s, %s }", field->value, field->str); 4410 if (field->next) { 4411 trace_seq_puts(s, ", "); 4412 print_fields(s, field->next); 4413 } 4414} 4415 4416/* for debugging */ 4417static void print_args(struct print_arg *args) 4418{ 4419 int print_paren = 1; 4420 struct trace_seq s; 4421 4422 switch (args->type) { 4423 case PRINT_NULL: 4424 printf("null"); 4425 break; 4426 case PRINT_ATOM: 4427 printf("%s", args->atom.atom); 4428 break; 4429 case PRINT_FIELD: 4430 printf("REC->%s", args->field.name); 4431 break; 4432 case PRINT_FLAGS: 4433 printf("__print_flags("); 4434 print_args(args->flags.field); 4435 printf(", %s, ", args->flags.delim); 4436 trace_seq_init(&s); 4437 print_fields(&s, args->flags.flags); 4438 trace_seq_do_printf(&s); 4439 trace_seq_destroy(&s); 4440 printf(")"); 4441 break; 4442 case PRINT_SYMBOL: 4443 printf("__print_symbolic("); 4444 print_args(args->symbol.field); 4445 printf(", "); 4446 trace_seq_init(&s); 4447 print_fields(&s, args->symbol.symbols); 4448 trace_seq_do_printf(&s); 4449 trace_seq_destroy(&s); 4450 printf(")"); 4451 break; 4452 case PRINT_HEX: 4453 printf("__print_hex("); 4454 print_args(args->hex.field); 4455 printf(", "); 4456 print_args(args->hex.size); 4457 printf(")"); 4458 break; 4459 case PRINT_STRING: 4460 case PRINT_BSTRING: 4461 printf("__get_str(%s)", args->string.string); 4462 break; 4463 case PRINT_TYPE: 4464 printf("(%s)", args->typecast.type); 4465 print_args(args->typecast.item); 4466 break; 4467 case PRINT_OP: 4468 if (strcmp(args->op.op, ":") == 0) 4469 print_paren = 0; 4470 if (print_paren) 4471 printf("("); 4472 print_args(args->op.left); 4473 printf(" %s ", args->op.op); 4474 print_args(args->op.right); 4475 if (print_paren) 4476 printf(")"); 4477 break; 4478 default: 4479 /* we should warn... */ 4480 return; 4481 } 4482 if (args->next) { 4483 printf("\n"); 4484 print_args(args->next); 4485 } 4486} 4487 4488static void parse_header_field(const char *field, 4489 int *offset, int *size, int mandatory) 4490{ 4491 unsigned long long save_input_buf_ptr; 4492 unsigned long long save_input_buf_siz; 4493 char *token; 4494 int type; 4495 4496 save_input_buf_ptr = input_buf_ptr; 4497 save_input_buf_siz = input_buf_siz; 4498 4499 if (read_expected(EVENT_ITEM, "field") < 0) 4500 return; 4501 if (read_expected(EVENT_OP, ":") < 0) 4502 return; 4503 4504 /* type */ 4505 if (read_expect_type(EVENT_ITEM, &token) < 0) 4506 goto fail; 4507 free_token(token); 4508 4509 /* 4510 * If this is not a mandatory field, then test it first. 4511 */ 4512 if (mandatory) { 4513 if (read_expected(EVENT_ITEM, field) < 0) 4514 return; 4515 } else { 4516 if (read_expect_type(EVENT_ITEM, &token) < 0) 4517 goto fail; 4518 if (strcmp(token, field) != 0) 4519 goto discard; 4520 free_token(token); 4521 } 4522 4523 if (read_expected(EVENT_OP, ";") < 0) 4524 return; 4525 if (read_expected(EVENT_ITEM, "offset") < 0) 4526 return; 4527 if (read_expected(EVENT_OP, ":") < 0) 4528 return; 4529 if (read_expect_type(EVENT_ITEM, &token) < 0) 4530 goto fail; 4531 *offset = atoi(token); 4532 free_token(token); 4533 if (read_expected(EVENT_OP, ";") < 0) 4534 return; 4535 if (read_expected(EVENT_ITEM, "size") < 0) 4536 return; 4537 if (read_expected(EVENT_OP, ":") < 0) 4538 return; 4539 if (read_expect_type(EVENT_ITEM, &token) < 0) 4540 goto fail; 4541 *size = atoi(token); 4542 free_token(token); 4543 if (read_expected(EVENT_OP, ";") < 0) 4544 return; 4545 type = read_token(&token); 4546 if (type != EVENT_NEWLINE) { 4547 /* newer versions of the kernel have a "signed" type */ 4548 if (type != EVENT_ITEM) 4549 goto fail; 4550 4551 if (strcmp(token, "signed") != 0) 4552 goto fail; 4553 4554 free_token(token); 4555 4556 if (read_expected(EVENT_OP, ":") < 0) 4557 return; 4558 4559 if (read_expect_type(EVENT_ITEM, &token)) 4560 goto fail; 4561 4562 free_token(token); 4563 if (read_expected(EVENT_OP, ";") < 0) 4564 return; 4565 4566 if (read_expect_type(EVENT_NEWLINE, &token)) 4567 goto fail; 4568 } 4569 fail: 4570 free_token(token); 4571 return; 4572 4573 discard: 4574 input_buf_ptr = save_input_buf_ptr; 4575 input_buf_siz = save_input_buf_siz; 4576 *offset = 0; 4577 *size = 0; 4578 free_token(token); 4579} 4580 4581/** 4582 * pevent_parse_header_page - parse the data stored in the header page 4583 * @pevent: the handle to the pevent 4584 * @buf: the buffer storing the header page format string 4585 * @size: the size of @buf 4586 * @long_size: the long size to use if there is no header 4587 * 4588 * This parses the header page format for information on the 4589 * ring buffer used. The @buf should be copied from 4590 * 4591 * /sys/kernel/debug/tracing/events/header_page 4592 */ 4593int pevent_parse_header_page(struct pevent *pevent, char *buf, unsigned long size, 4594 int long_size) 4595{ 4596 int ignore; 4597 4598 if (!size) { 4599 /* 4600 * Old kernels did not have header page info. 4601 * Sorry but we just use what we find here in user space. 4602 */ 4603 pevent->header_page_ts_size = sizeof(long long); 4604 pevent->header_page_size_size = long_size; 4605 pevent->header_page_data_offset = sizeof(long long) + long_size; 4606 pevent->old_format = 1; 4607 return -1; 4608 } 4609 init_input_buf(buf, size); 4610 4611 parse_header_field("timestamp", &pevent->header_page_ts_offset, 4612 &pevent->header_page_ts_size, 1); 4613 parse_header_field("commit", &pevent->header_page_size_offset, 4614 &pevent->header_page_size_size, 1); 4615 parse_header_field("overwrite", &pevent->header_page_overwrite, 4616 &ignore, 0); 4617 parse_header_field("data", &pevent->header_page_data_offset, 4618 &pevent->header_page_data_size, 1); 4619 4620 return 0; 4621} 4622 4623static int event_matches(struct event_format *event, 4624 int id, const char *sys_name, 4625 const char *event_name) 4626{ 4627 if (id >= 0 && id != event->id) 4628 return 0; 4629 4630 if (event_name && (strcmp(event_name, event->name) != 0)) 4631 return 0; 4632 4633 if (sys_name && (strcmp(sys_name, event->system) != 0)) 4634 return 0; 4635 4636 return 1; 4637} 4638 4639static void free_handler(struct event_handler *handle) 4640{ 4641 free((void *)handle->sys_name); 4642 free((void *)handle->event_name); 4643 free(handle); 4644} 4645 4646static int find_event_handle(struct pevent *pevent, struct event_format *event) 4647{ 4648 struct event_handler *handle, **next; 4649 4650 for (next = &pevent->handlers; *next; 4651 next = &(*next)->next) { 4652 handle = *next; 4653 if (event_matches(event, handle->id, 4654 handle->sys_name, 4655 handle->event_name)) 4656 break; 4657 } 4658 4659 if (!(*next)) 4660 return 0; 4661 4662 pr_stat("overriding event (%d) %s:%s with new print handler", 4663 event->id, event->system, event->name); 4664 4665 event->handler = handle->func; 4666 event->context = handle->context; 4667 4668 *next = handle->next; 4669 free_handler(handle); 4670 4671 return 1; 4672} 4673 4674/** 4675 * pevent_parse_event - parse the event format 4676 * @pevent: the handle to the pevent 4677 * @buf: the buffer storing the event format string 4678 * @size: the size of @buf 4679 * @sys: the system the event belongs to 4680 * 4681 * This parses the event format and creates an event structure 4682 * to quickly parse raw data for a given event. 4683 * 4684 * These files currently come from: 4685 * 4686 * /sys/kernel/debug/tracing/events/.../.../format 4687 */ 4688int pevent_parse_event(struct pevent *pevent, 4689 const char *buf, unsigned long size, 4690 const char *sys) 4691{ 4692 struct event_format *event; 4693 int ret; 4694 4695 init_input_buf(buf, size); 4696 4697 event = alloc_event(); 4698 if (!event) 4699 return -ENOMEM; 4700 4701 event->name = event_read_name(); 4702 if (!event->name) { 4703 /* Bad event? */ 4704 free(event); 4705 return -1; 4706 } 4707 4708 if (strcmp(sys, "ftrace") == 0) { 4709 4710 event->flags |= EVENT_FL_ISFTRACE; 4711 4712 if (strcmp(event->name, "bprint") == 0) 4713 event->flags |= EVENT_FL_ISBPRINT; 4714 } 4715 4716 event->id = event_read_id(); 4717 if (event->id < 0) 4718 die("failed to read event id"); 4719 4720 event->system = strdup(sys); 4721 if (!event->system) 4722 die("failed to allocate system"); 4723 4724 /* Add pevent to event so that it can be referenced */ 4725 event->pevent = pevent; 4726 4727 ret = event_read_format(event); 4728 if (ret < 0) { 4729 do_warning("failed to read event format for %s", event->name); 4730 goto event_failed; 4731 } 4732 4733 /* 4734 * If the event has an override, don't print warnings if the event 4735 * print format fails to parse. 4736 */ 4737 if (find_event_handle(pevent, event)) 4738 show_warning = 0; 4739 4740 ret = event_read_print(event); 4741 if (ret < 0) { 4742 do_warning("failed to read event print fmt for %s", 4743 event->name); 4744 show_warning = 1; 4745 goto event_failed; 4746 } 4747 show_warning = 1; 4748 4749 add_event(pevent, event); 4750 4751 if (!ret && (event->flags & EVENT_FL_ISFTRACE)) { 4752 struct format_field *field; 4753 struct print_arg *arg, **list; 4754 4755 /* old ftrace had no args */ 4756 4757 list = &event->print_fmt.args; 4758 for (field = event->format.fields; field; field = field->next) { 4759 arg = alloc_arg(); 4760 *list = arg; 4761 list = &arg->next; 4762 arg->type = PRINT_FIELD; 4763 arg->field.name = strdup(field->name); 4764 if (!arg->field.name) { 4765 do_warning("failed to allocate field name"); 4766 event->flags |= EVENT_FL_FAILED; 4767 return -1; 4768 } 4769 arg->field.field = field; 4770 } 4771 return 0; 4772 } 4773 4774#define PRINT_ARGS 0 4775 if (PRINT_ARGS && event->print_fmt.args) 4776 print_args(event->print_fmt.args); 4777 4778 return 0; 4779 4780 event_failed: 4781 event->flags |= EVENT_FL_FAILED; 4782 /* still add it even if it failed */ 4783 add_event(pevent, event); 4784 return -1; 4785} 4786 4787int get_field_val(struct trace_seq *s, struct format_field *field, 4788 const char *name, struct pevent_record *record, 4789 unsigned long long *val, int err) 4790{ 4791 if (!field) { 4792 if (err) 4793 trace_seq_printf(s, "<CANT FIND FIELD %s>", name); 4794 return -1; 4795 } 4796 4797 if (pevent_read_number_field(field, record->data, val)) { 4798 if (err) 4799 trace_seq_printf(s, " %s=INVALID", name); 4800 return -1; 4801 } 4802 4803 return 0; 4804} 4805 4806/** 4807 * pevent_get_field_raw - return the raw pointer into the data field 4808 * @s: The seq to print to on error 4809 * @event: the event that the field is for 4810 * @name: The name of the field 4811 * @record: The record with the field name. 4812 * @len: place to store the field length. 4813 * @err: print default error if failed. 4814 * 4815 * Returns a pointer into record->data of the field and places 4816 * the length of the field in @len. 4817 * 4818 * On failure, it returns NULL. 4819 */ 4820void *pevent_get_field_raw(struct trace_seq *s, struct event_format *event, 4821 const char *name, struct pevent_record *record, 4822 int *len, int err) 4823{ 4824 struct format_field *field; 4825 void *data = record->data; 4826 unsigned offset; 4827 int dummy; 4828 4829 if (!event) 4830 return NULL; 4831 4832 field = pevent_find_field(event, name); 4833 4834 if (!field) { 4835 if (err) 4836 trace_seq_printf(s, "<CANT FIND FIELD %s>", name); 4837 return NULL; 4838 } 4839 4840 /* Allow @len to be NULL */ 4841 if (!len) 4842 len = &dummy; 4843 4844 offset = field->offset; 4845 if (field->flags & FIELD_IS_DYNAMIC) { 4846 offset = pevent_read_number(event->pevent, 4847 data + offset, field->size); 4848 *len = offset >> 16; 4849 offset &= 0xffff; 4850 } else 4851 *len = field->size; 4852 4853 return data + offset; 4854} 4855 4856/** 4857 * pevent_get_field_val - find a field and return its value 4858 * @s: The seq to print to on error 4859 * @event: the event that the field is for 4860 * @name: The name of the field 4861 * @record: The record with the field name. 4862 * @val: place to store the value of the field. 4863 * @err: print default error if failed. 4864 * 4865 * Returns 0 on success -1 on field not found. 4866 */ 4867int pevent_get_field_val(struct trace_seq *s, struct event_format *event, 4868 const char *name, struct pevent_record *record, 4869 unsigned long long *val, int err) 4870{ 4871 struct format_field *field; 4872 4873 if (!event) 4874 return -1; 4875 4876 field = pevent_find_field(event, name); 4877 4878 return get_field_val(s, field, name, record, val, err); 4879} 4880 4881/** 4882 * pevent_get_common_field_val - find a common field and return its value 4883 * @s: The seq to print to on error 4884 * @event: the event that the field is for 4885 * @name: The name of the field 4886 * @record: The record with the field name. 4887 * @val: place to store the value of the field. 4888 * @err: print default error if failed. 4889 * 4890 * Returns 0 on success -1 on field not found. 4891 */ 4892int pevent_get_common_field_val(struct trace_seq *s, struct event_format *event, 4893 const char *name, struct pevent_record *record, 4894 unsigned long long *val, int err) 4895{ 4896 struct format_field *field; 4897 4898 if (!event) 4899 return -1; 4900 4901 field = pevent_find_common_field(event, name); 4902 4903 return get_field_val(s, field, name, record, val, err); 4904} 4905 4906/** 4907 * pevent_get_any_field_val - find a any field and return its value 4908 * @s: The seq to print to on error 4909 * @event: the event that the field is for 4910 * @name: The name of the field 4911 * @record: The record with the field name. 4912 * @val: place to store the value of the field. 4913 * @err: print default error if failed. 4914 * 4915 * Returns 0 on success -1 on field not found. 4916 */ 4917int pevent_get_any_field_val(struct trace_seq *s, struct event_format *event, 4918 const char *name, struct pevent_record *record, 4919 unsigned long long *val, int err) 4920{ 4921 struct format_field *field; 4922 4923 if (!event) 4924 return -1; 4925 4926 field = pevent_find_any_field(event, name); 4927 4928 return get_field_val(s, field, name, record, val, err); 4929} 4930 4931/** 4932 * pevent_print_num_field - print a field and a format 4933 * @s: The seq to print to 4934 * @fmt: The printf format to print the field with. 4935 * @event: the event that the field is for 4936 * @name: The name of the field 4937 * @record: The record with the field name. 4938 * @err: print default error if failed. 4939 * 4940 * Returns: 0 on success, -1 field not found, or 1 if buffer is full. 4941 */ 4942int pevent_print_num_field(struct trace_seq *s, const char *fmt, 4943 struct event_format *event, const char *name, 4944 struct pevent_record *record, int err) 4945{ 4946 struct format_field *field = pevent_find_field(event, name); 4947 unsigned long long val; 4948 4949 if (!field) 4950 goto failed; 4951 4952 if (pevent_read_number_field(field, record->data, &val)) 4953 goto failed; 4954 4955 return trace_seq_printf(s, fmt, val); 4956 4957 failed: 4958 if (err) 4959 trace_seq_printf(s, "CAN'T FIND FIELD \"%s\"", name); 4960 return -1; 4961} 4962 4963static void free_func_handle(struct pevent_function_handler *func) 4964{ 4965 struct pevent_func_params *params; 4966 4967 free(func->name); 4968 4969 while (func->params) { 4970 params = func->params; 4971 func->params = params->next; 4972 free(params); 4973 } 4974 4975 free(func); 4976} 4977 4978/** 4979 * pevent_register_print_function - register a helper function 4980 * @pevent: the handle to the pevent 4981 * @func: the function to process the helper function 4982 * @ret_type: the return type of the helper function 4983 * @name: the name of the helper function 4984 * @parameters: A list of enum pevent_func_arg_type 4985 * 4986 * Some events may have helper functions in the print format arguments. 4987 * This allows a plugin to dynamically create a way to process one 4988 * of these functions. 4989 * 4990 * The @parameters is a variable list of pevent_func_arg_type enums that 4991 * must end with PEVENT_FUNC_ARG_VOID. 4992 */ 4993int pevent_register_print_function(struct pevent *pevent, 4994 pevent_func_handler func, 4995 enum pevent_func_arg_type ret_type, 4996 char *name, ...) 4997{ 4998 struct pevent_function_handler *func_handle; 4999 struct pevent_func_params **next_param; 5000 struct pevent_func_params *param; 5001 enum pevent_func_arg_type type; 5002 va_list ap; 5003 5004 func_handle = find_func_handler(pevent, name); 5005 if (func_handle) { 5006 /* 5007 * This is most like caused by the users own 5008 * plugins updating the function. This overrides the 5009 * system defaults. 5010 */ 5011 pr_stat("override of function helper '%s'", name); 5012 remove_func_handler(pevent, name); 5013 } 5014 5015 func_handle = malloc_or_die(sizeof(*func_handle)); 5016 memset(func_handle, 0, sizeof(*func_handle)); 5017 5018 func_handle->ret_type = ret_type; 5019 func_handle->name = strdup(name); 5020 func_handle->func = func; 5021 if (!func_handle->name) 5022 die("Failed to allocate function name"); 5023 5024 next_param = &(func_handle->params); 5025 va_start(ap, name); 5026 for (;;) { 5027 type = va_arg(ap, enum pevent_func_arg_type); 5028 if (type == PEVENT_FUNC_ARG_VOID) 5029 break; 5030 5031 if (type < 0 || type >= PEVENT_FUNC_ARG_MAX_TYPES) { 5032 warning("Invalid argument type %d", type); 5033 goto out_free; 5034 } 5035 5036 param = malloc_or_die(sizeof(*param)); 5037 param->type = type; 5038 param->next = NULL; 5039 5040 *next_param = param; 5041 next_param = &(param->next); 5042 5043 func_handle->nr_args++; 5044 } 5045 va_end(ap); 5046 5047 func_handle->next = pevent->func_handlers; 5048 pevent->func_handlers = func_handle; 5049 5050 return 0; 5051 out_free: 5052 va_end(ap); 5053 free_func_handle(func_handle); 5054 return -1; 5055} 5056 5057/** 5058 * pevent_register_event_handler - register a way to parse an event 5059 * @pevent: the handle to the pevent 5060 * @id: the id of the event to register 5061 * @sys_name: the system name the event belongs to 5062 * @event_name: the name of the event 5063 * @func: the function to call to parse the event information 5064 * @context: the data to be passed to @func 5065 * 5066 * This function allows a developer to override the parsing of 5067 * a given event. If for some reason the default print format 5068 * is not sufficient, this function will register a function 5069 * for an event to be used to parse the data instead. 5070 * 5071 * If @id is >= 0, then it is used to find the event. 5072 * else @sys_name and @event_name are used. 5073 */ 5074int pevent_register_event_handler(struct pevent *pevent, 5075 int id, char *sys_name, char *event_name, 5076 pevent_event_handler_func func, 5077 void *context) 5078{ 5079 struct event_format *event; 5080 struct event_handler *handle; 5081 5082 if (id >= 0) { 5083 /* search by id */ 5084 event = pevent_find_event(pevent, id); 5085 if (!event) 5086 goto not_found; 5087 if (event_name && (strcmp(event_name, event->name) != 0)) 5088 goto not_found; 5089 if (sys_name && (strcmp(sys_name, event->system) != 0)) 5090 goto not_found; 5091 } else { 5092 event = pevent_find_event_by_name(pevent, sys_name, event_name); 5093 if (!event) 5094 goto not_found; 5095 } 5096 5097 pr_stat("overriding event (%d) %s:%s with new print handler", 5098 event->id, event->system, event->name); 5099 5100 event->handler = func; 5101 event->context = context; 5102 return 0; 5103 5104 not_found: 5105 /* Save for later use. */ 5106 handle = malloc_or_die(sizeof(*handle)); 5107 memset(handle, 0, sizeof(*handle)); 5108 handle->id = id; 5109 if (event_name) 5110 handle->event_name = strdup(event_name); 5111 if (sys_name) 5112 handle->sys_name = strdup(sys_name); 5113 5114 if ((event_name && !handle->event_name) || 5115 (sys_name && !handle->sys_name)) { 5116 die("Failed to allocate event/sys name"); 5117 } 5118 5119 handle->func = func; 5120 handle->next = pevent->handlers; 5121 pevent->handlers = handle; 5122 handle->context = context; 5123 5124 return -1; 5125} 5126 5127/** 5128 * pevent_alloc - create a pevent handle 5129 */ 5130struct pevent *pevent_alloc(void) 5131{ 5132 struct pevent *pevent; 5133 5134 pevent = malloc(sizeof(*pevent)); 5135 if (!pevent) 5136 return NULL; 5137 memset(pevent, 0, sizeof(*pevent)); 5138 pevent->ref_count = 1; 5139 5140 return pevent; 5141} 5142 5143void pevent_ref(struct pevent *pevent) 5144{ 5145 pevent->ref_count++; 5146} 5147 5148static void free_format_fields(struct format_field *field) 5149{ 5150 struct format_field *next; 5151 5152 while (field) { 5153 next = field->next; 5154 free(field->type); 5155 free(field->name); 5156 free(field); 5157 field = next; 5158 } 5159} 5160 5161static void free_formats(struct format *format) 5162{ 5163 free_format_fields(format->common_fields); 5164 free_format_fields(format->fields); 5165} 5166 5167static void free_event(struct event_format *event) 5168{ 5169 free(event->name); 5170 free(event->system); 5171 5172 free_formats(&event->format); 5173 5174 free(event->print_fmt.format); 5175 free_args(event->print_fmt.args); 5176 5177 free(event); 5178} 5179 5180/** 5181 * pevent_free - free a pevent handle 5182 * @pevent: the pevent handle to free 5183 */ 5184void pevent_free(struct pevent *pevent) 5185{ 5186 struct cmdline_list *cmdlist, *cmdnext; 5187 struct func_list *funclist, *funcnext; 5188 struct printk_list *printklist, *printknext; 5189 struct pevent_function_handler *func_handler; 5190 struct event_handler *handle; 5191 int i; 5192 5193 if (!pevent) 5194 return; 5195 5196 cmdlist = pevent->cmdlist; 5197 funclist = pevent->funclist; 5198 printklist = pevent->printklist; 5199 5200 pevent->ref_count--; 5201 if (pevent->ref_count) 5202 return; 5203 5204 if (pevent->cmdlines) { 5205 for (i = 0; i < pevent->cmdline_count; i++) 5206 free(pevent->cmdlines[i].comm); 5207 free(pevent->cmdlines); 5208 } 5209 5210 while (cmdlist) { 5211 cmdnext = cmdlist->next; 5212 free(cmdlist->comm); 5213 free(cmdlist); 5214 cmdlist = cmdnext; 5215 } 5216 5217 if (pevent->func_map) { 5218 for (i = 0; i < pevent->func_count; i++) { 5219 free(pevent->func_map[i].func); 5220 free(pevent->func_map[i].mod); 5221 } 5222 free(pevent->func_map); 5223 } 5224 5225 while (funclist) { 5226 funcnext = funclist->next; 5227 free(funclist->func); 5228 free(funclist->mod); 5229 free(funclist); 5230 funclist = funcnext; 5231 } 5232 5233 while (pevent->func_handlers) { 5234 func_handler = pevent->func_handlers; 5235 pevent->func_handlers = func_handler->next; 5236 free_func_handle(func_handler); 5237 } 5238 5239 if (pevent->printk_map) { 5240 for (i = 0; i < pevent->printk_count; i++) 5241 free(pevent->printk_map[i].printk); 5242 free(pevent->printk_map); 5243 } 5244 5245 while (printklist) { 5246 printknext = printklist->next; 5247 free(printklist->printk); 5248 free(printklist); 5249 printklist = printknext; 5250 } 5251 5252 for (i = 0; i < pevent->nr_events; i++) 5253 free_event(pevent->events[i]); 5254 5255 while (pevent->handlers) { 5256 handle = pevent->handlers; 5257 pevent->handlers = handle->next; 5258 free_handler(handle); 5259 } 5260 5261 free(pevent->events); 5262 free(pevent->sort_events); 5263 5264 free(pevent); 5265} 5266 5267void pevent_unref(struct pevent *pevent) 5268{ 5269 pevent_free(pevent); 5270}