1e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/* 2e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Copyright (C) 2009, Steven Rostedt <srostedt@redhat.com> 3e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * 4e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 5e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * 6e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * This program is free software; you can redistribute it and/or modify 7e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * it under the terms of the GNU General Public License as published by 8e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * the Free Software Foundation; version 2 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 General Public License for more details. 14e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * 15e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * You should have received a copy of the GNU General Public License 16e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * along with this program; if not, write to the Free Software 17e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * 19e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 20e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */ 21e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <stdio.h> 22e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <stdlib.h> 23e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <string.h> 24e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <ctype.h> 25e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <errno.h> 26e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 27e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "../perf.h" 28e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "util.h" 29e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "trace-event.h" 30e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 31e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct pevent *read_trace_init(int file_bigendian, int host_bigendian) 32e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 33e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct pevent *pevent = pevent_alloc(); 34e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 35e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (pevent != NULL) { 36e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pevent_set_flag(pevent, PEVENT_NSEC_OUTPUT); 37e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pevent_set_file_bigendian(pevent, file_bigendian); 38e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pevent_set_host_bigendian(pevent, host_bigendian); 39e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 40e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 41e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return pevent; 42e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 43e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 44e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int get_common_field(struct scripting_context *context, 45e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int *offset, int *size, const char *type) 46e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 47e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct pevent *pevent = context->pevent; 48e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct event_format *event; 49e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct format_field *field; 50e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 51e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!*size) { 52e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!pevent->events) 53e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return 0; 54e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 55e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng event = pevent->events[0]; 56e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng field = pevent_find_common_field(event, type); 57e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!field) 58e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return 0; 59e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *offset = field->offset; 60e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *size = field->size; 61e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 62e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 63e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return pevent_read_number(pevent, context->event_data + *offset, *size); 64e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 65e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 66e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint common_lock_depth(struct scripting_context *context) 67e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 68e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng static int offset; 69e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng static int size; 70e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int ret; 71e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 72e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ret = get_common_field(context, &size, &offset, 73e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng "common_lock_depth"); 74e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (ret < 0) 75e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return -1; 76e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 77e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return ret; 78e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 79e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 80e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint common_flags(struct scripting_context *context) 81e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 82e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng static int offset; 83e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng static int size; 84e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int ret; 85e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 86e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ret = get_common_field(context, &size, &offset, 87e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng "common_flags"); 88e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (ret < 0) 89e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return -1; 90e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 91e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return ret; 92e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 93e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 94e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint common_pc(struct scripting_context *context) 95e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 96e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng static int offset; 97e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng static int size; 98e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int ret; 99e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 100e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ret = get_common_field(context, &size, &offset, 101e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng "common_preempt_count"); 102e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (ret < 0) 103e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return -1; 104e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 105e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return ret; 106e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 107e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 108e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengunsigned long long 109e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengraw_field_value(struct event_format *event, const char *name, void *data) 110e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 111e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct format_field *field; 112e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng unsigned long long val; 113e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 114e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng field = pevent_find_any_field(event, name); 115e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!field) 116e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return 0ULL; 117e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 118e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pevent_read_number_field(field, data, &val); 119e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 120e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return val; 121e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 122e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 123e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid *raw_field_ptr(struct event_format *event, const char *name, void *data) 124e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 125e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct format_field *field; 126e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 127e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng field = pevent_find_any_field(event, name); 128e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!field) 129e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return NULL; 130e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 131e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (field->flags & FIELD_IS_DYNAMIC) { 132e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int offset; 133e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 134e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng offset = *(int *)(data + field->offset); 135e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng offset &= 0xffff; 136e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 137e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return data + offset; 138e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 139e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 140e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return data + field->offset; 141e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 142e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 143e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint trace_parse_common_type(struct pevent *pevent, void *data) 144e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 145e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct pevent_record record; 146e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 147e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng record.data = data; 148e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return pevent_data_type(pevent, &record); 149e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 150e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 151e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint trace_parse_common_pid(struct pevent *pevent, void *data) 152e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 153e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct pevent_record record; 154e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 155e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng record.data = data; 156e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return pevent_data_pid(pevent, &record); 157e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 158e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 159e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengunsigned long long read_size(struct event_format *event, void *ptr, int size) 160e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 161e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return pevent_read_number(event->pevent, ptr, size); 162e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 163e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 164e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid event_format__print(struct event_format *event, 165e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int cpu, void *data, int size) 166e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 167e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct pevent_record record; 168e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct trace_seq s; 169e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 170e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng memset(&record, 0, sizeof(record)); 171e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng record.cpu = cpu; 172e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng record.size = size; 173e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng record.data = data; 174e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 175e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng trace_seq_init(&s); 176e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pevent_event_info(&s, event, &record); 177e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng trace_seq_do_printf(&s); 178e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 179e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 180e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid parse_proc_kallsyms(struct pevent *pevent, 181e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng char *file, unsigned int size __maybe_unused) 182e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 183e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng unsigned long long addr; 184e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng char *func; 185e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng char *line; 186e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng char *next = NULL; 187e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng char *addr_str; 188e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng char *mod; 189e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng char *fmt = NULL; 190e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 191e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng line = strtok_r(file, "\n", &next); 192e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng while (line) { 193e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng mod = NULL; 194e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng addr_str = strtok_r(line, " ", &fmt); 195e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng addr = strtoull(addr_str, NULL, 16); 196e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng /* skip character */ 197e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng strtok_r(NULL, " ", &fmt); 198e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng func = strtok_r(NULL, "\t", &fmt); 199e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng mod = strtok_r(NULL, "]", &fmt); 200e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng /* truncate the extra '[' */ 201e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (mod) 202e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng mod = mod + 1; 203e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 204e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pevent_register_function(pevent, func, addr, mod); 205e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 206e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng line = strtok_r(NULL, "\n", &next); 207e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 208e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 209e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 210e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid parse_ftrace_printk(struct pevent *pevent, 211e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng char *file, unsigned int size __maybe_unused) 212e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 213e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng unsigned long long addr; 214e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng char *printk; 215e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng char *line; 216e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng char *next = NULL; 217e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng char *addr_str; 218e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng char *fmt; 219e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 220e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng line = strtok_r(file, "\n", &next); 221e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng while (line) { 222e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng addr_str = strtok_r(line, ":", &fmt); 223e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!addr_str) { 224e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng warning("printk format with empty entry"); 225e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng break; 226e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 227e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng addr = strtoull(addr_str, NULL, 16); 228e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng /* fmt still has a space, skip it */ 229e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng printk = strdup(fmt+1); 230e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng line = strtok_r(NULL, "\n", &next); 231e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pevent_register_print_string(pevent, printk, addr); 232e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 233e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 234e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 235e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint parse_ftrace_file(struct pevent *pevent, char *buf, unsigned long size) 236e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 237e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return pevent_parse_event(pevent, buf, size, "ftrace"); 238e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 239e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 240e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint parse_event_file(struct pevent *pevent, 241e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng char *buf, unsigned long size, char *sys) 242e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 243e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return pevent_parse_event(pevent, buf, size, sys); 244e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 245e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 246e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct event_format *trace_find_next_event(struct pevent *pevent, 247e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct event_format *event) 248e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 249e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng static int idx; 250e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 251e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!pevent || !pevent->events) 252e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return NULL; 253e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 254e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!event) { 255e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng idx = 0; 256e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return pevent->events[0]; 257e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 258e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 259e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (idx < pevent->nr_events && event == pevent->events[idx]) { 260e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng idx++; 261e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (idx == pevent->nr_events) 262e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return NULL; 263e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return pevent->events[idx]; 264e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 265e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 266e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng for (idx = 1; idx < pevent->nr_events; idx++) { 267e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (event == pevent->events[idx - 1]) 268e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return pevent->events[idx]; 269e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 270e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return NULL; 271e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 272e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 273e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct flag { 274e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng const char *name; 275e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng unsigned long long value; 276e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}; 277e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 278e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic const struct flag flags[] = { 279e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng { "HI_SOFTIRQ", 0 }, 280e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng { "TIMER_SOFTIRQ", 1 }, 281e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng { "NET_TX_SOFTIRQ", 2 }, 282e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng { "NET_RX_SOFTIRQ", 3 }, 283e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng { "BLOCK_SOFTIRQ", 4 }, 284e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng { "BLOCK_IOPOLL_SOFTIRQ", 5 }, 285e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng { "TASKLET_SOFTIRQ", 6 }, 286e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng { "SCHED_SOFTIRQ", 7 }, 287e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng { "HRTIMER_SOFTIRQ", 8 }, 288e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng { "RCU_SOFTIRQ", 9 }, 289e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 290e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng { "HRTIMER_NORESTART", 0 }, 291e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng { "HRTIMER_RESTART", 1 }, 292e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}; 293e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 294e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengunsigned long long eval_flag(const char *flag) 295e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 296e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int i; 297e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 298e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng /* 299e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Some flags in the format files do not get converted. 300e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * If the flag is not numeric, see if it is something that 301e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * we already know about. 302e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */ 303e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (isdigit(flag[0])) 304e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return strtoull(flag, NULL, 0); 305e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 306e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng for (i = 0; i < (int)(sizeof(flags)/sizeof(flags[0])); i++) 307e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (strcmp(flags[i].name, flag) == 0) 308e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return flags[i].value; 309e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 310e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return 0; 311e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 312