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