^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: LGPL-2.1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * The parts for function graph printing was taken and modified from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Linux Kernel that were written by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * - Copyright (C) 2009 Frederic Weisbecker,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Frederic Weisbecker gave his permission to relicense the code to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * the Lesser General Public License.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <inttypes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <stdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <stdarg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <stdint.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <limits.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/time64.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <netinet/in.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "event-parse.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "event-parse-local.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include "event-utils.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include "trace-seq.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) static const char *input_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) static unsigned long long input_buf_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static unsigned long long input_buf_siz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) static int is_flag_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static int is_symbolic_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static int show_warning = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define do_warning(fmt, ...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) if (show_warning) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) warning(fmt, ##__VA_ARGS__); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define do_warning_event(event, fmt, ...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) if (!show_warning) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) continue; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) if (event) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) warning("[%s:%s] " fmt, event->system, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) event->name, ##__VA_ARGS__); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) else \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) warning(fmt, ##__VA_ARGS__); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * init_input_buf - init buffer for parsing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * @buf: buffer to parse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * @size: the size of the buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * Initializes the internal buffer that tep_read_token() will parse.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) __hidden void init_input_buf(const char *buf, unsigned long long size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) input_buf = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) input_buf_siz = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) input_buf_ptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) __hidden const char *get_input_buf(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) return input_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) __hidden unsigned long long get_input_buf_ptr(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return input_buf_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct event_handler {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct event_handler *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) const char *sys_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) const char *event_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) tep_event_handler_func func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) void *context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct func_params {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) struct func_params *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) enum tep_func_arg_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct tep_function_handler {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) struct tep_function_handler *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) enum tep_func_arg_type ret_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) tep_func_handler func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct func_params *params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) int nr_args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static unsigned long long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) process_defined_func(struct trace_seq *s, void *data, int size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct tep_event *event, struct tep_print_arg *arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static void free_func_handle(struct tep_function_handler *func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) void breakpoint(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static int x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) x++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static struct tep_print_arg *alloc_arg(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return calloc(1, sizeof(struct tep_print_arg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct tep_cmdline {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) char *comm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) int pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) static int cmdline_cmp(const void *a, const void *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) const struct tep_cmdline *ca = a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) const struct tep_cmdline *cb = b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (ca->pid < cb->pid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (ca->pid > cb->pid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /* Looking for where to place the key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static int cmdline_slot_cmp(const void *a, const void *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) const struct tep_cmdline *ca = a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) const struct tep_cmdline *cb = b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) const struct tep_cmdline *cb1 = cb + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) if (ca->pid < cb->pid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (ca->pid > cb->pid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (ca->pid <= cb1->pid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct cmdline_list {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) struct cmdline_list *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) char *comm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) int pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) static int cmdline_init(struct tep_handle *tep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) struct cmdline_list *cmdlist = tep->cmdlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) struct cmdline_list *item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) struct tep_cmdline *cmdlines;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) cmdlines = malloc(sizeof(*cmdlines) * tep->cmdline_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (!cmdlines)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) while (cmdlist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) cmdlines[i].pid = cmdlist->pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) cmdlines[i].comm = cmdlist->comm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) item = cmdlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) cmdlist = cmdlist->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) free(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) qsort(cmdlines, tep->cmdline_count, sizeof(*cmdlines), cmdline_cmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) tep->cmdlines = cmdlines;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) tep->cmdlist = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) static const char *find_cmdline(struct tep_handle *tep, int pid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) const struct tep_cmdline *comm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) struct tep_cmdline key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if (!pid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) return "<idle>";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (!tep->cmdlines && cmdline_init(tep))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) return "<not enough memory for cmdlines!>";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) key.pid = pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) comm = bsearch(&key, tep->cmdlines, tep->cmdline_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) sizeof(*tep->cmdlines), cmdline_cmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) if (comm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return comm->comm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) return "<...>";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * tep_is_pid_registered - return if a pid has a cmdline registered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * @tep: a handle to the trace event parser context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * @pid: The pid to check if it has a cmdline registered with.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * Returns true if the pid has a cmdline mapped to it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) bool tep_is_pid_registered(struct tep_handle *tep, int pid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) const struct tep_cmdline *comm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) struct tep_cmdline key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (!pid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (!tep->cmdlines && cmdline_init(tep))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) key.pid = pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) comm = bsearch(&key, tep->cmdlines, tep->cmdline_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) sizeof(*tep->cmdlines), cmdline_cmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (comm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * If the command lines have been converted to an array, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) * we must add this pid. This is much slower than when cmdlines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) * are added before the array is initialized.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static int add_new_comm(struct tep_handle *tep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) const char *comm, int pid, bool override)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) struct tep_cmdline *cmdlines = tep->cmdlines;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct tep_cmdline *cmdline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) struct tep_cmdline key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) char *new_comm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) int cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (!pid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) /* avoid duplicates */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) key.pid = pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) cmdline = bsearch(&key, tep->cmdlines, tep->cmdline_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) sizeof(*tep->cmdlines), cmdline_cmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (cmdline) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) if (!override) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) errno = EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) new_comm = strdup(comm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (!new_comm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) errno = ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) free(cmdline->comm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) cmdline->comm = new_comm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) cmdlines = realloc(cmdlines, sizeof(*cmdlines) * (tep->cmdline_count + 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (!cmdlines) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) errno = ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) tep->cmdlines = cmdlines;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) key.comm = strdup(comm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (!key.comm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) errno = ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (!tep->cmdline_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) /* no entries yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) tep->cmdlines[0] = key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) tep->cmdline_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) /* Now find where we want to store the new cmdline */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) cmdline = bsearch(&key, tep->cmdlines, tep->cmdline_count - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) sizeof(*tep->cmdlines), cmdline_slot_cmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) cnt = tep->cmdline_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) if (cmdline) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) /* cmdline points to the one before the spot we want */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) cmdline++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) cnt -= cmdline - tep->cmdlines;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) /* The new entry is either before or after the list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (key.pid > tep->cmdlines[tep->cmdline_count - 1].pid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) tep->cmdlines[tep->cmdline_count++] = key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) cmdline = &tep->cmdlines[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) memmove(cmdline + 1, cmdline, (cnt * sizeof(*cmdline)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) *cmdline = key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) tep->cmdline_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) static int _tep_register_comm(struct tep_handle *tep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) const char *comm, int pid, bool override)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) struct cmdline_list *item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) if (tep->cmdlines)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) return add_new_comm(tep, comm, pid, override);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) item = malloc(sizeof(*item));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (!item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (comm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) item->comm = strdup(comm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) item->comm = strdup("<...>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (!item->comm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) free(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) item->pid = pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) item->next = tep->cmdlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) tep->cmdlist = item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) tep->cmdline_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) * tep_register_comm - register a pid / comm mapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) * @tep: a handle to the trace event parser context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) * @comm: the command line to register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) * @pid: the pid to map the command line to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) * This adds a mapping to search for command line names with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) * a given pid. The comm is duplicated. If a command with the same pid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) * already exist, -1 is returned and errno is set to EEXIST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) int tep_register_comm(struct tep_handle *tep, const char *comm, int pid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) return _tep_register_comm(tep, comm, pid, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) * tep_override_comm - register a pid / comm mapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) * @tep: a handle to the trace event parser context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) * @comm: the command line to register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) * @pid: the pid to map the command line to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) * This adds a mapping to search for command line names with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) * a given pid. The comm is duplicated. If a command with the same pid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) * already exist, the command string is udapted with the new one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) int tep_override_comm(struct tep_handle *tep, const char *comm, int pid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if (!tep->cmdlines && cmdline_init(tep)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) errno = ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) return _tep_register_comm(tep, comm, pid, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) struct func_map {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) unsigned long long addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) char *func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) char *mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) struct func_list {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) struct func_list *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) unsigned long long addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) char *func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) char *mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) static int func_cmp(const void *a, const void *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) const struct func_map *fa = a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) const struct func_map *fb = b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (fa->addr < fb->addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (fa->addr > fb->addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) * We are searching for a record in between, not an exact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) * match.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) static int func_bcmp(const void *a, const void *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) const struct func_map *fa = a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) const struct func_map *fb = b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if ((fa->addr == fb->addr) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) (fa->addr > fb->addr &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) fa->addr < (fb+1)->addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (fa->addr < fb->addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) static int func_map_init(struct tep_handle *tep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) struct func_list *funclist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) struct func_list *item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) struct func_map *func_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) func_map = malloc(sizeof(*func_map) * (tep->func_count + 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) if (!func_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) funclist = tep->funclist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) while (funclist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) func_map[i].func = funclist->func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) func_map[i].addr = funclist->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) func_map[i].mod = funclist->mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) item = funclist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) funclist = funclist->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) free(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) qsort(func_map, tep->func_count, sizeof(*func_map), func_cmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) * Add a special record at the end.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) func_map[tep->func_count].func = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) func_map[tep->func_count].addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) func_map[tep->func_count].mod = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) tep->func_map = func_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) tep->funclist = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) static struct func_map *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) __find_func(struct tep_handle *tep, unsigned long long addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) struct func_map *func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) struct func_map key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (!tep->func_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) func_map_init(tep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) key.addr = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) func = bsearch(&key, tep->func_map, tep->func_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) sizeof(*tep->func_map), func_bcmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) return func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) struct func_resolver {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) tep_func_resolver_t *func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) void *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) struct func_map map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) * tep_set_function_resolver - set an alternative function resolver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) * @tep: a handle to the trace event parser context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) * @resolver: function to be used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) * @priv: resolver function private state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) * Some tools may have already a way to resolve kernel functions, allow them to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) * keep using it instead of duplicating all the entries inside tep->funclist.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) int tep_set_function_resolver(struct tep_handle *tep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) tep_func_resolver_t *func, void *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) struct func_resolver *resolver = malloc(sizeof(*resolver));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (resolver == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) resolver->func = func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) resolver->priv = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) free(tep->func_resolver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) tep->func_resolver = resolver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) * tep_reset_function_resolver - reset alternative function resolver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) * @tep: a handle to the trace event parser context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) * Stop using whatever alternative resolver was set, use the default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) * one instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) void tep_reset_function_resolver(struct tep_handle *tep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) free(tep->func_resolver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) tep->func_resolver = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) static struct func_map *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) find_func(struct tep_handle *tep, unsigned long long addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) struct func_map *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) if (!tep->func_resolver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) return __find_func(tep, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) map = &tep->func_resolver->map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) map->mod = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) map->addr = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) map->func = tep->func_resolver->func(tep->func_resolver->priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) &map->addr, &map->mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) if (map->func == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) return map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) * tep_find_function - find a function by a given address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) * @tep: a handle to the trace event parser context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) * @addr: the address to find the function with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) * Returns a pointer to the function stored that has the given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) * address. Note, the address does not have to be exact, it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) * will select the function that would contain the address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) const char *tep_find_function(struct tep_handle *tep, unsigned long long addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) struct func_map *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) map = find_func(tep, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) if (!map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) return map->func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) * tep_find_function_address - find a function address by a given address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) * @tep: a handle to the trace event parser context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) * @addr: the address to find the function with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) * Returns the address the function starts at. This can be used in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) * conjunction with tep_find_function to print both the function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) * name and the function offset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) unsigned long long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) tep_find_function_address(struct tep_handle *tep, unsigned long long addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) struct func_map *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) map = find_func(tep, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) if (!map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) return map->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) * tep_register_function - register a function with a given address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) * @tep: a handle to the trace event parser context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) * @function: the function name to register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) * @addr: the address the function starts at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) * @mod: the kernel module the function may be in (NULL for none)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) * This registers a function name with an address and module.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) * The @func passed in is duplicated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) int tep_register_function(struct tep_handle *tep, char *func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) unsigned long long addr, char *mod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) struct func_list *item = malloc(sizeof(*item));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) if (!item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) item->next = tep->funclist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) item->func = strdup(func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) if (!item->func)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) if (mod) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) item->mod = strdup(mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) if (!item->mod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) goto out_free_func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) item->mod = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) item->addr = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) tep->funclist = item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) tep->func_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) out_free_func:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) free(item->func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) item->func = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) free(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) errno = ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) * tep_print_funcs - print out the stored functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) * @tep: a handle to the trace event parser context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) * This prints out the stored functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) void tep_print_funcs(struct tep_handle *tep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) if (!tep->func_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) func_map_init(tep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) for (i = 0; i < (int)tep->func_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) printf("%016llx %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) tep->func_map[i].addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) tep->func_map[i].func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) if (tep->func_map[i].mod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) printf(" [%s]\n", tep->func_map[i].mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) printf("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) struct printk_map {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) unsigned long long addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) char *printk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) struct printk_list {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) struct printk_list *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) unsigned long long addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) char *printk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) static int printk_cmp(const void *a, const void *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) const struct printk_map *pa = a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) const struct printk_map *pb = b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) if (pa->addr < pb->addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if (pa->addr > pb->addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) static int printk_map_init(struct tep_handle *tep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) struct printk_list *printklist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) struct printk_list *item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) struct printk_map *printk_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) printk_map = malloc(sizeof(*printk_map) * (tep->printk_count + 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) if (!printk_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) printklist = tep->printklist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) while (printklist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) printk_map[i].printk = printklist->printk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) printk_map[i].addr = printklist->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) item = printklist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) printklist = printklist->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) free(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) qsort(printk_map, tep->printk_count, sizeof(*printk_map), printk_cmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) tep->printk_map = printk_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) tep->printklist = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) static struct printk_map *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) find_printk(struct tep_handle *tep, unsigned long long addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) struct printk_map *printk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) struct printk_map key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) if (!tep->printk_map && printk_map_init(tep))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) key.addr = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) printk = bsearch(&key, tep->printk_map, tep->printk_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) sizeof(*tep->printk_map), printk_cmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) return printk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) * tep_register_print_string - register a string by its address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) * @tep: a handle to the trace event parser context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) * @fmt: the string format to register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) * @addr: the address the string was located at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) * This registers a string by the address it was stored in the kernel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) * The @fmt passed in is duplicated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) int tep_register_print_string(struct tep_handle *tep, const char *fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) unsigned long long addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) struct printk_list *item = malloc(sizeof(*item));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) if (!item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) item->next = tep->printklist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) item->addr = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) /* Strip off quotes and '\n' from the end */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) if (fmt[0] == '"')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) fmt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) item->printk = strdup(fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) if (!item->printk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) p = item->printk + strlen(item->printk) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) if (*p == '"')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) *p = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) p -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) if (strcmp(p, "\\n") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) *p = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) tep->printklist = item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) tep->printk_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) free(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) errno = ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) * tep_print_printk - print out the stored strings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) * @tep: a handle to the trace event parser context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) * This prints the string formats that were stored.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) void tep_print_printk(struct tep_handle *tep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) if (!tep->printk_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) printk_map_init(tep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) for (i = 0; i < (int)tep->printk_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) printf("%016llx %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) tep->printk_map[i].addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) tep->printk_map[i].printk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) static struct tep_event *alloc_event(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) return calloc(1, sizeof(struct tep_event));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) static int add_event(struct tep_handle *tep, struct tep_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) struct tep_event **events = realloc(tep->events, sizeof(event) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) (tep->nr_events + 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) if (!events)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) tep->events = events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) for (i = 0; i < tep->nr_events; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) if (tep->events[i]->id > event->id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) if (i < tep->nr_events)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) memmove(&tep->events[i + 1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) &tep->events[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) sizeof(event) * (tep->nr_events - i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) tep->events[i] = event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) tep->nr_events++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) event->tep = tep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) static int event_item_type(enum tep_event_type type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) case TEP_EVENT_ITEM ... TEP_EVENT_SQUOTE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) case TEP_EVENT_ERROR ... TEP_EVENT_DELIM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) static void free_flag_sym(struct tep_print_flag_sym *fsym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) struct tep_print_flag_sym *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) while (fsym) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) next = fsym->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) free(fsym->value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) free(fsym->str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) free(fsym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) fsym = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) static void free_arg(struct tep_print_arg *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) struct tep_print_arg *farg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (!arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) switch (arg->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) case TEP_PRINT_ATOM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) free(arg->atom.atom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) case TEP_PRINT_FIELD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) free(arg->field.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) case TEP_PRINT_FLAGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) free_arg(arg->flags.field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) free(arg->flags.delim);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) free_flag_sym(arg->flags.flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) case TEP_PRINT_SYMBOL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) free_arg(arg->symbol.field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) free_flag_sym(arg->symbol.symbols);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) case TEP_PRINT_HEX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) case TEP_PRINT_HEX_STR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) free_arg(arg->hex.field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) free_arg(arg->hex.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) case TEP_PRINT_INT_ARRAY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) free_arg(arg->int_array.field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) free_arg(arg->int_array.count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) free_arg(arg->int_array.el_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) case TEP_PRINT_TYPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) free(arg->typecast.type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) free_arg(arg->typecast.item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) case TEP_PRINT_STRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) case TEP_PRINT_BSTRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) free(arg->string.string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) case TEP_PRINT_BITMASK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) free(arg->bitmask.bitmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) case TEP_PRINT_DYNAMIC_ARRAY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) case TEP_PRINT_DYNAMIC_ARRAY_LEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) free(arg->dynarray.index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) case TEP_PRINT_OP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) free(arg->op.op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) free_arg(arg->op.left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) free_arg(arg->op.right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) case TEP_PRINT_FUNC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) while (arg->func.args) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) farg = arg->func.args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) arg->func.args = farg->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) free_arg(farg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) case TEP_PRINT_NULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) free(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) static enum tep_event_type get_type(int ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) if (ch == '\n')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) return TEP_EVENT_NEWLINE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) if (isspace(ch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) return TEP_EVENT_SPACE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) if (isalnum(ch) || ch == '_')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) return TEP_EVENT_ITEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) if (ch == '\'')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) return TEP_EVENT_SQUOTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) if (ch == '"')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) return TEP_EVENT_DQUOTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) if (!isprint(ch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) return TEP_EVENT_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) if (ch == '(' || ch == ')' || ch == ',')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) return TEP_EVENT_DELIM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) return TEP_EVENT_OP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) static int __read_char(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) if (input_buf_ptr >= input_buf_siz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) return input_buf[input_buf_ptr++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) * peek_char - peek at the next character that will be read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) * Returns the next character read, or -1 if end of buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) __hidden int peek_char(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) if (input_buf_ptr >= input_buf_siz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) return input_buf[input_buf_ptr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) static int extend_token(char **tok, char *buf, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) char *newtok = realloc(*tok, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) if (!newtok) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) free(*tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) *tok = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) if (!*tok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) strcpy(newtok, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) strcat(newtok, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) *tok = newtok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) static enum tep_event_type force_token(const char *str, char **tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) static enum tep_event_type __read_token(char **tok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) char buf[BUFSIZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) int ch, last_ch, quote_ch, next_ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) int tok_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) enum tep_event_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) *tok = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) ch = __read_char();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) if (ch < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) return TEP_EVENT_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) type = get_type(ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) if (type == TEP_EVENT_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) return type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) buf[i++] = ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) case TEP_EVENT_NEWLINE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) case TEP_EVENT_DELIM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) if (asprintf(tok, "%c", ch) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) return TEP_EVENT_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) return type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) case TEP_EVENT_OP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) switch (ch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) case '-':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) next_ch = peek_char();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) if (next_ch == '>') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) buf[i++] = __read_char();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) /* fall through */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) case '+':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) case '|':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) case '&':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) case '>':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) case '<':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) last_ch = ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) ch = peek_char();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) if (ch != last_ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) goto test_equal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) buf[i++] = __read_char();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) switch (last_ch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) case '>':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) case '<':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) goto test_equal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) case '!':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) case '=':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) goto test_equal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) default: /* what should we do instead? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) buf[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) *tok = strdup(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) return type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) test_equal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) ch = peek_char();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) if (ch == '=')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) buf[i++] = __read_char();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) case TEP_EVENT_DQUOTE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) case TEP_EVENT_SQUOTE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) /* don't keep quotes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) i--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) quote_ch = ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) last_ch = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) concat:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) if (i == (BUFSIZ - 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) buf[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) tok_size += BUFSIZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) if (extend_token(tok, buf, tok_size) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) return TEP_EVENT_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) last_ch = ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) ch = __read_char();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) buf[i++] = ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) /* the '\' '\' will cancel itself */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) if (ch == '\\' && last_ch == '\\')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) last_ch = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) } while (ch != quote_ch || last_ch == '\\');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) /* remove the last quote */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) i--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) * For strings (double quotes) check the next token.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) * If it is another string, concatinate the two.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) if (type == TEP_EVENT_DQUOTE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) unsigned long long save_input_buf_ptr = input_buf_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) ch = __read_char();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) } while (isspace(ch));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) if (ch == '"')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) goto concat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) input_buf_ptr = save_input_buf_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) case TEP_EVENT_ERROR ... TEP_EVENT_SPACE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) case TEP_EVENT_ITEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) while (get_type(peek_char()) == type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) if (i == (BUFSIZ - 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) buf[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) tok_size += BUFSIZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) if (extend_token(tok, buf, tok_size) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) return TEP_EVENT_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) ch = __read_char();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) buf[i++] = ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) buf[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) if (extend_token(tok, buf, tok_size + i + 1) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) return TEP_EVENT_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) if (type == TEP_EVENT_ITEM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) * Older versions of the kernel has a bug that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) * creates invalid symbols and will break the mac80211
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) * parsing. This is a work around to that bug.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) * See Linux kernel commit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) * 811cb50baf63461ce0bdb234927046131fc7fa8b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) if (strcmp(*tok, "LOCAL_PR_FMT") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) free(*tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) *tok = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) return force_token("\"%s\" ", tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) } else if (strcmp(*tok, "STA_PR_FMT") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) free(*tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) *tok = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) return force_token("\" sta:%pM\" ", tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) } else if (strcmp(*tok, "VIF_PR_FMT") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) free(*tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) *tok = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) return force_token("\" vif:%p(%d)\" ", tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) return type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) static enum tep_event_type force_token(const char *str, char **tok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) const char *save_input_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) unsigned long long save_input_buf_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) unsigned long long save_input_buf_siz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) enum tep_event_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) /* save off the current input pointers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) save_input_buf = input_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) save_input_buf_ptr = input_buf_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) save_input_buf_siz = input_buf_siz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) init_input_buf(str, strlen(str));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) type = __read_token(tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) /* reset back to original token */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) input_buf = save_input_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) input_buf_ptr = save_input_buf_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) input_buf_siz = save_input_buf_siz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) return type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) * free_token - free a token returned by tep_read_token
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) * @token: the token to free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) __hidden void free_token(char *tok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) if (tok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) free(tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) * read_token - access to utilities to use the tep parser
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) * @tok: The token to return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) * This will parse tokens from the string given by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) * tep_init_data().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) * Returns the token type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) __hidden enum tep_event_type read_token(char **tok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) enum tep_event_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) type = __read_token(tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) if (type != TEP_EVENT_SPACE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) return type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) free_token(*tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) /* not reached */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) *tok = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) return TEP_EVENT_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) /* no newline */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) static enum tep_event_type read_token_item(char **tok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) enum tep_event_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) type = __read_token(tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) if (type != TEP_EVENT_SPACE && type != TEP_EVENT_NEWLINE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) return type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) free_token(*tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) *tok = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) /* not reached */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) *tok = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) return TEP_EVENT_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) static int test_type(enum tep_event_type type, enum tep_event_type expect)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) if (type != expect) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) do_warning("Error: expected type %d but read %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) expect, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) static int test_type_token(enum tep_event_type type, const char *token,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) enum tep_event_type expect, const char *expect_tok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) if (type != expect) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) do_warning("Error: expected type %d but read %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) expect, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) if (strcmp(token, expect_tok) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) do_warning("Error: expected '%s' but read '%s'",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) expect_tok, token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) static int __read_expect_type(enum tep_event_type expect, char **tok, int newline_ok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) enum tep_event_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) if (newline_ok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) type = read_token(tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) type = read_token_item(tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) return test_type(type, expect);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) static int read_expect_type(enum tep_event_type expect, char **tok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) return __read_expect_type(expect, tok, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) static int __read_expected(enum tep_event_type expect, const char *str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) int newline_ok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) enum tep_event_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) char *token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) if (newline_ok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) type = read_token(&token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) type = read_token_item(&token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) ret = test_type_token(type, token, expect, str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) static int read_expected(enum tep_event_type expect, const char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) return __read_expected(expect, str, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) static int read_expected_item(enum tep_event_type expect, const char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) return __read_expected(expect, str, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) static char *event_read_name(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) char *token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) if (read_expected(TEP_EVENT_ITEM, "name") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) if (read_expected(TEP_EVENT_OP, ":") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) if (read_expect_type(TEP_EVENT_ITEM, &token) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) return token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) static int event_read_id(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) char *token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) if (read_expected_item(TEP_EVENT_ITEM, "ID") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) if (read_expected(TEP_EVENT_OP, ":") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) if (read_expect_type(TEP_EVENT_ITEM, &token) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) id = strtoul(token, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) return id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) static int field_is_string(struct tep_format_field *field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) if ((field->flags & TEP_FIELD_IS_ARRAY) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) (strstr(field->type, "char") || strstr(field->type, "u8") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) strstr(field->type, "s8")))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) static int field_is_dynamic(struct tep_format_field *field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) if (strncmp(field->type, "__data_loc", 10) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) static int field_is_long(struct tep_format_field *field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) /* includes long long */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) if (strstr(field->type, "long"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) static unsigned int type_size(const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) /* This covers all TEP_FIELD_IS_STRING types. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) static struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) const char *type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) unsigned int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) } table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) { "u8", 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) { "u16", 2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) { "u32", 4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) { "u64", 8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) { "s8", 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) { "s16", 2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) { "s32", 4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) { "s64", 8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) { "char", 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) for (i = 0; table[i].type; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) if (!strcmp(table[i].type, name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) return table[i].size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) static int append(char **buf, const char *delim, const char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) char *new_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) new_buf = realloc(*buf, strlen(*buf) + strlen(delim) + strlen(str) + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) if (!new_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) strcat(new_buf, delim);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) strcat(new_buf, str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) *buf = new_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) static int event_read_fields(struct tep_event *event, struct tep_format_field **fields)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) struct tep_format_field *field = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) enum tep_event_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) char *token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) char *last_token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) char *delim = " ";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) int count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) unsigned int size_dynamic = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) type = read_token(&token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) if (type == TEP_EVENT_NEWLINE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) if (test_type_token(type, token, TEP_EVENT_ITEM, "field"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) type = read_token(&token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) * The ftrace fields may still use the "special" name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) * Just ignore it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) if (event->flags & TEP_EVENT_FL_ISFTRACE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) type == TEP_EVENT_ITEM && strcmp(token, "special") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) type = read_token(&token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) if (test_type_token(type, token, TEP_EVENT_OP, ":") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) if (read_expect_type(TEP_EVENT_ITEM, &token) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) last_token = token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) field = calloc(1, sizeof(*field));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) if (!field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) field->event = event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) /* read the rest of the type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) type = read_token(&token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) if (type == TEP_EVENT_ITEM ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) (type == TEP_EVENT_OP && strcmp(token, "*") == 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) * Some of the ftrace fields are broken and have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) * an illegal "." in them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) (event->flags & TEP_EVENT_FL_ISFTRACE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) type == TEP_EVENT_OP && strcmp(token, ".") == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) if (strcmp(token, "*") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) field->flags |= TEP_FIELD_IS_POINTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) if (field->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) ret = append(&field->type, delim, last_token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) free(last_token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) field->type = last_token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) last_token = token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) delim = " ";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) /* Handle __attribute__((user)) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) if ((type == TEP_EVENT_DELIM) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) strcmp("__attribute__", last_token) == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) token[0] == '(') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) int depth = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) ret = append(&field->type, " ", last_token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) ret |= append(&field->type, "", "(");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) delim = " ";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) while ((type = read_token(&token)) != TEP_EVENT_NONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) if (type == TEP_EVENT_DELIM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) if (token[0] == '(')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) depth++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) else if (token[0] == ')')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) depth--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) if (!depth)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) ret = append(&field->type, "", token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) delim = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) ret = append(&field->type, delim, token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) delim = " ";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) free(last_token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) last_token = token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) if (!field->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) do_warning_event(event, "%s: no type found", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) field->name = field->alias = last_token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) if (test_type(type, TEP_EVENT_OP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) if (strcmp(token, "[") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) enum tep_event_type last_type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) char *brackets = token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) field->flags |= TEP_FIELD_IS_ARRAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) type = read_token(&token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) if (type == TEP_EVENT_ITEM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) field->arraylen = strtoul(token, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) field->arraylen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) while (strcmp(token, "]") != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) const char *delim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) if (last_type == TEP_EVENT_ITEM &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) type == TEP_EVENT_ITEM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) delim = " ";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) delim = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) last_type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) ret = append(&brackets, delim, token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) free(brackets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) /* We only care about the last token */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) field->arraylen = strtoul(token, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) type = read_token(&token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) if (type == TEP_EVENT_NONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) free(brackets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) do_warning_event(event, "failed to find token");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) ret = append(&brackets, "", "]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) free(brackets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) /* add brackets to type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) type = read_token(&token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) * If the next token is not an OP, then it is of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) * the format: type [] item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) if (type == TEP_EVENT_ITEM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) ret = append(&field->type, " ", field->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) free(brackets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) ret = append(&field->type, "", brackets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) size_dynamic = type_size(field->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) free_token(field->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) field->name = field->alias = token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) type = read_token(&token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) ret = append(&field->type, "", brackets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) free(brackets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) free(brackets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) if (field_is_string(field))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) field->flags |= TEP_FIELD_IS_STRING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) if (field_is_dynamic(field))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) field->flags |= TEP_FIELD_IS_DYNAMIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) if (field_is_long(field))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) field->flags |= TEP_FIELD_IS_LONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) if (test_type_token(type, token, TEP_EVENT_OP, ";"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) if (read_expected(TEP_EVENT_ITEM, "offset") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) goto fail_expect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) if (read_expected(TEP_EVENT_OP, ":") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) goto fail_expect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) if (read_expect_type(TEP_EVENT_ITEM, &token))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) field->offset = strtoul(token, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) if (read_expected(TEP_EVENT_OP, ";") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) goto fail_expect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) if (read_expected(TEP_EVENT_ITEM, "size") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) goto fail_expect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) if (read_expected(TEP_EVENT_OP, ":") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) goto fail_expect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) if (read_expect_type(TEP_EVENT_ITEM, &token))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) field->size = strtoul(token, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) if (read_expected(TEP_EVENT_OP, ";") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) goto fail_expect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) type = read_token(&token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) if (type != TEP_EVENT_NEWLINE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) /* newer versions of the kernel have a "signed" type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) if (test_type_token(type, token, TEP_EVENT_ITEM, "signed"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) if (read_expected(TEP_EVENT_OP, ":") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) goto fail_expect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) if (read_expect_type(TEP_EVENT_ITEM, &token))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) if (strtoul(token, NULL, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) field->flags |= TEP_FIELD_IS_SIGNED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) if (read_expected(TEP_EVENT_OP, ";") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) goto fail_expect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) if (read_expect_type(TEP_EVENT_NEWLINE, &token))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) if (field->flags & TEP_FIELD_IS_ARRAY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) if (field->arraylen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) field->elementsize = field->size / field->arraylen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) else if (field->flags & TEP_FIELD_IS_DYNAMIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) field->elementsize = size_dynamic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) else if (field->flags & TEP_FIELD_IS_STRING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) field->elementsize = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) else if (field->flags & TEP_FIELD_IS_LONG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) field->elementsize = event->tep ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) event->tep->long_size :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) sizeof(long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) field->elementsize = field->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) *fields = field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) fields = &field->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) } while (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) fail_expect:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) if (field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) free(field->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) free(field->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) free(field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) static int event_read_format(struct tep_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) char *token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) if (read_expected_item(TEP_EVENT_ITEM, "format") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) if (read_expected(TEP_EVENT_OP, ":") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) if (read_expect_type(TEP_EVENT_NEWLINE, &token))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) ret = event_read_fields(event, &event->format.common_fields);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) event->format.nr_common = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) ret = event_read_fields(event, &event->format.fields);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) event->format.nr_fields = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) static enum tep_event_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) process_arg_token(struct tep_event *event, struct tep_print_arg *arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) char **tok, enum tep_event_type type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) static enum tep_event_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) process_arg(struct tep_event *event, struct tep_print_arg *arg, char **tok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) enum tep_event_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) char *token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) type = read_token(&token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) *tok = token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) return process_arg_token(event, arg, tok, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) static enum tep_event_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) process_op(struct tep_event *event, struct tep_print_arg *arg, char **tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) * For __print_symbolic() and __print_flags, we need to completely
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) * evaluate the first argument, which defines what to print next.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) static enum tep_event_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) process_field_arg(struct tep_event *event, struct tep_print_arg *arg, char **tok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) enum tep_event_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) type = process_arg(event, arg, tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) while (type == TEP_EVENT_OP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) type = process_op(event, arg, tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) return type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) static enum tep_event_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) process_cond(struct tep_event *event, struct tep_print_arg *top, char **tok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) struct tep_print_arg *arg, *left, *right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) enum tep_event_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) char *token = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) arg = alloc_arg();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) left = alloc_arg();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) right = alloc_arg();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) if (!arg || !left || !right) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) do_warning_event(event, "%s: not enough memory!", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) /* arg will be freed at out_free */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) free_arg(left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) free_arg(right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) arg->type = TEP_PRINT_OP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) arg->op.left = left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) arg->op.right = right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) *tok = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) type = process_arg(event, left, &token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) if (type == TEP_EVENT_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) /* Handle other operations in the arguments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) if (type == TEP_EVENT_OP && strcmp(token, ":") != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) type = process_op(event, left, &token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) if (test_type_token(type, token, TEP_EVENT_OP, ":"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) arg->op.op = token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) type = process_arg(event, right, &token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) top->op.right = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) *tok = token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) return type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) /* Top may point to itself */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) top->op.right = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) free_arg(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) return TEP_EVENT_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) static enum tep_event_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) process_array(struct tep_event *event, struct tep_print_arg *top, char **tok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) struct tep_print_arg *arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) enum tep_event_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) char *token = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) arg = alloc_arg();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) if (!arg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) do_warning_event(event, "%s: not enough memory!", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) /* '*tok' is set to top->op.op. No need to free. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) *tok = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) return TEP_EVENT_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) *tok = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) type = process_arg(event, arg, &token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) if (test_type_token(type, token, TEP_EVENT_OP, "]"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) top->op.right = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) type = read_token_item(&token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) *tok = token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) return type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) free_arg(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) return TEP_EVENT_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) static int get_op_prio(char *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) if (!op[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) switch (op[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) case '~':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) case '!':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) return 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) case '*':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) case '/':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) case '%':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) return 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) case '+':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) case '-':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) return 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) /* '>>' and '<<' are 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) case '<':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) case '>':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) return 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) /* '==' and '!=' are 10 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) case '&':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) return 11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) case '^':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) return 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) case '|':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) return 13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) case '?':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) return 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) do_warning("unknown op '%c'", op[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) if (strcmp(op, "++") == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) strcmp(op, "--") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) return 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) } else if (strcmp(op, ">>") == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) strcmp(op, "<<") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) return 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) } else if (strcmp(op, ">=") == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) strcmp(op, "<=") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) return 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) } else if (strcmp(op, "==") == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) strcmp(op, "!=") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) return 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) } else if (strcmp(op, "&&") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) return 14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) } else if (strcmp(op, "||") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) return 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) do_warning("unknown op '%s'", op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) static int set_op_prio(struct tep_print_arg *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) /* single ops are the greatest */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) if (!arg->op.left || arg->op.left->type == TEP_PRINT_NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) arg->op.prio = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) arg->op.prio = get_op_prio(arg->op.op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) return arg->op.prio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) /* Note, *tok does not get freed, but will most likely be saved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) static enum tep_event_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) process_op(struct tep_event *event, struct tep_print_arg *arg, char **tok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) struct tep_print_arg *left, *right = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) enum tep_event_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) char *token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) /* the op is passed in via tok */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) token = *tok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) if (arg->type == TEP_PRINT_OP && !arg->op.left) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) /* handle single op */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) if (token[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) do_warning_event(event, "bad op token %s", token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) switch (token[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) case '~':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) case '!':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) case '+':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) case '-':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) do_warning_event(event, "bad op token %s", token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) /* make an empty left */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) left = alloc_arg();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) if (!left)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) goto out_warn_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) left->type = TEP_PRINT_NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) arg->op.left = left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) right = alloc_arg();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) if (!right)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) goto out_warn_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) arg->op.right = right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) /* do not free the token, it belongs to an op */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) *tok = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) type = process_arg(event, right, tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) } else if (strcmp(token, "?") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) left = alloc_arg();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) if (!left)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) goto out_warn_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) /* copy the top arg to the left */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) *left = *arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) arg->type = TEP_PRINT_OP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) arg->op.op = token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) arg->op.left = left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) arg->op.prio = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) /* it will set arg->op.right */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) type = process_cond(event, arg, tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) } else if (strcmp(token, ">>") == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) strcmp(token, "<<") == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) strcmp(token, "&") == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) strcmp(token, "|") == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) strcmp(token, "&&") == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) strcmp(token, "||") == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) strcmp(token, "-") == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) strcmp(token, "+") == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) strcmp(token, "*") == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) strcmp(token, "^") == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) strcmp(token, "/") == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) strcmp(token, "%") == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) strcmp(token, "<") == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) strcmp(token, ">") == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) strcmp(token, "<=") == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) strcmp(token, ">=") == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) strcmp(token, "==") == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) strcmp(token, "!=") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) left = alloc_arg();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) if (!left)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) goto out_warn_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) /* copy the top arg to the left */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) *left = *arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) arg->type = TEP_PRINT_OP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) arg->op.op = token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) arg->op.left = left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) arg->op.right = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) if (set_op_prio(arg) == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) event->flags |= TEP_EVENT_FL_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) /* arg->op.op (= token) will be freed at out_free */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) arg->op.op = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) type = read_token_item(&token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) *tok = token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) /* could just be a type pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) if ((strcmp(arg->op.op, "*") == 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) type == TEP_EVENT_DELIM && (strcmp(token, ")") == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) if (left->type != TEP_PRINT_ATOM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) do_warning_event(event, "bad pointer type");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) ret = append(&left->atom.atom, " ", "*");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) goto out_warn_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) free(arg->op.op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) *arg = *left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) free(left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) return type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) right = alloc_arg();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) if (!right)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) goto out_warn_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) type = process_arg_token(event, right, tok, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) if (type == TEP_EVENT_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) free_arg(right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) /* token was freed in process_arg_token() via *tok */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) token = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) if (right->type == TEP_PRINT_OP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) get_op_prio(arg->op.op) < get_op_prio(right->op.op)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) struct tep_print_arg tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) /* rotate ops according to the priority */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) arg->op.right = right->op.left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) tmp = *arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) *arg = *right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) *right = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) arg->op.left = right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) arg->op.right = right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) } else if (strcmp(token, "[") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) left = alloc_arg();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) if (!left)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) goto out_warn_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) *left = *arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) arg->type = TEP_PRINT_OP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) arg->op.op = token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) arg->op.left = left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) arg->op.prio = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) /* it will set arg->op.right */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) type = process_array(event, arg, tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) do_warning_event(event, "unknown op '%s'", token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) event->flags |= TEP_EVENT_FL_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) /* the arg is now the left side */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) if (type == TEP_EVENT_OP && strcmp(*tok, ":") != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) int prio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) /* higher prios need to be closer to the root */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) prio = get_op_prio(*tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) if (prio > arg->op.prio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) return process_op(event, arg, tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) return process_op(event, right, tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) return type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) out_warn_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) do_warning_event(event, "%s: not enough memory!", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) *tok = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) return TEP_EVENT_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) static enum tep_event_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) process_entry(struct tep_event *event __maybe_unused, struct tep_print_arg *arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) char **tok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) enum tep_event_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) char *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) char *token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) if (read_expected(TEP_EVENT_OP, "->") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) if (read_expect_type(TEP_EVENT_ITEM, &token) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) field = token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) arg->type = TEP_PRINT_FIELD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) arg->field.name = field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) if (is_flag_field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) arg->field.field = tep_find_any_field(event, arg->field.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) arg->field.field->flags |= TEP_FIELD_IS_FLAG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) is_flag_field = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) } else if (is_symbolic_field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) arg->field.field = tep_find_any_field(event, arg->field.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) arg->field.field->flags |= TEP_FIELD_IS_SYMBOLIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) is_symbolic_field = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) type = read_token(&token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) *tok = token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) return type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) *tok = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) return TEP_EVENT_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) static int alloc_and_process_delim(struct tep_event *event, char *next_token,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) struct tep_print_arg **print_arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) struct tep_print_arg *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) enum tep_event_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) char *token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) field = alloc_arg();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) if (!field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) do_warning_event(event, "%s: not enough memory!", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) errno = ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) type = process_arg(event, field, &token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) if (test_type_token(type, token, TEP_EVENT_DELIM, next_token)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) errno = EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) free_arg(field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) goto out_free_token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) *print_arg = field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) out_free_token:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) static char *arg_eval (struct tep_print_arg *arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) static unsigned long long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) eval_type_str(unsigned long long val, const char *type, int pointer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) int sign = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) char *ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) len = strlen(type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) if (pointer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) if (type[len-1] != '*') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) do_warning("pointer expected with non pointer type");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) ref = malloc(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) if (!ref) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) do_warning("%s: not enough memory!", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) memcpy(ref, type, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) /* chop off the " *" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) ref[len - 2] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) val = eval_type_str(val, ref, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) free(ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) /* check if this is a pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) if (type[len - 1] == '*')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) /* Try to figure out the arg size*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) if (strncmp(type, "struct", 6) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) /* all bets off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) if (strcmp(type, "u8") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) return val & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) if (strcmp(type, "u16") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) return val & 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) if (strcmp(type, "u32") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) return val & 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) if (strcmp(type, "u64") == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) strcmp(type, "s64") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) if (strcmp(type, "s8") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) return (unsigned long long)(char)val & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) if (strcmp(type, "s16") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) return (unsigned long long)(short)val & 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) if (strcmp(type, "s32") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) return (unsigned long long)(int)val & 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) if (strncmp(type, "unsigned ", 9) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) sign = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) type += 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) if (strcmp(type, "char") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) if (sign)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) return (unsigned long long)(char)val & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) return val & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) if (strcmp(type, "short") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) if (sign)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) return (unsigned long long)(short)val & 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) return val & 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) if (strcmp(type, "int") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) if (sign)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) return (unsigned long long)(int)val & 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) return val & 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) * Try to figure out the type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) static unsigned long long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) eval_type(unsigned long long val, struct tep_print_arg *arg, int pointer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) if (arg->type != TEP_PRINT_TYPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) do_warning("expected type argument");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) return eval_type_str(val, arg->typecast.type, pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) static int arg_num_eval(struct tep_print_arg *arg, long long *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) long long left, right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) int ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) switch (arg->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) case TEP_PRINT_ATOM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) *val = strtoll(arg->atom.atom, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) case TEP_PRINT_TYPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) ret = arg_num_eval(arg->typecast.item, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) *val = eval_type(*val, arg, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) case TEP_PRINT_OP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) switch (arg->op.op[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) case '|':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) ret = arg_num_eval(arg->op.left, &left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) ret = arg_num_eval(arg->op.right, &right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) if (arg->op.op[1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) *val = left || right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) *val = left | right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) case '&':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) ret = arg_num_eval(arg->op.left, &left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) ret = arg_num_eval(arg->op.right, &right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) if (arg->op.op[1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) *val = left && right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) *val = left & right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) case '<':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) ret = arg_num_eval(arg->op.left, &left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) ret = arg_num_eval(arg->op.right, &right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) switch (arg->op.op[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) *val = left < right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) case '<':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) *val = left << right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) case '=':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) *val = left <= right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) do_warning("unknown op '%s'", arg->op.op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) case '>':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) ret = arg_num_eval(arg->op.left, &left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) ret = arg_num_eval(arg->op.right, &right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) switch (arg->op.op[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) *val = left > right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) case '>':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) *val = left >> right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) case '=':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) *val = left >= right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) do_warning("unknown op '%s'", arg->op.op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) case '=':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) ret = arg_num_eval(arg->op.left, &left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) ret = arg_num_eval(arg->op.right, &right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) if (arg->op.op[1] != '=') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) do_warning("unknown op '%s'", arg->op.op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) *val = left == right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) case '!':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) ret = arg_num_eval(arg->op.left, &left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) ret = arg_num_eval(arg->op.right, &right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) switch (arg->op.op[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) case '=':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) *val = left != right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) do_warning("unknown op '%s'", arg->op.op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) case '-':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) /* check for negative */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) if (arg->op.left->type == TEP_PRINT_NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) left = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) ret = arg_num_eval(arg->op.left, &left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) ret = arg_num_eval(arg->op.right, &right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) *val = left - right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) case '+':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) if (arg->op.left->type == TEP_PRINT_NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) left = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) ret = arg_num_eval(arg->op.left, &left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) ret = arg_num_eval(arg->op.right, &right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) *val = left + right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) case '~':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) ret = arg_num_eval(arg->op.right, &right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) *val = ~right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) do_warning("unknown op '%s'", arg->op.op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) case TEP_PRINT_NULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) case TEP_PRINT_FIELD ... TEP_PRINT_SYMBOL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) case TEP_PRINT_STRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) case TEP_PRINT_BSTRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) case TEP_PRINT_BITMASK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) do_warning("invalid eval type %d", arg->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) static char *arg_eval (struct tep_print_arg *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) long long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) static char buf[24];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) switch (arg->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) case TEP_PRINT_ATOM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) return arg->atom.atom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) case TEP_PRINT_TYPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) return arg_eval(arg->typecast.item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) case TEP_PRINT_OP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) if (!arg_num_eval(arg, &val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) sprintf(buf, "%lld", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) return buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) case TEP_PRINT_NULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) case TEP_PRINT_FIELD ... TEP_PRINT_SYMBOL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) case TEP_PRINT_STRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) case TEP_PRINT_BSTRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) case TEP_PRINT_BITMASK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) do_warning("invalid eval type %d", arg->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) static enum tep_event_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) process_fields(struct tep_event *event, struct tep_print_flag_sym **list, char **tok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) enum tep_event_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) struct tep_print_arg *arg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) struct tep_print_flag_sym *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) char *token = *tok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) char *value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) type = read_token_item(&token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) if (test_type_token(type, token, TEP_EVENT_OP, "{"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) arg = alloc_arg();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) if (!arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) type = process_arg(event, arg, &token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) if (type == TEP_EVENT_OP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) type = process_op(event, arg, &token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) if (type == TEP_EVENT_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) if (test_type_token(type, token, TEP_EVENT_DELIM, ","))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) field = calloc(1, sizeof(*field));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) if (!field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) value = arg_eval(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) if (value == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) goto out_free_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) field->value = strdup(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) if (field->value == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) goto out_free_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) free_arg(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) arg = alloc_arg();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) if (!arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) type = process_arg(event, arg, &token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) if (test_type_token(type, token, TEP_EVENT_OP, "}"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) goto out_free_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) value = arg_eval(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) if (value == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) goto out_free_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) field->str = strdup(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) if (field->str == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) goto out_free_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) free_arg(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) arg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) *list = field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) list = &field->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) type = read_token_item(&token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) } while (type == TEP_EVENT_DELIM && strcmp(token, ",") == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) *tok = token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) return type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) out_free_field:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) free_flag_sym(field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) free_arg(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) *tok = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) return TEP_EVENT_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) static enum tep_event_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) process_flags(struct tep_event *event, struct tep_print_arg *arg, char **tok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) struct tep_print_arg *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) enum tep_event_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) char *token = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) memset(arg, 0, sizeof(*arg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) arg->type = TEP_PRINT_FLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) field = alloc_arg();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) if (!field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) do_warning_event(event, "%s: not enough memory!", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) type = process_field_arg(event, field, &token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) /* Handle operations in the first argument */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) while (type == TEP_EVENT_OP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) type = process_op(event, field, &token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) if (test_type_token(type, token, TEP_EVENT_DELIM, ","))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) goto out_free_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) arg->flags.field = field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) type = read_token_item(&token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) if (event_item_type(type)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) arg->flags.delim = token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) type = read_token_item(&token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) if (test_type_token(type, token, TEP_EVENT_DELIM, ","))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) type = process_fields(event, &arg->flags.flags, &token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) if (test_type_token(type, token, TEP_EVENT_DELIM, ")"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) type = read_token_item(tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) return type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) out_free_field:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) free_arg(field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) *tok = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) return TEP_EVENT_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) static enum tep_event_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) process_symbols(struct tep_event *event, struct tep_print_arg *arg, char **tok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) struct tep_print_arg *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) enum tep_event_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) char *token = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) memset(arg, 0, sizeof(*arg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) arg->type = TEP_PRINT_SYMBOL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) field = alloc_arg();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) if (!field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) do_warning_event(event, "%s: not enough memory!", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) type = process_field_arg(event, field, &token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) if (test_type_token(type, token, TEP_EVENT_DELIM, ","))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) goto out_free_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) arg->symbol.field = field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) type = process_fields(event, &arg->symbol.symbols, &token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) if (test_type_token(type, token, TEP_EVENT_DELIM, ")"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) type = read_token_item(tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) return type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) out_free_field:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) free_arg(field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) *tok = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) return TEP_EVENT_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) static enum tep_event_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) process_hex_common(struct tep_event *event, struct tep_print_arg *arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) char **tok, enum tep_print_arg_type type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) memset(arg, 0, sizeof(*arg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) arg->type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) if (alloc_and_process_delim(event, ",", &arg->hex.field))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) if (alloc_and_process_delim(event, ")", &arg->hex.size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) goto free_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) return read_token_item(tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) free_field:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) free_arg(arg->hex.field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) arg->hex.field = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) *tok = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) return TEP_EVENT_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) static enum tep_event_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) process_hex(struct tep_event *event, struct tep_print_arg *arg, char **tok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) return process_hex_common(event, arg, tok, TEP_PRINT_HEX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) static enum tep_event_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) process_hex_str(struct tep_event *event, struct tep_print_arg *arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) char **tok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) return process_hex_common(event, arg, tok, TEP_PRINT_HEX_STR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) static enum tep_event_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) process_int_array(struct tep_event *event, struct tep_print_arg *arg, char **tok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) memset(arg, 0, sizeof(*arg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) arg->type = TEP_PRINT_INT_ARRAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) if (alloc_and_process_delim(event, ",", &arg->int_array.field))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) if (alloc_and_process_delim(event, ",", &arg->int_array.count))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) goto free_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) if (alloc_and_process_delim(event, ")", &arg->int_array.el_size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) goto free_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) return read_token_item(tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) free_size:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) free_arg(arg->int_array.count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) arg->int_array.count = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) free_field:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) free_arg(arg->int_array.field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) arg->int_array.field = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) *tok = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) return TEP_EVENT_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) static enum tep_event_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) process_dynamic_array(struct tep_event *event, struct tep_print_arg *arg, char **tok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) struct tep_format_field *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) enum tep_event_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) char *token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) memset(arg, 0, sizeof(*arg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) arg->type = TEP_PRINT_DYNAMIC_ARRAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) * The item within the parenthesis is another field that holds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) * the index into where the array starts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) type = read_token(&token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) *tok = token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) if (type != TEP_EVENT_ITEM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) /* Find the field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) field = tep_find_field(event, token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) if (!field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) arg->dynarray.field = field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) arg->dynarray.index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) if (read_expected(TEP_EVENT_DELIM, ")") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) type = read_token_item(&token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) *tok = token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) if (type != TEP_EVENT_OP || strcmp(token, "[") != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) return type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) arg = alloc_arg();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) if (!arg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) do_warning_event(event, "%s: not enough memory!", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) *tok = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) return TEP_EVENT_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) type = process_arg(event, arg, &token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) if (type == TEP_EVENT_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) goto out_free_arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) if (!test_type_token(type, token, TEP_EVENT_OP, "]"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) goto out_free_arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) type = read_token_item(tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) return type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) out_free_arg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) free_arg(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) *tok = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) return TEP_EVENT_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) static enum tep_event_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) process_dynamic_array_len(struct tep_event *event, struct tep_print_arg *arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) char **tok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) struct tep_format_field *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) enum tep_event_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) char *token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) if (read_expect_type(TEP_EVENT_ITEM, &token) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) arg->type = TEP_PRINT_DYNAMIC_ARRAY_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) /* Find the field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) field = tep_find_field(event, token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) if (!field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) arg->dynarray.field = field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) arg->dynarray.index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) if (read_expected(TEP_EVENT_DELIM, ")") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) type = read_token(&token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) *tok = token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) return type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) *tok = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) return TEP_EVENT_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) static enum tep_event_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) process_paren(struct tep_event *event, struct tep_print_arg *arg, char **tok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) struct tep_print_arg *item_arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) enum tep_event_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) char *token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) type = process_arg(event, arg, &token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) if (type == TEP_EVENT_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) if (type == TEP_EVENT_OP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) type = process_op(event, arg, &token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) if (type == TEP_EVENT_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) if (test_type_token(type, token, TEP_EVENT_DELIM, ")"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) type = read_token_item(&token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) * If the next token is an item or another open paren, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) * this was a typecast.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) if (event_item_type(type) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) (type == TEP_EVENT_DELIM && strcmp(token, "(") == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) /* make this a typecast and contine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) /* prevous must be an atom */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) if (arg->type != TEP_PRINT_ATOM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) do_warning_event(event, "previous needed to be TEP_PRINT_ATOM");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) item_arg = alloc_arg();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) if (!item_arg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) do_warning_event(event, "%s: not enough memory!",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) arg->type = TEP_PRINT_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) arg->typecast.type = arg->atom.atom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) arg->typecast.item = item_arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) type = process_arg_token(event, item_arg, &token, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) *tok = token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) return type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) *tok = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) return TEP_EVENT_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) static enum tep_event_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) process_str(struct tep_event *event __maybe_unused, struct tep_print_arg *arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) char **tok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) enum tep_event_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) char *token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) if (read_expect_type(TEP_EVENT_ITEM, &token) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) arg->type = TEP_PRINT_STRING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) arg->string.string = token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) arg->string.offset = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) if (read_expected(TEP_EVENT_DELIM, ")") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) type = read_token(&token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) *tok = token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) return type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) *tok = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) return TEP_EVENT_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) static enum tep_event_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) process_bitmask(struct tep_event *event __maybe_unused, struct tep_print_arg *arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) char **tok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) enum tep_event_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) char *token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) if (read_expect_type(TEP_EVENT_ITEM, &token) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) arg->type = TEP_PRINT_BITMASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) arg->bitmask.bitmask = token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) arg->bitmask.offset = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) if (read_expected(TEP_EVENT_DELIM, ")") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) type = read_token(&token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) *tok = token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) return type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) *tok = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) return TEP_EVENT_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) static struct tep_function_handler *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) find_func_handler(struct tep_handle *tep, char *func_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) struct tep_function_handler *func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) if (!tep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) for (func = tep->func_handlers; func; func = func->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) if (strcmp(func->name, func_name) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) return func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) static void remove_func_handler(struct tep_handle *tep, char *func_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) struct tep_function_handler *func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) struct tep_function_handler **next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) next = &tep->func_handlers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) while ((func = *next)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) if (strcmp(func->name, func_name) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) *next = func->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) free_func_handle(func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) next = &func->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) static enum tep_event_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) process_func_handler(struct tep_event *event, struct tep_function_handler *func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) struct tep_print_arg *arg, char **tok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) struct tep_print_arg **next_arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) struct tep_print_arg *farg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) enum tep_event_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) char *token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) arg->type = TEP_PRINT_FUNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) arg->func.func = func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) *tok = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) next_arg = &(arg->func.args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) for (i = 0; i < func->nr_args; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) farg = alloc_arg();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) if (!farg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) do_warning_event(event, "%s: not enough memory!",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) return TEP_EVENT_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) type = process_arg(event, farg, &token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) if (i < (func->nr_args - 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) if (type != TEP_EVENT_DELIM || strcmp(token, ",") != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) do_warning_event(event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) "Error: function '%s()' expects %d arguments but event %s only uses %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) func->name, func->nr_args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) event->name, i + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) if (type != TEP_EVENT_DELIM || strcmp(token, ")") != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) do_warning_event(event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) "Error: function '%s()' only expects %d arguments but event %s has more",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) func->name, func->nr_args, event->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) *next_arg = farg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) next_arg = &(farg->next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) type = read_token(&token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) *tok = token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) return type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) free_arg(farg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) return TEP_EVENT_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) static enum tep_event_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) process_builtin_expect(struct tep_event *event, struct tep_print_arg *arg, char **tok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) enum tep_event_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) char *token = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) /* Handle __builtin_expect( cond, #) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) type = process_arg(event, arg, &token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) if (type != TEP_EVENT_DELIM || token[0] != ',')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) /* We don't care what the second parameter is of the __builtin_expect() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) if (read_expect_type(TEP_EVENT_ITEM, &token) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) if (read_expected(TEP_EVENT_DELIM, ")") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) type = read_token_item(tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) return type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) *tok = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) return TEP_EVENT_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) static enum tep_event_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) process_function(struct tep_event *event, struct tep_print_arg *arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) char *token, char **tok)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) struct tep_function_handler *func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) if (strcmp(token, "__print_flags") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) is_flag_field = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) return process_flags(event, arg, tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) if (strcmp(token, "__print_symbolic") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) is_symbolic_field = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) return process_symbols(event, arg, tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) if (strcmp(token, "__print_hex") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) return process_hex(event, arg, tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) if (strcmp(token, "__print_hex_str") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) return process_hex_str(event, arg, tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) if (strcmp(token, "__print_array") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) return process_int_array(event, arg, tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) if (strcmp(token, "__get_str") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) return process_str(event, arg, tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) if (strcmp(token, "__get_bitmask") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) return process_bitmask(event, arg, tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) if (strcmp(token, "__get_dynamic_array") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) return process_dynamic_array(event, arg, tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) if (strcmp(token, "__get_dynamic_array_len") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) return process_dynamic_array_len(event, arg, tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) if (strcmp(token, "__builtin_expect") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) return process_builtin_expect(event, arg, tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) func = find_func_handler(event->tep, token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) if (func) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) return process_func_handler(event, func, arg, tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) do_warning_event(event, "function %s not defined", token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) return TEP_EVENT_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) static enum tep_event_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) process_arg_token(struct tep_event *event, struct tep_print_arg *arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) char **tok, enum tep_event_type type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) char *token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) char *atom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) token = *tok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) case TEP_EVENT_ITEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) if (strcmp(token, "REC") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) type = process_entry(event, arg, &token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) atom = token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) /* test the next token */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) type = read_token_item(&token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) * If the next token is a parenthesis, then this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) * is a function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) if (type == TEP_EVENT_DELIM && strcmp(token, "(") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) token = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) /* this will free atom. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) type = process_function(event, arg, atom, &token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) /* atoms can be more than one token long */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) while (type == TEP_EVENT_ITEM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) ret = append(&atom, " ", token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) free(atom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) *tok = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) return TEP_EVENT_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) type = read_token_item(&token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) arg->type = TEP_PRINT_ATOM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) arg->atom.atom = atom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) case TEP_EVENT_DQUOTE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) case TEP_EVENT_SQUOTE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) arg->type = TEP_PRINT_ATOM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) arg->atom.atom = token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) type = read_token_item(&token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) case TEP_EVENT_DELIM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) if (strcmp(token, "(") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) type = process_paren(event, arg, &token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) case TEP_EVENT_OP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) /* handle single ops */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) arg->type = TEP_PRINT_OP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) arg->op.op = token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) arg->op.left = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) type = process_op(event, arg, &token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) /* On error, the op is freed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) if (type == TEP_EVENT_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) arg->op.op = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) /* return error type if errored */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) case TEP_EVENT_ERROR ... TEP_EVENT_NEWLINE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) do_warning_event(event, "unexpected type %d", type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) return TEP_EVENT_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) *tok = token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) return type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) static int event_read_print_args(struct tep_event *event, struct tep_print_arg **list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) enum tep_event_type type = TEP_EVENT_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) struct tep_print_arg *arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) char *token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) int args = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) if (type == TEP_EVENT_NEWLINE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) type = read_token_item(&token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) arg = alloc_arg();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) if (!arg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) do_warning_event(event, "%s: not enough memory!",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) type = process_arg(event, arg, &token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) if (type == TEP_EVENT_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) free_arg(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) *list = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) args++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) if (type == TEP_EVENT_OP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) type = process_op(event, arg, &token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) if (type == TEP_EVENT_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) *list = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) free_arg(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) list = &arg->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) if (type == TEP_EVENT_DELIM && strcmp(token, ",") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) *list = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) list = &arg->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) } while (type != TEP_EVENT_NONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) if (type != TEP_EVENT_NONE && type != TEP_EVENT_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) return args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) static int event_read_print(struct tep_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) enum tep_event_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) char *token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) if (read_expected_item(TEP_EVENT_ITEM, "print") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) if (read_expected(TEP_EVENT_ITEM, "fmt") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) if (read_expected(TEP_EVENT_OP, ":") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) if (read_expect_type(TEP_EVENT_DQUOTE, &token) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) concat:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) event->print_fmt.format = token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) event->print_fmt.args = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) /* ok to have no arg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) type = read_token_item(&token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) if (type == TEP_EVENT_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) /* Handle concatenation of print lines */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) if (type == TEP_EVENT_DQUOTE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) char *cat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) if (asprintf(&cat, "%s%s", event->print_fmt.format, token) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) free_token(event->print_fmt.format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) event->print_fmt.format = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) token = cat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) goto concat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) if (test_type_token(type, token, TEP_EVENT_DELIM, ","))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) ret = event_read_print_args(event, &event->print_fmt.args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) * tep_find_common_field - return a common field by event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) * @event: handle for the event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) * @name: the name of the common field to return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) * Returns a common field from the event by the given @name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) * This only searches the common fields and not all field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) struct tep_format_field *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) tep_find_common_field(struct tep_event *event, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) struct tep_format_field *format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) for (format = event->format.common_fields;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) format; format = format->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) if (strcmp(format->name, name) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) return format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) * tep_find_field - find a non-common field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) * @event: handle for the event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) * @name: the name of the non-common field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) * Returns a non-common field by the given @name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) * This does not search common fields.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) struct tep_format_field *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) tep_find_field(struct tep_event *event, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) struct tep_format_field *format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) for (format = event->format.fields;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) format; format = format->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) if (strcmp(format->name, name) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) return format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) * tep_find_any_field - find any field by name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) * @event: handle for the event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) * @name: the name of the field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) * Returns a field by the given @name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) * This searches the common field names first, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) * the non-common ones if a common one was not found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) struct tep_format_field *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) tep_find_any_field(struct tep_event *event, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) struct tep_format_field *format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) format = tep_find_common_field(event, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) if (format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) return format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) return tep_find_field(event, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) * tep_read_number - read a number from data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) * @tep: a handle to the trace event parser context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) * @ptr: the raw data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) * @size: the size of the data that holds the number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) * Returns the number (converted to host) from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) * raw data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) unsigned long long tep_read_number(struct tep_handle *tep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) const void *ptr, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) unsigned long long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) switch (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) return *(unsigned char *)ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) return data2host2(tep, *(unsigned short *)ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) return data2host4(tep, *(unsigned int *)ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) memcpy(&val, (ptr), sizeof(unsigned long long));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) return data2host8(tep, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) /* BUG! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) * tep_read_number_field - read a number from data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) * @field: a handle to the field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) * @data: the raw data to read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) * @value: the value to place the number in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) * Reads raw data according to a field offset and size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) * and translates it into @value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) * Returns 0 on success, -1 otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) int tep_read_number_field(struct tep_format_field *field, const void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) unsigned long long *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) if (!field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) switch (field->size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) *value = tep_read_number(field->event->tep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) data + field->offset, field->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) static int get_common_info(struct tep_handle *tep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) const char *type, int *offset, int *size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) struct tep_event *event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) struct tep_format_field *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) * All events should have the same common elements.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) * Pick any event to find where the type is;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) if (!tep->events) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) do_warning("no event_list!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) event = tep->events[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) field = tep_find_common_field(event, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) if (!field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) *offset = field->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) *size = field->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) static int __parse_common(struct tep_handle *tep, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) int *size, int *offset, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) if (!*size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) ret = get_common_info(tep, name, offset, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) return tep_read_number(tep, data + *offset, *size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) static int trace_parse_common_type(struct tep_handle *tep, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) return __parse_common(tep, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) &tep->type_size, &tep->type_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) "common_type");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) static int parse_common_pid(struct tep_handle *tep, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) return __parse_common(tep, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) &tep->pid_size, &tep->pid_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) "common_pid");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) static int parse_common_pc(struct tep_handle *tep, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) return __parse_common(tep, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) &tep->pc_size, &tep->pc_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) "common_preempt_count");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) static int parse_common_flags(struct tep_handle *tep, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) return __parse_common(tep, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) &tep->flags_size, &tep->flags_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) "common_flags");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) static int parse_common_lock_depth(struct tep_handle *tep, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) return __parse_common(tep, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) &tep->ld_size, &tep->ld_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) "common_lock_depth");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) static int parse_common_migrate_disable(struct tep_handle *tep, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) return __parse_common(tep, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) &tep->ld_size, &tep->ld_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) "common_migrate_disable");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) static int events_id_cmp(const void *a, const void *b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) * tep_find_event - find an event by given id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) * @tep: a handle to the trace event parser context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) * @id: the id of the event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) * Returns an event that has a given @id.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) struct tep_event *tep_find_event(struct tep_handle *tep, int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) struct tep_event **eventptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) struct tep_event key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) struct tep_event *pkey = &key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) /* Check cache first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) if (tep->last_event && tep->last_event->id == id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) return tep->last_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) key.id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) eventptr = bsearch(&pkey, tep->events, tep->nr_events,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) sizeof(*tep->events), events_id_cmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) if (eventptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) tep->last_event = *eventptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) return *eventptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) * tep_find_event_by_name - find an event by given name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) * @tep: a handle to the trace event parser context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) * @sys: the system name to search for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) * @name: the name of the event to search for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) * This returns an event with a given @name and under the system
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) * @sys. If @sys is NULL the first event with @name is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) struct tep_event *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) tep_find_event_by_name(struct tep_handle *tep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) const char *sys, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) struct tep_event *event = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) if (tep->last_event &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) strcmp(tep->last_event->name, name) == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) (!sys || strcmp(tep->last_event->system, sys) == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) return tep->last_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) for (i = 0; i < tep->nr_events; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) event = tep->events[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) if (strcmp(event->name, name) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) if (!sys)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) if (strcmp(event->system, sys) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) if (i == tep->nr_events)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) event = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) tep->last_event = event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) return event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) static unsigned long long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) eval_num_arg(void *data, int size, struct tep_event *event, struct tep_print_arg *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) struct tep_handle *tep = event->tep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) unsigned long long val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) unsigned long long left, right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) struct tep_print_arg *typearg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) struct tep_print_arg *larg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) unsigned long offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) unsigned int field_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) switch (arg->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) case TEP_PRINT_NULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) /* ?? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) case TEP_PRINT_ATOM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) return strtoull(arg->atom.atom, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) case TEP_PRINT_FIELD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) if (!arg->field.field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) arg->field.field = tep_find_any_field(event, arg->field.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) if (!arg->field.field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) goto out_warning_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) /* must be a number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) val = tep_read_number(tep, data + arg->field.field->offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) arg->field.field->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) case TEP_PRINT_FLAGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) case TEP_PRINT_SYMBOL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) case TEP_PRINT_INT_ARRAY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) case TEP_PRINT_HEX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) case TEP_PRINT_HEX_STR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) case TEP_PRINT_TYPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) val = eval_num_arg(data, size, event, arg->typecast.item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) return eval_type(val, arg, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) case TEP_PRINT_STRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) case TEP_PRINT_BSTRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) case TEP_PRINT_BITMASK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) case TEP_PRINT_FUNC: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) struct trace_seq s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675) trace_seq_init(&s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) val = process_defined_func(&s, data, size, event, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) trace_seq_destroy(&s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) case TEP_PRINT_OP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) if (strcmp(arg->op.op, "[") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) * Arrays are special, since we don't want
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) * to read the arg as is.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) right = eval_num_arg(data, size, event, arg->op.right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) /* handle typecasts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) larg = arg->op.left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) while (larg->type == TEP_PRINT_TYPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) if (!typearg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) typearg = larg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) larg = larg->typecast.item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) /* Default to long size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) field_size = tep->long_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) switch (larg->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) case TEP_PRINT_DYNAMIC_ARRAY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) offset = tep_read_number(tep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) data + larg->dynarray.field->offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) larg->dynarray.field->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) if (larg->dynarray.field->elementsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705) field_size = larg->dynarray.field->elementsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) * The actual length of the dynamic array is stored
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) * in the top half of the field, and the offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) * is in the bottom half of the 32 bit field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) offset &= 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) offset += right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) case TEP_PRINT_FIELD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) if (!larg->field.field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) larg->field.field =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) tep_find_any_field(event, larg->field.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) if (!larg->field.field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) arg = larg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) goto out_warning_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) field_size = larg->field.field->elementsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) offset = larg->field.field->offset +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) right * larg->field.field->elementsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) goto default_op; /* oops, all bets off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) val = tep_read_number(tep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) data + offset, field_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) if (typearg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) val = eval_type(val, typearg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) } else if (strcmp(arg->op.op, "?") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) left = eval_num_arg(data, size, event, arg->op.left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) arg = arg->op.right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) if (left)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) val = eval_num_arg(data, size, event, arg->op.left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) val = eval_num_arg(data, size, event, arg->op.right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) default_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) left = eval_num_arg(data, size, event, arg->op.left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) right = eval_num_arg(data, size, event, arg->op.right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) switch (arg->op.op[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) case '!':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) switch (arg->op.op[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) val = !right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) case '=':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754) val = left != right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757) goto out_warning_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) case '~':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) val = ~right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) case '|':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) if (arg->op.op[1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) val = left || right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) val = left | right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) case '&':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) if (arg->op.op[1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) val = left && right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) val = left & right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) case '<':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) switch (arg->op.op[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) val = left < right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) case '<':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781) val = left << right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) case '=':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) val = left <= right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) goto out_warning_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) case '>':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) switch (arg->op.op[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) val = left > right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) case '>':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) val = left >> right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) case '=':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) val = left >= right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) goto out_warning_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) case '=':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) if (arg->op.op[1] != '=')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) goto out_warning_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) val = left == right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) case '-':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) val = left - right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) case '+':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) val = left + right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) case '/':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) val = left / right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) case '%':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) val = left % right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) case '*':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) val = left * right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) goto out_warning_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) case TEP_PRINT_DYNAMIC_ARRAY_LEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) offset = tep_read_number(tep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) data + arg->dynarray.field->offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) arg->dynarray.field->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) * The total allocated length of the dynamic array is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836) * stored in the top half of the field, and the offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) * is in the bottom half of the 32 bit field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) val = (unsigned long long)(offset >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) case TEP_PRINT_DYNAMIC_ARRAY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) /* Without [], we pass the address to the dynamic data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) offset = tep_read_number(tep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) data + arg->dynarray.field->offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845) arg->dynarray.field->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) * The total allocated length of the dynamic array is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) * stored in the top half of the field, and the offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) * is in the bottom half of the 32 bit field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) offset &= 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) val = (unsigned long long)((unsigned long)data + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) default: /* not sure what to do there */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) out_warning_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) do_warning_event(event, "%s: unknown op '%s'", __func__, arg->op.op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) out_warning_field:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) do_warning_event(event, "%s: field %s not found",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) __func__, arg->field.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869) struct flag {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) unsigned long long value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874) static const struct flag flags[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) { "HI_SOFTIRQ", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) { "TIMER_SOFTIRQ", 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) { "NET_TX_SOFTIRQ", 2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) { "NET_RX_SOFTIRQ", 3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) { "BLOCK_SOFTIRQ", 4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) { "IRQ_POLL_SOFTIRQ", 5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) { "TASKLET_SOFTIRQ", 6 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) { "SCHED_SOFTIRQ", 7 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) { "HRTIMER_SOFTIRQ", 8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884) { "RCU_SOFTIRQ", 9 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) { "HRTIMER_NORESTART", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887) { "HRTIMER_RESTART", 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) static long long eval_flag(const char *flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) * Some flags in the format files do not get converted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) * If the flag is not numeric, see if it is something that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) * we already know about.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899) if (isdigit(flag[0]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900) return strtoull(flag, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902) for (i = 0; i < (int)(sizeof(flags)/sizeof(flags[0])); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) if (strcmp(flags[i].name, flag) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904) return flags[i].value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) return -1LL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909) static void print_str_to_seq(struct trace_seq *s, const char *format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) int len_arg, const char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912) if (len_arg >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) trace_seq_printf(s, format, len_arg, str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915) trace_seq_printf(s, format, str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) static void print_bitmask_to_seq(struct tep_handle *tep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919) struct trace_seq *s, const char *format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920) int len_arg, const void *data, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922) int nr_bits = size * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923) int str_size = (nr_bits + 3) / 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) int len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925) char buf[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) char *str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927) int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931) * The kernel likes to put in commas every 32 bits, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) * can do the same.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) str_size += (nr_bits - 1) / 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936) str = malloc(str_size + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937) if (!str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938) do_warning("%s: not enough memory!", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941) str[str_size] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943) /* Start out with -2 for the two chars per byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944) for (i = str_size - 2; i >= 0; i -= 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946) * data points to a bit mask of size bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947) * In the kernel, this is an array of long words, thus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948) * endianness is very important.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950) if (tep->file_bigendian)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951) index = size - (len + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) index = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955) snprintf(buf, 3, "%02x", *((unsigned char *)data + index));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956) memcpy(str + i, buf, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957) len++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958) if (!(len & 3) && i > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959) i--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960) str[i] = ',';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964) if (len_arg >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965) trace_seq_printf(s, format, len_arg, str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967) trace_seq_printf(s, format, str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969) free(str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972) static void print_str_arg(struct trace_seq *s, void *data, int size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973) struct tep_event *event, const char *format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974) int len_arg, struct tep_print_arg *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) struct tep_handle *tep = event->tep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977) struct tep_print_flag_sym *flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) struct tep_format_field *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979) struct printk_map *printk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980) long long val, fval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981) unsigned long long addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982) char *str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983) unsigned char *hex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984) int print;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985) int i, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987) switch (arg->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988) case TEP_PRINT_NULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989) /* ?? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991) case TEP_PRINT_ATOM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992) print_str_to_seq(s, format, len_arg, arg->atom.atom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994) case TEP_PRINT_FIELD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995) field = arg->field.field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996) if (!field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997) field = tep_find_any_field(event, arg->field.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998) if (!field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999) str = arg->field.name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000) goto out_warning_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002) arg->field.field = field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004) /* Zero sized fields, mean the rest of the data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005) len = field->size ? : size - field->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008) * Some events pass in pointers. If this is not an array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009) * and the size is the same as long_size, assume that it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010) * is a pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012) if (!(field->flags & TEP_FIELD_IS_ARRAY) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013) field->size == tep->long_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015) /* Handle heterogeneous recording and processing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016) * architectures
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018) * CASE I:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019) * Traces recorded on 32-bit devices (32-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020) * addressing) and processed on 64-bit devices:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021) * In this case, only 32 bits should be read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023) * CASE II:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024) * Traces recorded on 64 bit devices and processed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025) * on 32-bit devices:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026) * In this case, 64 bits must be read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028) addr = (tep->long_size == 8) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029) *(unsigned long long *)(data + field->offset) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030) (unsigned long long)*(unsigned int *)(data + field->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032) /* Check if it matches a print format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033) printk = find_printk(tep, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034) if (printk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035) trace_seq_puts(s, printk->printk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037) trace_seq_printf(s, "%llx", addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040) str = malloc(len + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041) if (!str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042) do_warning_event(event, "%s: not enough memory!",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046) memcpy(str, data + field->offset, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047) str[len] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048) print_str_to_seq(s, format, len_arg, str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049) free(str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051) case TEP_PRINT_FLAGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052) val = eval_num_arg(data, size, event, arg->flags.field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053) print = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054) for (flag = arg->flags.flags; flag; flag = flag->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055) fval = eval_flag(flag->value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056) if (!val && fval < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057) print_str_to_seq(s, format, len_arg, flag->str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060) if (fval > 0 && (val & fval) == fval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061) if (print && arg->flags.delim)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062) trace_seq_puts(s, arg->flags.delim);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4063) print_str_to_seq(s, format, len_arg, flag->str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4064) print = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4065) val &= ~fval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4066) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4067) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4068) if (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4069) if (print && arg->flags.delim)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4070) trace_seq_puts(s, arg->flags.delim);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4071) trace_seq_printf(s, "0x%llx", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4073) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4074) case TEP_PRINT_SYMBOL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4075) val = eval_num_arg(data, size, event, arg->symbol.field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4076) for (flag = arg->symbol.symbols; flag; flag = flag->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4077) fval = eval_flag(flag->value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4078) if (val == fval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4079) print_str_to_seq(s, format, len_arg, flag->str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4080) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4081) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4083) if (!flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4084) trace_seq_printf(s, "0x%llx", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4085) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4086) case TEP_PRINT_HEX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4087) case TEP_PRINT_HEX_STR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4088) if (arg->hex.field->type == TEP_PRINT_DYNAMIC_ARRAY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4089) unsigned long offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4090) offset = tep_read_number(tep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4091) data + arg->hex.field->dynarray.field->offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4092) arg->hex.field->dynarray.field->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4093) hex = data + (offset & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4094) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4095) field = arg->hex.field->field.field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4096) if (!field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4097) str = arg->hex.field->field.name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4098) field = tep_find_any_field(event, str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4099) if (!field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4100) goto out_warning_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4101) arg->hex.field->field.field = field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4103) hex = data + field->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4105) len = eval_num_arg(data, size, event, arg->hex.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4106) for (i = 0; i < len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4107) if (i && arg->type == TEP_PRINT_HEX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4108) trace_seq_putc(s, ' ');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4109) trace_seq_printf(s, "%02x", hex[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4111) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4113) case TEP_PRINT_INT_ARRAY: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4114) void *num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4115) int el_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4117) if (arg->int_array.field->type == TEP_PRINT_DYNAMIC_ARRAY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4118) unsigned long offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4119) struct tep_format_field *field =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4120) arg->int_array.field->dynarray.field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4121) offset = tep_read_number(tep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4122) data + field->offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4123) field->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4124) num = data + (offset & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4125) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4126) field = arg->int_array.field->field.field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4127) if (!field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4128) str = arg->int_array.field->field.name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4129) field = tep_find_any_field(event, str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4130) if (!field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4131) goto out_warning_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4132) arg->int_array.field->field.field = field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4134) num = data + field->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4136) len = eval_num_arg(data, size, event, arg->int_array.count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4137) el_size = eval_num_arg(data, size, event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4138) arg->int_array.el_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4139) for (i = 0; i < len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4140) if (i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4141) trace_seq_putc(s, ' ');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4143) if (el_size == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4144) trace_seq_printf(s, "%u", *(uint8_t *)num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4145) } else if (el_size == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4146) trace_seq_printf(s, "%u", *(uint16_t *)num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4147) } else if (el_size == 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4148) trace_seq_printf(s, "%u", *(uint32_t *)num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4149) } else if (el_size == 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4150) trace_seq_printf(s, "%"PRIu64, *(uint64_t *)num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4151) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4152) trace_seq_printf(s, "BAD SIZE:%d 0x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4153) el_size, *(uint8_t *)num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4154) el_size = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4157) num += el_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4159) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4161) case TEP_PRINT_TYPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4162) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4163) case TEP_PRINT_STRING: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4164) int str_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4166) if (arg->string.offset == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4167) struct tep_format_field *f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4169) f = tep_find_any_field(event, arg->string.string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4170) arg->string.offset = f->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4172) str_offset = data2host4(tep, *(unsigned int *)(data + arg->string.offset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4173) str_offset &= 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4174) print_str_to_seq(s, format, len_arg, ((char *)data) + str_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4175) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4177) case TEP_PRINT_BSTRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4178) print_str_to_seq(s, format, len_arg, arg->string.string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4179) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4180) case TEP_PRINT_BITMASK: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4181) int bitmask_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4182) int bitmask_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4184) if (arg->bitmask.offset == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4185) struct tep_format_field *f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4187) f = tep_find_any_field(event, arg->bitmask.bitmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4188) arg->bitmask.offset = f->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4190) bitmask_offset = data2host4(tep, *(unsigned int *)(data + arg->bitmask.offset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4191) bitmask_size = bitmask_offset >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4192) bitmask_offset &= 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4193) print_bitmask_to_seq(tep, s, format, len_arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4194) data + bitmask_offset, bitmask_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4195) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4197) case TEP_PRINT_OP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4198) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4199) * The only op for string should be ? :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4200) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4201) if (arg->op.op[0] != '?')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4202) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4203) val = eval_num_arg(data, size, event, arg->op.left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4204) if (val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4205) print_str_arg(s, data, size, event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4206) format, len_arg, arg->op.right->op.left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4207) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4208) print_str_arg(s, data, size, event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4209) format, len_arg, arg->op.right->op.right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4210) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4211) case TEP_PRINT_FUNC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4212) process_defined_func(s, data, size, event, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4213) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4214) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4215) /* well... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4216) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4219) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4221) out_warning_field:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4222) do_warning_event(event, "%s: field %s not found",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4223) __func__, arg->field.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4226) static unsigned long long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4227) process_defined_func(struct trace_seq *s, void *data, int size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4228) struct tep_event *event, struct tep_print_arg *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4230) struct tep_function_handler *func_handle = arg->func.func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4231) struct func_params *param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4232) unsigned long long *args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4233) unsigned long long ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4234) struct tep_print_arg *farg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4235) struct trace_seq str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4236) struct save_str {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4237) struct save_str *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4238) char *str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4239) } *strings = NULL, *string;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4240) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4242) if (!func_handle->nr_args) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4243) ret = (*func_handle->func)(s, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4244) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4247) farg = arg->func.args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4248) param = func_handle->params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4250) ret = ULLONG_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4251) args = malloc(sizeof(*args) * func_handle->nr_args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4252) if (!args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4253) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4255) for (i = 0; i < func_handle->nr_args; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4256) switch (param->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4257) case TEP_FUNC_ARG_INT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4258) case TEP_FUNC_ARG_LONG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4259) case TEP_FUNC_ARG_PTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4260) args[i] = eval_num_arg(data, size, event, farg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4261) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4262) case TEP_FUNC_ARG_STRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4263) trace_seq_init(&str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4264) print_str_arg(&str, data, size, event, "%s", -1, farg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4265) trace_seq_terminate(&str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4266) string = malloc(sizeof(*string));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4267) if (!string) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4268) do_warning_event(event, "%s(%d): malloc str",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4269) __func__, __LINE__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4270) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4272) string->next = strings;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4273) string->str = strdup(str.buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4274) if (!string->str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4275) free(string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4276) do_warning_event(event, "%s(%d): malloc str",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4277) __func__, __LINE__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4278) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4280) args[i] = (uintptr_t)string->str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4281) strings = string;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4282) trace_seq_destroy(&str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4283) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4284) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4285) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4286) * Something went totally wrong, this is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4287) * an input error, something in this code broke.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4288) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4289) do_warning_event(event, "Unexpected end of arguments\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4290) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4292) farg = farg->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4293) param = param->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4296) ret = (*func_handle->func)(s, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4297) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4298) free(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4299) while (strings) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4300) string = strings;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4301) strings = string->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4302) free(string->str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4303) free(string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4306) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4307) /* TBD : handle return type here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4308) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4311) static void free_args(struct tep_print_arg *args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4313) struct tep_print_arg *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4315) while (args) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4316) next = args->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4318) free_arg(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4319) args = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4323) static struct tep_print_arg *make_bprint_args(char *fmt, void *data, int size, struct tep_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4324) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4325) struct tep_handle *tep = event->tep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4326) struct tep_format_field *field, *ip_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4327) struct tep_print_arg *args, *arg, **next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4328) unsigned long long ip, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4329) char *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4330) void *bptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4331) int vsize = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4333) field = tep->bprint_buf_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4334) ip_field = tep->bprint_ip_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4336) if (!field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4337) field = tep_find_field(event, "buf");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4338) if (!field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4339) do_warning_event(event, "can't find buffer field for binary printk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4340) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4342) ip_field = tep_find_field(event, "ip");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4343) if (!ip_field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4344) do_warning_event(event, "can't find ip field for binary printk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4345) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4347) tep->bprint_buf_field = field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4348) tep->bprint_ip_field = ip_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4351) ip = tep_read_number(tep, data + ip_field->offset, ip_field->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4353) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4354) * The first arg is the IP pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4355) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4356) args = alloc_arg();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4357) if (!args) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4358) do_warning_event(event, "%s(%d): not enough memory!",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4359) __func__, __LINE__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4360) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4362) arg = args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4363) arg->next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4364) next = &arg->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4366) arg->type = TEP_PRINT_ATOM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4368) if (asprintf(&arg->atom.atom, "%lld", ip) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4369) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4371) /* skip the first "%ps: " */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4372) for (ptr = fmt + 5, bptr = data + field->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4373) bptr < data + size && *ptr; ptr++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4374) int ls = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4376) if (*ptr == '%') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4377) process_again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4378) ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4379) switch (*ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4380) case '%':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4381) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4382) case 'l':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4383) ls++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4384) goto process_again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4385) case 'L':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4386) ls = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4387) goto process_again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4388) case '0' ... '9':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4389) goto process_again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4390) case '.':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4391) goto process_again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4392) case 'z':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4393) case 'Z':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4394) ls = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4395) goto process_again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4396) case 'p':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4397) ls = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4398) if (isalnum(ptr[1])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4399) ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4400) /* Check for special pointers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4401) switch (*ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4402) case 's':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4403) case 'S':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4404) case 'x':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4405) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4406) case 'f':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4407) case 'F':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4408) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4409) * Pre-5.5 kernels use %pf and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4410) * %pF for printing symbols
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4411) * while kernels since 5.5 use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4412) * %pfw for fwnodes. So check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4413) * %p[fF] isn't followed by 'w'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4414) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4415) if (ptr[1] != 'w')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4416) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4417) /* fall through */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4418) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4419) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4420) * Older kernels do not process
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4421) * dereferenced pointers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4422) * Only process if the pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4423) * value is a printable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4424) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4425) if (isprint(*(char *)bptr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4426) goto process_string;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4429) /* fall through */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4430) case 'd':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4431) case 'u':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4432) case 'i':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4433) case 'x':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4434) case 'X':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4435) case 'o':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4436) switch (ls) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4437) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4438) vsize = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4439) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4440) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4441) vsize = tep->long_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4442) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4443) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4444) vsize = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4445) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4446) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4447) vsize = ls; /* ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4448) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4450) /* fall through */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4451) case '*':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4452) if (*ptr == '*')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4453) vsize = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4455) /* the pointers are always 4 bytes aligned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4456) bptr = (void *)(((unsigned long)bptr + 3) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4457) ~3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4458) val = tep_read_number(tep, bptr, vsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4459) bptr += vsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4460) arg = alloc_arg();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4461) if (!arg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4462) do_warning_event(event, "%s(%d): not enough memory!",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4463) __func__, __LINE__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4464) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4466) arg->next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4467) arg->type = TEP_PRINT_ATOM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4468) if (asprintf(&arg->atom.atom, "%lld", val) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4469) free(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4470) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4472) *next = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4473) next = &arg->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4474) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4475) * The '*' case means that an arg is used as the length.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4476) * We need to continue to figure out for what.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4477) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4478) if (*ptr == '*')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4479) goto process_again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4481) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4482) case 's':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4483) process_string:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4484) arg = alloc_arg();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4485) if (!arg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4486) do_warning_event(event, "%s(%d): not enough memory!",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4487) __func__, __LINE__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4488) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4490) arg->next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4491) arg->type = TEP_PRINT_BSTRING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4492) arg->string.string = strdup(bptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4493) if (!arg->string.string)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4494) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4495) bptr += strlen(bptr) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4496) *next = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4497) next = &arg->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4498) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4499) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4504) return args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4506) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4507) free_args(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4508) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4511) static char *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4512) get_bprint_format(void *data, int size __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4513) struct tep_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4514) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4515) struct tep_handle *tep = event->tep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4516) unsigned long long addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4517) struct tep_format_field *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4518) struct printk_map *printk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4519) char *format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4521) field = tep->bprint_fmt_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4523) if (!field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4524) field = tep_find_field(event, "fmt");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4525) if (!field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4526) do_warning_event(event, "can't find format field for binary printk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4527) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4529) tep->bprint_fmt_field = field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4532) addr = tep_read_number(tep, data + field->offset, field->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4534) printk = find_printk(tep, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4535) if (!printk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4536) if (asprintf(&format, "%%ps: (NO FORMAT FOUND at %llx)\n", addr) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4537) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4538) return format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4541) if (asprintf(&format, "%s: %s", "%ps", printk->printk) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4542) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4544) return format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4547) static int print_mac_arg(struct trace_seq *s, const char *format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4548) void *data, int size, struct tep_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4549) struct tep_print_arg *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4551) const char *fmt = "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4552) bool reverse = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4553) unsigned char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4554) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4556) if (arg->type == TEP_PRINT_FUNC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4557) process_defined_func(s, data, size, event, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4558) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4561) if (arg->type != TEP_PRINT_FIELD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4562) trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4563) arg->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4564) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4567) if (format[0] == 'm') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4568) fmt = "%.2x%.2x%.2x%.2x%.2x%.2x";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4569) } else if (format[0] == 'M' && format[1] == 'F') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4570) fmt = "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4571) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4573) if (format[1] == 'R') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4574) reverse = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4575) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4578) if (!arg->field.field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4579) arg->field.field =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4580) tep_find_any_field(event, arg->field.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4581) if (!arg->field.field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4582) do_warning_event(event, "%s: field %s not found",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4583) __func__, arg->field.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4584) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4587) if (arg->field.field->size != 6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4588) trace_seq_printf(s, "INVALIDMAC");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4589) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4592) buf = data + arg->field.field->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4593) if (reverse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4594) trace_seq_printf(s, fmt, buf[5], buf[4], buf[3], buf[2], buf[1], buf[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4595) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4596) trace_seq_printf(s, fmt, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4598) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4601) static int parse_ip4_print_args(struct tep_handle *tep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4602) const char *ptr, bool *reverse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4603) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4604) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4606) *reverse = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4608) /* hnbl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4609) switch (*ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4610) case 'h':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4611) if (tep->file_bigendian)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4612) *reverse = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4613) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4614) *reverse = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4615) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4616) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4617) case 'l':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4618) *reverse = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4619) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4620) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4621) case 'n':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4622) case 'b':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4623) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4624) /* fall through */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4625) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4626) *reverse = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4627) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4630) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4633) static void print_ip4_addr(struct trace_seq *s, char i, bool reverse, unsigned char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4634) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4635) const char *fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4637) if (i == 'i')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4638) fmt = "%03d.%03d.%03d.%03d";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4639) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4640) fmt = "%d.%d.%d.%d";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4642) if (reverse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4643) trace_seq_printf(s, fmt, buf[3], buf[2], buf[1], buf[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4644) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4645) trace_seq_printf(s, fmt, buf[0], buf[1], buf[2], buf[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4649) static inline bool ipv6_addr_v4mapped(const struct in6_addr *a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4650) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4651) return ((unsigned long)(a->s6_addr32[0] | a->s6_addr32[1]) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4652) (unsigned long)(a->s6_addr32[2] ^ htonl(0x0000ffff))) == 0UL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4655) static inline bool ipv6_addr_is_isatap(const struct in6_addr *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4656) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4657) return (addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4660) static void print_ip6c_addr(struct trace_seq *s, unsigned char *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4661) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4662) int i, j, range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4663) unsigned char zerolength[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4664) int longest = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4665) int colonpos = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4666) uint16_t word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4667) uint8_t hi, lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4668) bool needcolon = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4669) bool useIPv4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4670) struct in6_addr in6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4672) memcpy(&in6, addr, sizeof(struct in6_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4674) useIPv4 = ipv6_addr_v4mapped(&in6) || ipv6_addr_is_isatap(&in6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4676) memset(zerolength, 0, sizeof(zerolength));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4678) if (useIPv4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4679) range = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4680) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4681) range = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4683) /* find position of longest 0 run */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4684) for (i = 0; i < range; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4685) for (j = i; j < range; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4686) if (in6.s6_addr16[j] != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4687) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4688) zerolength[i]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4691) for (i = 0; i < range; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4692) if (zerolength[i] > longest) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4693) longest = zerolength[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4694) colonpos = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4697) if (longest == 1) /* don't compress a single 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4698) colonpos = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4700) /* emit address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4701) for (i = 0; i < range; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4702) if (i == colonpos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4703) if (needcolon || i == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4704) trace_seq_printf(s, ":");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4705) trace_seq_printf(s, ":");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4706) needcolon = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4707) i += longest - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4708) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4710) if (needcolon) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4711) trace_seq_printf(s, ":");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4712) needcolon = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4714) /* hex u16 without leading 0s */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4715) word = ntohs(in6.s6_addr16[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4716) hi = word >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4717) lo = word & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4718) if (hi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4719) trace_seq_printf(s, "%x%02x", hi, lo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4720) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4721) trace_seq_printf(s, "%x", lo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4723) needcolon = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4726) if (useIPv4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4727) if (needcolon)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4728) trace_seq_printf(s, ":");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4729) print_ip4_addr(s, 'I', false, &in6.s6_addr[12]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4732) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4735) static void print_ip6_addr(struct trace_seq *s, char i, unsigned char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4736) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4737) int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4739) for (j = 0; j < 16; j += 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4740) trace_seq_printf(s, "%02x%02x", buf[j], buf[j+1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4741) if (i == 'I' && j < 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4742) trace_seq_printf(s, ":");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4746) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4747) * %pi4 print an IPv4 address with leading zeros
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4748) * %pI4 print an IPv4 address without leading zeros
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4749) * %pi6 print an IPv6 address without colons
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4750) * %pI6 print an IPv6 address with colons
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4751) * %pI6c print an IPv6 address in compressed form with colons
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4752) * %pISpc print an IP address based on sockaddr; p adds port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4753) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4754) static int print_ipv4_arg(struct trace_seq *s, const char *ptr, char i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4755) void *data, int size, struct tep_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4756) struct tep_print_arg *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4757) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4758) bool reverse = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4759) unsigned char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4760) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4762) ret = parse_ip4_print_args(event->tep, ptr, &reverse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4764) if (arg->type == TEP_PRINT_FUNC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4765) process_defined_func(s, data, size, event, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4766) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4769) if (arg->type != TEP_PRINT_FIELD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4770) trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4771) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4774) if (!arg->field.field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4775) arg->field.field =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4776) tep_find_any_field(event, arg->field.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4777) if (!arg->field.field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4778) do_warning("%s: field %s not found",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4779) __func__, arg->field.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4780) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4784) buf = data + arg->field.field->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4786) if (arg->field.field->size != 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4787) trace_seq_printf(s, "INVALIDIPv4");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4788) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4791) print_ip4_addr(s, i, reverse, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4792) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4796) static int print_ipv6_arg(struct trace_seq *s, const char *ptr, char i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4797) void *data, int size, struct tep_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4798) struct tep_print_arg *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4799) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4800) char have_c = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4801) unsigned char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4802) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4804) /* pI6c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4805) if (i == 'I' && *ptr == 'c') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4806) have_c = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4807) ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4808) rc++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4811) if (arg->type == TEP_PRINT_FUNC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4812) process_defined_func(s, data, size, event, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4813) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4816) if (arg->type != TEP_PRINT_FIELD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4817) trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4818) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4821) if (!arg->field.field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4822) arg->field.field =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4823) tep_find_any_field(event, arg->field.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4824) if (!arg->field.field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4825) do_warning("%s: field %s not found",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4826) __func__, arg->field.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4827) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4831) buf = data + arg->field.field->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4833) if (arg->field.field->size != 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4834) trace_seq_printf(s, "INVALIDIPv6");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4835) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4838) if (have_c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4839) print_ip6c_addr(s, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4840) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4841) print_ip6_addr(s, i, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4843) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4846) static int print_ipsa_arg(struct trace_seq *s, const char *ptr, char i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4847) void *data, int size, struct tep_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4848) struct tep_print_arg *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4849) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4850) char have_c = 0, have_p = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4851) unsigned char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4852) struct sockaddr_storage *sa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4853) bool reverse = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4854) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4855) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4857) /* pISpc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4858) if (i == 'I') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4859) if (*ptr == 'p') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4860) have_p = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4861) ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4862) rc++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4864) if (*ptr == 'c') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4865) have_c = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4866) ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4867) rc++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4870) ret = parse_ip4_print_args(event->tep, ptr, &reverse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4871) ptr += ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4872) rc += ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4874) if (arg->type == TEP_PRINT_FUNC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4875) process_defined_func(s, data, size, event, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4876) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4879) if (arg->type != TEP_PRINT_FIELD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4880) trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4881) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4884) if (!arg->field.field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4885) arg->field.field =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4886) tep_find_any_field(event, arg->field.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4887) if (!arg->field.field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4888) do_warning("%s: field %s not found",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4889) __func__, arg->field.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4890) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4892) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4894) sa = (struct sockaddr_storage *) (data + arg->field.field->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4896) if (sa->ss_family == AF_INET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4897) struct sockaddr_in *sa4 = (struct sockaddr_in *) sa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4899) if (arg->field.field->size < sizeof(struct sockaddr_in)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4900) trace_seq_printf(s, "INVALIDIPv4");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4901) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4904) print_ip4_addr(s, i, reverse, (unsigned char *) &sa4->sin_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4905) if (have_p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4906) trace_seq_printf(s, ":%d", ntohs(sa4->sin_port));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4909) } else if (sa->ss_family == AF_INET6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4910) struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *) sa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4912) if (arg->field.field->size < sizeof(struct sockaddr_in6)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4913) trace_seq_printf(s, "INVALIDIPv6");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4914) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4915) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4917) if (have_p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4918) trace_seq_printf(s, "[");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4920) buf = (unsigned char *) &sa6->sin6_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4921) if (have_c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4922) print_ip6c_addr(s, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4923) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4924) print_ip6_addr(s, i, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4926) if (have_p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4927) trace_seq_printf(s, "]:%d", ntohs(sa6->sin6_port));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4928) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4930) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4933) static int print_ip_arg(struct trace_seq *s, const char *ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4934) void *data, int size, struct tep_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4935) struct tep_print_arg *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4936) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4937) char i = *ptr; /* 'i' or 'I' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4938) int rc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4940) /* IP version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4941) ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4943) switch (*ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4944) case '4':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4945) rc += print_ipv4_arg(s, ptr + 1, i, data, size, event, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4946) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4947) case '6':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4948) rc += print_ipv6_arg(s, ptr + 1, i, data, size, event, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4949) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4950) case 'S':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4951) rc += print_ipsa_arg(s, ptr + 1, i, data, size, event, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4952) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4953) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4954) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4957) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4960) static const int guid_index[16] = {3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, 12, 13, 14, 15};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4961) static const int uuid_index[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4963) static int print_uuid_arg(struct trace_seq *s, const char *ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4964) void *data, int size, struct tep_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4965) struct tep_print_arg *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4966) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4967) const int *index = uuid_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4968) char *format = "%02x";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4969) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4970) char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4971) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4973) switch (*(ptr + 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4974) case 'L':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4975) format = "%02X";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4976) /* fall through */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4977) case 'l':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4978) index = guid_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4979) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4980) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4981) case 'B':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4982) format = "%02X";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4983) /* fall through */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4984) case 'b':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4985) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4986) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4987) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4989) if (arg->type == TEP_PRINT_FUNC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4990) process_defined_func(s, data, size, event, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4991) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4992) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4994) if (arg->type != TEP_PRINT_FIELD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4995) trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4996) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4999) if (!arg->field.field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5000) arg->field.field =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5001) tep_find_any_field(event, arg->field.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5002) if (!arg->field.field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5003) do_warning("%s: field %s not found",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5004) __func__, arg->field.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5005) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5007) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5009) if (arg->field.field->size != 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5010) trace_seq_printf(s, "INVALIDUUID");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5011) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5014) buf = data + arg->field.field->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5016) for (i = 0; i < 16; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5017) trace_seq_printf(s, format, buf[index[i]] & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5018) switch (i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5019) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5020) case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5021) case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5022) case 9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5023) trace_seq_printf(s, "-");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5024) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5025) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5028) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5031) static int print_raw_buff_arg(struct trace_seq *s, const char *ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5032) void *data, int size, struct tep_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5033) struct tep_print_arg *arg, int print_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5034) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5035) int plen = print_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5036) char *delim = " ";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5037) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5038) char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5039) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5040) unsigned long offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5041) int arr_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5043) switch (*(ptr + 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5044) case 'C':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5045) delim = ":";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5046) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5047) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5048) case 'D':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5049) delim = "-";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5050) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5051) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5052) case 'N':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5053) delim = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5054) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5055) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5058) if (arg->type == TEP_PRINT_FUNC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5059) process_defined_func(s, data, size, event, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5060) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5061) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5063) if (arg->type != TEP_PRINT_DYNAMIC_ARRAY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5064) trace_seq_printf(s, "ARG TYPE NOT FIELD BUT %d", arg->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5065) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5066) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5068) offset = tep_read_number(event->tep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5069) data + arg->dynarray.field->offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5070) arg->dynarray.field->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5071) arr_len = (unsigned long long)(offset >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5072) buf = data + (offset & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5074) if (arr_len < plen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5075) plen = arr_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5077) if (plen < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5078) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5080) trace_seq_printf(s, "%02x", buf[0] & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5081) for (i = 1; i < plen; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5082) trace_seq_printf(s, "%s%02x", delim, buf[i] & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5084) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5087) static int is_printable_array(char *p, unsigned int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5088) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5089) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5091) for (i = 0; i < len && p[i]; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5092) if (!isprint(p[i]) && !isspace(p[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5093) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5094) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5095) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5097) void tep_print_field(struct trace_seq *s, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5098) struct tep_format_field *field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5099) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5100) unsigned long long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5101) unsigned int offset, len, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5102) struct tep_handle *tep = field->event->tep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5104) if (field->flags & TEP_FIELD_IS_ARRAY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5105) offset = field->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5106) len = field->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5107) if (field->flags & TEP_FIELD_IS_DYNAMIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5108) val = tep_read_number(tep, data + offset, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5109) offset = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5110) len = offset >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5111) offset &= 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5113) if (field->flags & TEP_FIELD_IS_STRING &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5114) is_printable_array(data + offset, len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5115) trace_seq_printf(s, "%s", (char *)data + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5116) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5117) trace_seq_puts(s, "ARRAY[");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5118) for (i = 0; i < len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5119) if (i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5120) trace_seq_puts(s, ", ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5121) trace_seq_printf(s, "%02x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5122) *((unsigned char *)data + offset + i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5124) trace_seq_putc(s, ']');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5125) field->flags &= ~TEP_FIELD_IS_STRING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5127) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5128) val = tep_read_number(tep, data + field->offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5129) field->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5130) if (field->flags & TEP_FIELD_IS_POINTER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5131) trace_seq_printf(s, "0x%llx", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5132) } else if (field->flags & TEP_FIELD_IS_SIGNED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5133) switch (field->size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5134) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5135) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5136) * If field is long then print it in hex.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5137) * A long usually stores pointers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5138) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5139) if (field->flags & TEP_FIELD_IS_LONG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5140) trace_seq_printf(s, "0x%x", (int)val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5141) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5142) trace_seq_printf(s, "%d", (int)val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5143) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5144) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5145) trace_seq_printf(s, "%2d", (short)val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5146) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5147) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5148) trace_seq_printf(s, "%1d", (char)val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5149) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5150) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5151) trace_seq_printf(s, "%lld", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5153) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5154) if (field->flags & TEP_FIELD_IS_LONG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5155) trace_seq_printf(s, "0x%llx", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5156) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5157) trace_seq_printf(s, "%llu", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5162) void tep_print_fields(struct trace_seq *s, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5163) int size __maybe_unused, struct tep_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5165) struct tep_format_field *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5167) field = event->format.fields;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5168) while (field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5169) trace_seq_printf(s, " %s=", field->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5170) tep_print_field(s, data, field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5171) field = field->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5175) static int print_function(struct trace_seq *s, const char *format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5176) void *data, int size, struct tep_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5177) struct tep_print_arg *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5179) struct func_map *func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5180) unsigned long long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5182) val = eval_num_arg(data, size, event, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5183) func = find_func(event->tep, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5184) if (func) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5185) trace_seq_puts(s, func->func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5186) if (*format == 'F' || *format == 'S')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5187) trace_seq_printf(s, "+0x%llx", val - func->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5188) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5189) if (event->tep->long_size == 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5190) trace_seq_printf(s, "0x%lx", (long)val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5191) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5192) trace_seq_printf(s, "0x%llx", (long long)val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5195) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5198) static int print_arg_pointer(struct trace_seq *s, const char *format, int plen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5199) void *data, int size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5200) struct tep_event *event, struct tep_print_arg *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5202) unsigned long long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5203) int ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5205) if (arg->type == TEP_PRINT_BSTRING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5206) trace_seq_puts(s, arg->string.string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5207) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5209) while (*format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5210) if (*format == 'p') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5211) format++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5212) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5214) format++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5217) switch (*format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5218) case 'F':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5219) case 'f':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5220) case 'S':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5221) case 's':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5222) ret += print_function(s, format, data, size, event, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5223) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5224) case 'M':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5225) case 'm':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5226) ret += print_mac_arg(s, format, data, size, event, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5227) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5228) case 'I':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5229) case 'i':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5230) ret += print_ip_arg(s, format, data, size, event, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5231) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5232) case 'U':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5233) ret += print_uuid_arg(s, format, data, size, event, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5234) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5235) case 'h':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5236) ret += print_raw_buff_arg(s, format, data, size, event, arg, plen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5237) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5238) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5239) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5240) val = eval_num_arg(data, size, event, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5241) trace_seq_printf(s, "%p", (void *)(intptr_t)val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5242) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5245) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5249) static int print_arg_number(struct trace_seq *s, const char *format, int plen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5250) void *data, int size, int ls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5251) struct tep_event *event, struct tep_print_arg *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5253) unsigned long long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5255) val = eval_num_arg(data, size, event, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5257) switch (ls) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5258) case -2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5259) if (plen >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5260) trace_seq_printf(s, format, plen, (char)val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5261) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5262) trace_seq_printf(s, format, (char)val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5263) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5264) case -1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5265) if (plen >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5266) trace_seq_printf(s, format, plen, (short)val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5267) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5268) trace_seq_printf(s, format, (short)val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5269) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5270) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5271) if (plen >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5272) trace_seq_printf(s, format, plen, (int)val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5273) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5274) trace_seq_printf(s, format, (int)val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5275) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5276) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5277) if (plen >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5278) trace_seq_printf(s, format, plen, (long)val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5279) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5280) trace_seq_printf(s, format, (long)val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5281) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5282) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5283) if (plen >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5284) trace_seq_printf(s, format, plen, (long long)val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5285) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5286) trace_seq_printf(s, format, (long long)val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5287) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5288) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5289) do_warning_event(event, "bad count (%d)", ls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5290) event->flags |= TEP_EVENT_FL_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5292) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5296) static void print_arg_string(struct trace_seq *s, const char *format, int plen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5297) void *data, int size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5298) struct tep_event *event, struct tep_print_arg *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5300) struct trace_seq p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5302) /* Use helper trace_seq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5303) trace_seq_init(&p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5304) print_str_arg(&p, data, size, event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5305) format, plen, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5306) trace_seq_terminate(&p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5307) trace_seq_puts(s, p.buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5308) trace_seq_destroy(&p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5311) static int parse_arg_format_pointer(const char *format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5313) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5314) int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5315) int loop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5317) switch (*format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5318) case 'F':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5319) case 'S':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5320) case 'f':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5321) case 's':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5322) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5323) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5324) case 'M':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5325) case 'm':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5326) /* [mM]R , [mM]F */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5327) switch (format[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5328) case 'R':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5329) case 'F':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5330) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5331) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5333) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5334) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5335) case 'I':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5336) case 'i':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5337) index = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5338) loop = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5339) switch (format[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5340) case 'S':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5341) /*[S][pfs]*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5342) while (loop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5343) switch (format[index]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5344) case 'p':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5345) case 'f':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5346) case 's':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5347) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5348) index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5349) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5350) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5351) loop = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5352) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5355) /* fall through */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5356) case '4':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5357) /* [4S][hnbl] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5358) switch (format[index]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5359) case 'h':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5360) case 'n':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5361) case 'l':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5362) case 'b':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5363) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5364) index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5365) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5367) if (format[1] == '4') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5368) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5369) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5371) /* fall through */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5372) case '6':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5373) /* [6S]c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5374) if (format[index] == 'c')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5375) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5376) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5377) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5379) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5380) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5381) case 'U':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5382) switch (format[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5383) case 'L':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5384) case 'l':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5385) case 'B':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5386) case 'b':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5387) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5388) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5390) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5391) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5392) case 'h':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5393) switch (format[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5394) case 'C':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5395) case 'D':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5396) case 'N':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5397) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5398) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5400) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5401) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5402) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5403) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5406) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5409) static void free_parse_args(struct tep_print_parse *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5410) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5411) struct tep_print_parse *del;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5413) while (arg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5414) del = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5415) arg = del->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5416) free(del->format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5417) free(del);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5421) static int parse_arg_add(struct tep_print_parse **parse, char *format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5422) enum tep_print_parse_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5423) struct tep_print_arg *arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5424) struct tep_print_arg *len_as_arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5425) int ls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5426) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5427) struct tep_print_parse *parg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5429) parg = calloc(1, sizeof(*parg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5430) if (!parg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5431) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5432) parg->format = strdup(format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5433) if (!parg->format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5434) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5435) parg->type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5436) parg->arg = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5437) parg->len_as_arg = len_as_arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5438) parg->ls = ls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5439) *parse = parg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5440) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5441) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5442) if (parg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5443) free(parg->format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5444) free(parg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5446) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5449) static int parse_arg_format(struct tep_print_parse **parse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5450) struct tep_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5451) const char *format, struct tep_print_arg **arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5452) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5453) struct tep_print_arg *len_arg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5454) char print_format[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5455) const char *start = format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5456) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5457) int ls = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5458) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5459) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5461) format++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5462) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5463) for (; *format; format++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5464) switch (*format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5465) case '#':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5466) /* FIXME: need to handle properly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5467) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5468) case 'h':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5469) ls--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5470) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5471) case 'l':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5472) ls++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5473) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5474) case 'L':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5475) ls = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5476) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5477) case '.':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5478) case 'z':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5479) case 'Z':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5480) case '0' ... '9':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5481) case '-':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5482) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5483) case '*':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5484) /* The argument is the length. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5485) if (!*arg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5486) do_warning_event(event, "no argument match");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5487) event->flags |= TEP_EVENT_FL_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5488) goto out_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5490) if (len_arg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5491) do_warning_event(event, "argument already matched");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5492) event->flags |= TEP_EVENT_FL_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5493) goto out_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5495) len_arg = *arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5496) *arg = (*arg)->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5497) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5498) case 'p':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5499) if (!*arg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5500) do_warning_event(event, "no argument match");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5501) event->flags |= TEP_EVENT_FL_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5502) goto out_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5504) res = parse_arg_format_pointer(format + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5505) if (res > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5506) format += res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5507) ret += res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5509) len = ((unsigned long)format + 1) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5510) (unsigned long)start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5511) /* should never happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5512) if (len > 31) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5513) do_warning_event(event, "bad format!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5514) event->flags |= TEP_EVENT_FL_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5515) len = 31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5517) memcpy(print_format, start, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5518) print_format[len] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5520) parse_arg_add(parse, print_format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5521) PRINT_FMT_ARG_POINTER, *arg, len_arg, ls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5522) *arg = (*arg)->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5523) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5524) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5525) case 'd':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5526) case 'u':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5527) case 'i':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5528) case 'x':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5529) case 'X':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5530) case 'o':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5531) if (!*arg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5532) do_warning_event(event, "no argument match");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5533) event->flags |= TEP_EVENT_FL_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5534) goto out_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5537) len = ((unsigned long)format + 1) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5538) (unsigned long)start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5540) /* should never happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5541) if (len > 30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5542) do_warning_event(event, "bad format!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5543) event->flags |= TEP_EVENT_FL_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5544) len = 31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5546) memcpy(print_format, start, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5547) print_format[len] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5549) if (event->tep->long_size == 8 && ls == 1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5550) sizeof(long) != 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5551) char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5553) /* make %l into %ll */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5554) if (ls == 1 && (p = strchr(print_format, 'l')))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5555) memmove(p+1, p, strlen(p)+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5556) ls = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5558) if (ls < -2 || ls > 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5559) do_warning_event(event, "bad count (%d)", ls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5560) event->flags |= TEP_EVENT_FL_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5562) parse_arg_add(parse, print_format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5563) PRINT_FMT_ARG_DIGIT, *arg, len_arg, ls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5564) *arg = (*arg)->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5565) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5566) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5567) case 's':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5568) if (!*arg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5569) do_warning_event(event, "no matching argument");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5570) event->flags |= TEP_EVENT_FL_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5571) goto out_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5574) len = ((unsigned long)format + 1) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5575) (unsigned long)start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5577) /* should never happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5578) if (len > 31) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5579) do_warning_event(event, "bad format!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5580) event->flags |= TEP_EVENT_FL_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5581) len = 31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5584) memcpy(print_format, start, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5585) print_format[len] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5587) parse_arg_add(parse, print_format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5588) PRINT_FMT_ARG_STRING, *arg, len_arg, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5589) *arg = (*arg)->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5590) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5591) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5592) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5593) snprintf(print_format, 32, ">%c<", *format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5594) parse_arg_add(parse, print_format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5595) PRINT_FMT_STRING, NULL, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5596) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5597) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5599) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5602) out_failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5603) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5607) static int parse_arg_string(struct tep_print_parse **parse, const char *format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5608) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5609) struct trace_seq s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5610) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5612) trace_seq_init(&s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5613) for (; *format; format++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5614) if (*format == '\\') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5615) format++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5616) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5617) switch (*format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5618) case 'n':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5619) trace_seq_putc(&s, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5620) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5621) case 't':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5622) trace_seq_putc(&s, '\t');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5623) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5624) case 'r':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5625) trace_seq_putc(&s, '\r');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5626) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5627) case '\\':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5628) trace_seq_putc(&s, '\\');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5629) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5630) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5631) trace_seq_putc(&s, *format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5632) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5634) } else if (*format == '%') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5635) if (*(format + 1) == '%') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5636) trace_seq_putc(&s, '%');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5637) format++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5638) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5639) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5640) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5641) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5642) trace_seq_putc(&s, *format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5644) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5646) trace_seq_terminate(&s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5647) parse_arg_add(parse, s.buffer, PRINT_FMT_STRING, NULL, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5648) trace_seq_destroy(&s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5650) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5653) static struct tep_print_parse *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5654) parse_args(struct tep_event *event, const char *format, struct tep_print_arg *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5655) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5656) struct tep_print_parse *parse_ret = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5657) struct tep_print_parse **parse = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5658) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5659) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5661) len = strlen(format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5662) while (*format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5663) if (!parse_ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5664) parse = &parse_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5665) if (*format == '%' && *(format + 1) != '%')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5666) ret = parse_arg_format(parse, event, format, &arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5667) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5668) ret = parse_arg_string(parse, format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5669) if (*parse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5670) parse = &((*parse)->next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5672) len -= ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5673) if (len > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5674) format += ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5675) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5676) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5678) return parse_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5681) static void print_event_cache(struct tep_print_parse *parse, struct trace_seq *s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5682) void *data, int size, struct tep_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5683) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5684) int len_arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5686) while (parse) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5687) if (parse->len_as_arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5688) len_arg = eval_num_arg(data, size, event, parse->len_as_arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5689) switch (parse->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5690) case PRINT_FMT_ARG_DIGIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5691) print_arg_number(s, parse->format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5692) parse->len_as_arg ? len_arg : -1, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5693) size, parse->ls, event, parse->arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5694) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5695) case PRINT_FMT_ARG_POINTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5696) print_arg_pointer(s, parse->format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5697) parse->len_as_arg ? len_arg : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5698) data, size, event, parse->arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5699) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5700) case PRINT_FMT_ARG_STRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5701) print_arg_string(s, parse->format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5702) parse->len_as_arg ? len_arg : -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5703) data, size, event, parse->arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5704) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5705) case PRINT_FMT_STRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5706) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5707) trace_seq_printf(s, "%s", parse->format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5708) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5710) parse = parse->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5714) static void pretty_print(struct trace_seq *s, void *data, int size, struct tep_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5715) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5716) struct tep_print_parse *parse = event->print_fmt.print_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5717) struct tep_print_arg *args = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5718) char *bprint_fmt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5720) if (event->flags & TEP_EVENT_FL_FAILED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5721) trace_seq_printf(s, "[FAILED TO PARSE]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5722) tep_print_fields(s, data, size, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5723) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5726) if (event->flags & TEP_EVENT_FL_ISBPRINT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5727) bprint_fmt = get_bprint_format(data, size, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5728) args = make_bprint_args(bprint_fmt, data, size, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5729) parse = parse_args(event, bprint_fmt, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5732) print_event_cache(parse, s, data, size, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5734) if (event->flags & TEP_EVENT_FL_ISBPRINT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5735) free_parse_args(parse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5736) free_args(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5737) free(bprint_fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5741) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5742) * This parses out the Latency format (interrupts disabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5743) * need rescheduling, in hard/soft interrupt, preempt count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5744) * and lock depth) and places it into the trace_seq.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5745) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5746) static void data_latency_format(struct tep_handle *tep, struct trace_seq *s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5747) char *format, struct tep_record *record)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5748) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5749) static int check_lock_depth = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5750) static int check_migrate_disable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5751) static int lock_depth_exists;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5752) static int migrate_disable_exists;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5753) unsigned int lat_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5754) struct trace_seq sq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5755) unsigned int pc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5756) int lock_depth = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5757) int migrate_disable = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5758) int hardirq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5759) int softirq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5760) void *data = record->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5762) trace_seq_init(&sq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5763) lat_flags = parse_common_flags(tep, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5764) pc = parse_common_pc(tep, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5765) /* lock_depth may not always exist */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5766) if (lock_depth_exists)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5767) lock_depth = parse_common_lock_depth(tep, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5768) else if (check_lock_depth) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5769) lock_depth = parse_common_lock_depth(tep, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5770) if (lock_depth < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5771) check_lock_depth = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5772) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5773) lock_depth_exists = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5776) /* migrate_disable may not always exist */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5777) if (migrate_disable_exists)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5778) migrate_disable = parse_common_migrate_disable(tep, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5779) else if (check_migrate_disable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5780) migrate_disable = parse_common_migrate_disable(tep, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5781) if (migrate_disable < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5782) check_migrate_disable = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5783) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5784) migrate_disable_exists = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5787) hardirq = lat_flags & TRACE_FLAG_HARDIRQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5788) softirq = lat_flags & TRACE_FLAG_SOFTIRQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5790) trace_seq_printf(&sq, "%c%c%c",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5791) (lat_flags & TRACE_FLAG_IRQS_OFF) ? 'd' :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5792) (lat_flags & TRACE_FLAG_IRQS_NOSUPPORT) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5793) 'X' : '.',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5794) (lat_flags & TRACE_FLAG_NEED_RESCHED) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5795) 'N' : '.',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5796) (hardirq && softirq) ? 'H' :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5797) hardirq ? 'h' : softirq ? 's' : '.');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5799) if (pc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5800) trace_seq_printf(&sq, "%x", pc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5801) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5802) trace_seq_printf(&sq, ".");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5804) if (migrate_disable_exists) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5805) if (migrate_disable < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5806) trace_seq_printf(&sq, ".");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5807) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5808) trace_seq_printf(&sq, "%d", migrate_disable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5811) if (lock_depth_exists) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5812) if (lock_depth < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5813) trace_seq_printf(&sq, ".");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5814) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5815) trace_seq_printf(&sq, "%d", lock_depth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5818) if (sq.state == TRACE_SEQ__MEM_ALLOC_FAILED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5819) s->state = TRACE_SEQ__MEM_ALLOC_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5820) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5823) trace_seq_terminate(&sq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5824) trace_seq_puts(s, sq.buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5825) trace_seq_destroy(&sq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5826) trace_seq_terminate(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5829) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5830) * tep_data_type - parse out the given event type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5831) * @tep: a handle to the trace event parser context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5832) * @rec: the record to read from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5833) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5834) * This returns the event id from the @rec.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5835) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5836) int tep_data_type(struct tep_handle *tep, struct tep_record *rec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5837) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5838) return trace_parse_common_type(tep, rec->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5841) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5842) * tep_data_pid - parse the PID from record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5843) * @tep: a handle to the trace event parser context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5844) * @rec: the record to parse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5845) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5846) * This returns the PID from a record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5847) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5848) int tep_data_pid(struct tep_handle *tep, struct tep_record *rec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5849) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5850) return parse_common_pid(tep, rec->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5853) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5854) * tep_data_preempt_count - parse the preempt count from the record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5855) * @tep: a handle to the trace event parser context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5856) * @rec: the record to parse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5857) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5858) * This returns the preempt count from a record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5859) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5860) int tep_data_preempt_count(struct tep_handle *tep, struct tep_record *rec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5861) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5862) return parse_common_pc(tep, rec->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5865) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5866) * tep_data_flags - parse the latency flags from the record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5867) * @tep: a handle to the trace event parser context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5868) * @rec: the record to parse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5869) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5870) * This returns the latency flags from a record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5871) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5872) * Use trace_flag_type enum for the flags (see event-parse.h).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5873) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5874) int tep_data_flags(struct tep_handle *tep, struct tep_record *rec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5875) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5876) return parse_common_flags(tep, rec->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5879) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5880) * tep_data_comm_from_pid - return the command line from PID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5881) * @tep: a handle to the trace event parser context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5882) * @pid: the PID of the task to search for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5883) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5884) * This returns a pointer to the command line that has the given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5885) * @pid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5886) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5887) const char *tep_data_comm_from_pid(struct tep_handle *tep, int pid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5888) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5889) const char *comm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5891) comm = find_cmdline(tep, pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5892) return comm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5895) static struct tep_cmdline *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5896) pid_from_cmdlist(struct tep_handle *tep, const char *comm, struct tep_cmdline *next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5897) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5898) struct cmdline_list *cmdlist = (struct cmdline_list *)next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5900) if (cmdlist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5901) cmdlist = cmdlist->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5902) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5903) cmdlist = tep->cmdlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5905) while (cmdlist && strcmp(cmdlist->comm, comm) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5906) cmdlist = cmdlist->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5908) return (struct tep_cmdline *)cmdlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5911) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5912) * tep_data_pid_from_comm - return the pid from a given comm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5913) * @tep: a handle to the trace event parser context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5914) * @comm: the cmdline to find the pid from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5915) * @next: the cmdline structure to find the next comm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5916) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5917) * This returns the cmdline structure that holds a pid for a given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5918) * comm, or NULL if none found. As there may be more than one pid for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5919) * a given comm, the result of this call can be passed back into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5920) * a recurring call in the @next parameter, and then it will find the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5921) * next pid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5922) * Also, it does a linear search, so it may be slow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5923) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5924) struct tep_cmdline *tep_data_pid_from_comm(struct tep_handle *tep, const char *comm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5925) struct tep_cmdline *next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5926) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5927) struct tep_cmdline *cmdline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5929) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5930) * If the cmdlines have not been converted yet, then use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5931) * the list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5932) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5933) if (!tep->cmdlines)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5934) return pid_from_cmdlist(tep, comm, next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5936) if (next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5937) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5938) * The next pointer could have been still from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5939) * a previous call before cmdlines were created
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5940) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5941) if (next < tep->cmdlines ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5942) next >= tep->cmdlines + tep->cmdline_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5943) next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5944) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5945) cmdline = next++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5948) if (!next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5949) cmdline = tep->cmdlines;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5951) while (cmdline < tep->cmdlines + tep->cmdline_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5952) if (strcmp(cmdline->comm, comm) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5953) return cmdline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5954) cmdline++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5956) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5959) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5960) * tep_cmdline_pid - return the pid associated to a given cmdline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5961) * @tep: a handle to the trace event parser context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5962) * @cmdline: The cmdline structure to get the pid from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5963) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5964) * Returns the pid for a give cmdline. If @cmdline is NULL, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5965) * -1 is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5966) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5967) int tep_cmdline_pid(struct tep_handle *tep, struct tep_cmdline *cmdline)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5968) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5969) struct cmdline_list *cmdlist = (struct cmdline_list *)cmdline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5971) if (!cmdline)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5972) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5974) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5975) * If cmdlines have not been created yet, or cmdline is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5976) * not part of the array, then treat it as a cmdlist instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5977) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5978) if (!tep->cmdlines ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5979) cmdline < tep->cmdlines ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5980) cmdline >= tep->cmdlines + tep->cmdline_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5981) return cmdlist->pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5983) return cmdline->pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5986) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5987) * This parses the raw @data using the given @event information and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5988) * writes the print format into the trace_seq.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5989) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5990) static void print_event_info(struct trace_seq *s, char *format, bool raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5991) struct tep_event *event, struct tep_record *record)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5992) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5993) int print_pretty = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5995) if (raw || (event->flags & TEP_EVENT_FL_PRINTRAW))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5996) tep_print_fields(s, record->data, record->size, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5997) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5999) if (event->handler && !(event->flags & TEP_EVENT_FL_NOHANDLE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6000) print_pretty = event->handler(s, record, event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6001) event->context);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6003) if (print_pretty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6004) pretty_print(s, record->data, record->size, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6005) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6007) trace_seq_terminate(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6008) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6010) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6011) * tep_find_event_by_record - return the event from a given record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6012) * @tep: a handle to the trace event parser context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6013) * @record: The record to get the event from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6014) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6015) * Returns the associated event for a given record, or NULL if non is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6016) * is found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6017) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6018) struct tep_event *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6019) tep_find_event_by_record(struct tep_handle *tep, struct tep_record *record)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6020) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6021) int type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6023) if (record->size < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6024) do_warning("ug! negative record size %d", record->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6025) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6028) type = trace_parse_common_type(tep, record->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6030) return tep_find_event(tep, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6031) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6033) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6034) * Writes the timestamp of the record into @s. Time divisor and precision can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6035) * specified as part of printf @format string. Example:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6036) * "%3.1000d" - divide the time by 1000 and print the first 3 digits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6037) * before the dot. Thus, the timestamp "123456000" will be printed as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6038) * "123.456"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6039) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6040) static void print_event_time(struct tep_handle *tep, struct trace_seq *s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6041) char *format, struct tep_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6042) struct tep_record *record)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6043) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6044) unsigned long long time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6045) char *divstr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6046) int prec = 0, pr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6047) int div = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6048) int p10 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6050) if (isdigit(*(format + 1)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6051) prec = atoi(format + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6052) divstr = strchr(format, '.');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6053) if (divstr && isdigit(*(divstr + 1)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6054) div = atoi(divstr + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6055) time = record->ts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6056) if (div) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6057) time += div / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6058) time /= div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6060) pr = prec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6061) while (pr--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6062) p10 *= 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6064) if (p10 > 1 && p10 < time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6065) trace_seq_printf(s, "%5llu.%0*llu", time / p10, prec, time % p10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6066) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6067) trace_seq_printf(s, "%12llu", time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6068) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6070) struct print_event_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6071) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6072) EVENT_TYPE_INT = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6073) EVENT_TYPE_STRING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6074) EVENT_TYPE_UNKNOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6075) } type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6076) char format[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6077) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6079) static void print_string(struct tep_handle *tep, struct trace_seq *s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6080) struct tep_record *record, struct tep_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6081) const char *arg, struct print_event_type *type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6082) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6083) const char *comm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6084) int pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6086) if (strncmp(arg, TEP_PRINT_LATENCY, strlen(TEP_PRINT_LATENCY)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6087) data_latency_format(tep, s, type->format, record);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6088) } else if (strncmp(arg, TEP_PRINT_COMM, strlen(TEP_PRINT_COMM)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6089) pid = parse_common_pid(tep, record->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6090) comm = find_cmdline(tep, pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6091) trace_seq_printf(s, type->format, comm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6092) } else if (strncmp(arg, TEP_PRINT_INFO_RAW, strlen(TEP_PRINT_INFO_RAW)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6093) print_event_info(s, type->format, true, event, record);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6094) } else if (strncmp(arg, TEP_PRINT_INFO, strlen(TEP_PRINT_INFO)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6095) print_event_info(s, type->format, false, event, record);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6096) } else if (strncmp(arg, TEP_PRINT_NAME, strlen(TEP_PRINT_NAME)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6097) trace_seq_printf(s, type->format, event->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6098) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6099) trace_seq_printf(s, "[UNKNOWN TEP TYPE %s]", arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6104) static void print_int(struct tep_handle *tep, struct trace_seq *s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6105) struct tep_record *record, struct tep_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6106) int arg, struct print_event_type *type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6108) int param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6110) switch (arg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6111) case TEP_PRINT_CPU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6112) param = record->cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6113) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6114) case TEP_PRINT_PID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6115) param = parse_common_pid(tep, record->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6116) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6117) case TEP_PRINT_TIME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6118) return print_event_time(tep, s, type->format, event, record);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6119) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6120) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6122) trace_seq_printf(s, type->format, param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6125) static int tep_print_event_param_type(char *format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6126) struct print_event_type *type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6128) char *str = format + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6129) int i = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6131) type->type = EVENT_TYPE_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6132) while (*str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6133) switch (*str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6134) case 'd':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6135) case 'u':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6136) case 'i':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6137) case 'x':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6138) case 'X':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6139) case 'o':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6140) type->type = EVENT_TYPE_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6141) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6142) case 's':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6143) type->type = EVENT_TYPE_STRING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6144) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6146) str++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6147) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6148) if (type->type != EVENT_TYPE_UNKNOWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6149) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6151) memset(type->format, 0, 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6152) memcpy(type->format, format, i < 32 ? i : 31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6153) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6156) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6157) * tep_print_event - Write various event information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6158) * @tep: a handle to the trace event parser context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6159) * @s: the trace_seq to write to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6160) * @record: The record to get the event from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6161) * @format: a printf format string. Supported event fileds:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6162) * TEP_PRINT_PID, "%d" - event PID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6163) * TEP_PRINT_CPU, "%d" - event CPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6164) * TEP_PRINT_COMM, "%s" - event command string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6165) * TEP_PRINT_NAME, "%s" - event name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6166) * TEP_PRINT_LATENCY, "%s" - event latency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6167) * TEP_PRINT_TIME, %d - event time stamp. A divisor and precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6168) * can be specified as part of this format string:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6169) * "%precision.divisord". Example:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6170) * "%3.1000d" - divide the time by 1000 and print the first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6171) * 3 digits before the dot. Thus, the time stamp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6172) * "123456000" will be printed as "123.456"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6173) * TEP_PRINT_INFO, "%s" - event information. If any width is specified in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6174) * the format string, the event information will be printed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6175) * in raw format.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6176) * Writes the specified event information into @s.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6177) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6178) void tep_print_event(struct tep_handle *tep, struct trace_seq *s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6179) struct tep_record *record, const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6181) struct print_event_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6182) char *format = strdup(fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6183) char *current = format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6184) char *str = format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6185) int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6186) va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6187) struct tep_event *event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6189) if (!format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6190) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6192) event = tep_find_event_by_record(tep, record);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6193) va_start(args, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6194) while (*current) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6195) current = strchr(str, '%');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6196) if (!current) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6197) trace_seq_puts(s, str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6198) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6200) memset(&type, 0, sizeof(type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6201) offset = tep_print_event_param_type(current, &type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6202) *current = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6203) trace_seq_puts(s, str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6204) current += offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6205) switch (type.type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6206) case EVENT_TYPE_STRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6207) print_string(tep, s, record, event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6208) va_arg(args, char*), &type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6209) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6210) case EVENT_TYPE_INT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6211) print_int(tep, s, record, event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6212) va_arg(args, int), &type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6213) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6214) case EVENT_TYPE_UNKNOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6215) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6216) trace_seq_printf(s, "[UNKNOWN TYPE]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6217) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6219) str = current;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6222) va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6223) free(format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6226) static int events_id_cmp(const void *a, const void *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6228) struct tep_event * const * ea = a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6229) struct tep_event * const * eb = b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6231) if ((*ea)->id < (*eb)->id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6232) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6234) if ((*ea)->id > (*eb)->id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6235) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6237) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6240) static int events_name_cmp(const void *a, const void *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6242) struct tep_event * const * ea = a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6243) struct tep_event * const * eb = b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6244) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6246) res = strcmp((*ea)->name, (*eb)->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6247) if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6248) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6250) res = strcmp((*ea)->system, (*eb)->system);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6251) if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6252) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6254) return events_id_cmp(a, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6257) static int events_system_cmp(const void *a, const void *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6259) struct tep_event * const * ea = a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6260) struct tep_event * const * eb = b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6261) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6263) res = strcmp((*ea)->system, (*eb)->system);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6264) if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6265) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6267) res = strcmp((*ea)->name, (*eb)->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6268) if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6269) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6271) return events_id_cmp(a, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6274) static struct tep_event **list_events_copy(struct tep_handle *tep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6276) struct tep_event **events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6278) if (!tep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6279) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6281) events = malloc(sizeof(*events) * (tep->nr_events + 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6282) if (!events)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6283) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6285) memcpy(events, tep->events, sizeof(*events) * tep->nr_events);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6286) events[tep->nr_events] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6287) return events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6290) static void list_events_sort(struct tep_event **events, int nr_events,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6291) enum tep_event_sort_type sort_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6293) int (*sort)(const void *a, const void *b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6295) switch (sort_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6296) case TEP_EVENT_SORT_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6297) sort = events_id_cmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6298) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6299) case TEP_EVENT_SORT_NAME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6300) sort = events_name_cmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6301) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6302) case TEP_EVENT_SORT_SYSTEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6303) sort = events_system_cmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6304) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6305) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6306) sort = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6309) if (sort)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6310) qsort(events, nr_events, sizeof(*events), sort);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6313) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6314) * tep_list_events - Get events, sorted by given criteria.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6315) * @tep: a handle to the tep context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6316) * @sort_type: desired sort order of the events in the array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6317) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6318) * Returns an array of pointers to all events, sorted by the given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6319) * @sort_type criteria. The last element of the array is NULL. The returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6320) * memory must not be freed, it is managed by the library.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6321) * The function is not thread safe.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6322) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6323) struct tep_event **tep_list_events(struct tep_handle *tep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6324) enum tep_event_sort_type sort_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6326) struct tep_event **events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6328) if (!tep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6329) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6331) events = tep->sort_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6332) if (events && tep->last_type == sort_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6333) return events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6335) if (!events) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6336) events = list_events_copy(tep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6337) if (!events)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6338) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6340) tep->sort_events = events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6342) /* the internal events are sorted by id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6343) if (sort_type == TEP_EVENT_SORT_ID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6344) tep->last_type = sort_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6345) return events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6349) list_events_sort(events, tep->nr_events, sort_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6350) tep->last_type = sort_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6352) return events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6356) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6357) * tep_list_events_copy - Thread safe version of tep_list_events()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6358) * @tep: a handle to the tep context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6359) * @sort_type: desired sort order of the events in the array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6360) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6361) * Returns an array of pointers to all events, sorted by the given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6362) * @sort_type criteria. The last element of the array is NULL. The returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6363) * array is newly allocated inside the function and must be freed by the caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6364) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6365) struct tep_event **tep_list_events_copy(struct tep_handle *tep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6366) enum tep_event_sort_type sort_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6368) struct tep_event **events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6370) if (!tep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6371) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6373) events = list_events_copy(tep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6374) if (!events)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6375) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6377) /* the internal events are sorted by id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6378) if (sort_type == TEP_EVENT_SORT_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6379) return events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6381) list_events_sort(events, tep->nr_events, sort_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6383) return events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6386) static struct tep_format_field **
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6387) get_event_fields(const char *type, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6388) int count, struct tep_format_field *list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6389) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6390) struct tep_format_field **fields;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6391) struct tep_format_field *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6392) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6394) fields = malloc(sizeof(*fields) * (count + 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6395) if (!fields)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6396) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6398) for (field = list; field; field = field->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6399) fields[i++] = field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6400) if (i == count + 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6401) do_warning("event %s has more %s fields than specified",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6402) name, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6403) i--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6404) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6408) if (i != count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6409) do_warning("event %s has less %s fields than specified",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6410) name, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6412) fields[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6414) return fields;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6417) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6418) * tep_event_common_fields - return a list of common fields for an event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6419) * @event: the event to return the common fields of.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6420) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6421) * Returns an allocated array of fields. The last item in the array is NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6422) * The array must be freed with free().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6423) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6424) struct tep_format_field **tep_event_common_fields(struct tep_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6426) return get_event_fields("common", event->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6427) event->format.nr_common,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6428) event->format.common_fields);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6431) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6432) * tep_event_fields - return a list of event specific fields for an event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6433) * @event: the event to return the fields of.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6434) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6435) * Returns an allocated array of fields. The last item in the array is NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6436) * The array must be freed with free().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6437) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6438) struct tep_format_field **tep_event_fields(struct tep_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6440) return get_event_fields("event", event->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6441) event->format.nr_fields,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6442) event->format.fields);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6445) static void print_fields(struct trace_seq *s, struct tep_print_flag_sym *field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6447) trace_seq_printf(s, "{ %s, %s }", field->value, field->str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6448) if (field->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6449) trace_seq_puts(s, ", ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6450) print_fields(s, field->next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6454) /* for debugging */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6455) static void print_args(struct tep_print_arg *args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6456) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6457) int print_paren = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6458) struct trace_seq s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6460) switch (args->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6461) case TEP_PRINT_NULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6462) printf("null");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6463) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6464) case TEP_PRINT_ATOM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6465) printf("%s", args->atom.atom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6466) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6467) case TEP_PRINT_FIELD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6468) printf("REC->%s", args->field.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6469) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6470) case TEP_PRINT_FLAGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6471) printf("__print_flags(");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6472) print_args(args->flags.field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6473) printf(", %s, ", args->flags.delim);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6474) trace_seq_init(&s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6475) print_fields(&s, args->flags.flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6476) trace_seq_do_printf(&s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6477) trace_seq_destroy(&s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6478) printf(")");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6479) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6480) case TEP_PRINT_SYMBOL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6481) printf("__print_symbolic(");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6482) print_args(args->symbol.field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6483) printf(", ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6484) trace_seq_init(&s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6485) print_fields(&s, args->symbol.symbols);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6486) trace_seq_do_printf(&s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6487) trace_seq_destroy(&s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6488) printf(")");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6489) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6490) case TEP_PRINT_HEX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6491) printf("__print_hex(");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6492) print_args(args->hex.field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6493) printf(", ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6494) print_args(args->hex.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6495) printf(")");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6496) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6497) case TEP_PRINT_HEX_STR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6498) printf("__print_hex_str(");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6499) print_args(args->hex.field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6500) printf(", ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6501) print_args(args->hex.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6502) printf(")");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6503) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6504) case TEP_PRINT_INT_ARRAY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6505) printf("__print_array(");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6506) print_args(args->int_array.field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6507) printf(", ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6508) print_args(args->int_array.count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6509) printf(", ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6510) print_args(args->int_array.el_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6511) printf(")");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6512) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6513) case TEP_PRINT_STRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6514) case TEP_PRINT_BSTRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6515) printf("__get_str(%s)", args->string.string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6516) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6517) case TEP_PRINT_BITMASK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6518) printf("__get_bitmask(%s)", args->bitmask.bitmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6519) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6520) case TEP_PRINT_TYPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6521) printf("(%s)", args->typecast.type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6522) print_args(args->typecast.item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6523) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6524) case TEP_PRINT_OP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6525) if (strcmp(args->op.op, ":") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6526) print_paren = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6527) if (print_paren)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6528) printf("(");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6529) print_args(args->op.left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6530) printf(" %s ", args->op.op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6531) print_args(args->op.right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6532) if (print_paren)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6533) printf(")");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6534) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6535) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6536) /* we should warn... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6537) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6539) if (args->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6540) printf("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6541) print_args(args->next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6545) static void parse_header_field(const char *field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6546) int *offset, int *size, int mandatory)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6547) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6548) unsigned long long save_input_buf_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6549) unsigned long long save_input_buf_siz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6550) char *token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6551) int type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6553) save_input_buf_ptr = input_buf_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6554) save_input_buf_siz = input_buf_siz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6556) if (read_expected(TEP_EVENT_ITEM, "field") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6557) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6558) if (read_expected(TEP_EVENT_OP, ":") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6559) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6561) /* type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6562) if (read_expect_type(TEP_EVENT_ITEM, &token) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6563) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6564) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6566) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6567) * If this is not a mandatory field, then test it first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6568) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6569) if (mandatory) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6570) if (read_expected(TEP_EVENT_ITEM, field) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6571) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6572) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6573) if (read_expect_type(TEP_EVENT_ITEM, &token) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6574) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6575) if (strcmp(token, field) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6576) goto discard;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6577) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6580) if (read_expected(TEP_EVENT_OP, ";") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6581) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6582) if (read_expected(TEP_EVENT_ITEM, "offset") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6583) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6584) if (read_expected(TEP_EVENT_OP, ":") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6585) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6586) if (read_expect_type(TEP_EVENT_ITEM, &token) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6587) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6588) *offset = atoi(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6589) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6590) if (read_expected(TEP_EVENT_OP, ";") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6591) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6592) if (read_expected(TEP_EVENT_ITEM, "size") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6593) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6594) if (read_expected(TEP_EVENT_OP, ":") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6595) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6596) if (read_expect_type(TEP_EVENT_ITEM, &token) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6597) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6598) *size = atoi(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6599) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6600) if (read_expected(TEP_EVENT_OP, ";") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6601) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6602) type = read_token(&token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6603) if (type != TEP_EVENT_NEWLINE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6604) /* newer versions of the kernel have a "signed" type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6605) if (type != TEP_EVENT_ITEM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6606) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6608) if (strcmp(token, "signed") != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6609) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6611) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6613) if (read_expected(TEP_EVENT_OP, ":") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6614) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6616) if (read_expect_type(TEP_EVENT_ITEM, &token))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6617) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6619) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6620) if (read_expected(TEP_EVENT_OP, ";") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6621) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6623) if (read_expect_type(TEP_EVENT_NEWLINE, &token))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6624) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6626) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6627) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6628) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6630) discard:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6631) input_buf_ptr = save_input_buf_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6632) input_buf_siz = save_input_buf_siz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6633) *offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6634) *size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6635) free_token(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6638) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6639) * tep_parse_header_page - parse the data stored in the header page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6640) * @tep: a handle to the trace event parser context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6641) * @buf: the buffer storing the header page format string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6642) * @size: the size of @buf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6643) * @long_size: the long size to use if there is no header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6644) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6645) * This parses the header page format for information on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6646) * ring buffer used. The @buf should be copied from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6647) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6648) * /sys/kernel/debug/tracing/events/header_page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6649) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6650) int tep_parse_header_page(struct tep_handle *tep, char *buf, unsigned long size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6651) int long_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6652) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6653) int ignore;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6655) if (!size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6656) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6657) * Old kernels did not have header page info.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6658) * Sorry but we just use what we find here in user space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6659) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6660) tep->header_page_ts_size = sizeof(long long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6661) tep->header_page_size_size = long_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6662) tep->header_page_data_offset = sizeof(long long) + long_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6663) tep->old_format = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6664) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6666) init_input_buf(buf, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6668) parse_header_field("timestamp", &tep->header_page_ts_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6669) &tep->header_page_ts_size, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6670) parse_header_field("commit", &tep->header_page_size_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6671) &tep->header_page_size_size, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6672) parse_header_field("overwrite", &tep->header_page_overwrite,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6673) &ignore, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6674) parse_header_field("data", &tep->header_page_data_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6675) &tep->header_page_data_size, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6677) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6680) static int event_matches(struct tep_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6681) int id, const char *sys_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6682) const char *event_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6683) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6684) if (id >= 0 && id != event->id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6685) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6687) if (event_name && (strcmp(event_name, event->name) != 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6688) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6690) if (sys_name && (strcmp(sys_name, event->system) != 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6691) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6693) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6696) static void free_handler(struct event_handler *handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6697) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6698) free((void *)handle->sys_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6699) free((void *)handle->event_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6700) free(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6703) static int find_event_handle(struct tep_handle *tep, struct tep_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6705) struct event_handler *handle, **next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6707) for (next = &tep->handlers; *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6708) next = &(*next)->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6709) handle = *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6710) if (event_matches(event, handle->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6711) handle->sys_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6712) handle->event_name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6713) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6716) if (!(*next))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6717) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6719) pr_stat("overriding event (%d) %s:%s with new print handler",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6720) event->id, event->system, event->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6722) event->handler = handle->func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6723) event->context = handle->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6725) *next = handle->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6726) free_handler(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6728) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6731) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6732) * parse_format - parse the event format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6733) * @buf: the buffer storing the event format string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6734) * @size: the size of @buf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6735) * @sys: the system the event belongs to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6736) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6737) * This parses the event format and creates an event structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6738) * to quickly parse raw data for a given event.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6739) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6740) * These files currently come from:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6741) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6742) * /sys/kernel/debug/tracing/events/.../.../format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6743) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6744) static enum tep_errno parse_format(struct tep_event **eventp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6745) struct tep_handle *tep, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6746) unsigned long size, const char *sys)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6747) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6748) struct tep_event *event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6749) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6751) init_input_buf(buf, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6753) *eventp = event = alloc_event();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6754) if (!event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6755) return TEP_ERRNO__MEM_ALLOC_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6757) event->name = event_read_name();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6758) if (!event->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6759) /* Bad event? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6760) ret = TEP_ERRNO__MEM_ALLOC_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6761) goto event_alloc_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6764) if (strcmp(sys, "ftrace") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6765) event->flags |= TEP_EVENT_FL_ISFTRACE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6767) if (strcmp(event->name, "bprint") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6768) event->flags |= TEP_EVENT_FL_ISBPRINT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6771) event->id = event_read_id();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6772) if (event->id < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6773) ret = TEP_ERRNO__READ_ID_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6774) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6775) * This isn't an allocation error actually.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6776) * But as the ID is critical, just bail out.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6777) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6778) goto event_alloc_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6781) event->system = strdup(sys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6782) if (!event->system) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6783) ret = TEP_ERRNO__MEM_ALLOC_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6784) goto event_alloc_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6787) /* Add tep to event so that it can be referenced */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6788) event->tep = tep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6790) ret = event_read_format(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6791) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6792) ret = TEP_ERRNO__READ_FORMAT_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6793) goto event_parse_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6796) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6797) * If the event has an override, don't print warnings if the event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6798) * print format fails to parse.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6799) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6800) if (tep && find_event_handle(tep, event))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6801) show_warning = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6803) ret = event_read_print(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6804) show_warning = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6806) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6807) ret = TEP_ERRNO__READ_PRINT_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6808) goto event_parse_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6811) if (!ret && (event->flags & TEP_EVENT_FL_ISFTRACE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6812) struct tep_format_field *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6813) struct tep_print_arg *arg, **list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6815) /* old ftrace had no args */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6816) list = &event->print_fmt.args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6817) for (field = event->format.fields; field; field = field->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6818) arg = alloc_arg();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6819) if (!arg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6820) event->flags |= TEP_EVENT_FL_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6821) return TEP_ERRNO__OLD_FTRACE_ARG_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6823) arg->type = TEP_PRINT_FIELD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6824) arg->field.name = strdup(field->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6825) if (!arg->field.name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6826) event->flags |= TEP_EVENT_FL_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6827) free_arg(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6828) return TEP_ERRNO__OLD_FTRACE_ARG_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6830) arg->field.field = field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6831) *list = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6832) list = &arg->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6836) if (!(event->flags & TEP_EVENT_FL_ISBPRINT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6837) event->print_fmt.print_cache = parse_args(event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6838) event->print_fmt.format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6839) event->print_fmt.args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6841) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6843) event_parse_failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6844) event->flags |= TEP_EVENT_FL_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6845) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6847) event_alloc_failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6848) free(event->system);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6849) free(event->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6850) free(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6851) *eventp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6852) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6855) static enum tep_errno
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6856) __parse_event(struct tep_handle *tep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6857) struct tep_event **eventp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6858) const char *buf, unsigned long size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6859) const char *sys)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6860) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6861) int ret = parse_format(eventp, tep, buf, size, sys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6862) struct tep_event *event = *eventp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6864) if (event == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6865) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6867) if (tep && add_event(tep, event)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6868) ret = TEP_ERRNO__MEM_ALLOC_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6869) goto event_add_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6872) #define PRINT_ARGS 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6873) if (PRINT_ARGS && event->print_fmt.args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6874) print_args(event->print_fmt.args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6876) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6878) event_add_failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6879) free_tep_event(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6880) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6881) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6883) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6884) * tep_parse_format - parse the event format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6885) * @tep: a handle to the trace event parser context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6886) * @eventp: returned format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6887) * @buf: the buffer storing the event format string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6888) * @size: the size of @buf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6889) * @sys: the system the event belongs to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6890) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6891) * This parses the event format and creates an event structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6892) * to quickly parse raw data for a given event.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6893) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6894) * These files currently come from:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6895) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6896) * /sys/kernel/debug/tracing/events/.../.../format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6897) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6898) enum tep_errno tep_parse_format(struct tep_handle *tep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6899) struct tep_event **eventp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6900) const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6901) unsigned long size, const char *sys)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6902) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6903) return __parse_event(tep, eventp, buf, size, sys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6906) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6907) * tep_parse_event - parse the event format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6908) * @tep: a handle to the trace event parser context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6909) * @buf: the buffer storing the event format string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6910) * @size: the size of @buf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6911) * @sys: the system the event belongs to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6912) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6913) * This parses the event format and creates an event structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6914) * to quickly parse raw data for a given event.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6915) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6916) * These files currently come from:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6917) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6918) * /sys/kernel/debug/tracing/events/.../.../format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6919) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6920) enum tep_errno tep_parse_event(struct tep_handle *tep, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6921) unsigned long size, const char *sys)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6922) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6923) struct tep_event *event = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6924) return __parse_event(tep, &event, buf, size, sys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6927) int get_field_val(struct trace_seq *s, struct tep_format_field *field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6928) const char *name, struct tep_record *record,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6929) unsigned long long *val, int err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6930) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6931) if (!field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6932) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6933) trace_seq_printf(s, "<CANT FIND FIELD %s>", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6934) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6937) if (tep_read_number_field(field, record->data, val)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6938) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6939) trace_seq_printf(s, " %s=INVALID", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6940) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6943) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6946) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6947) * tep_get_field_raw - return the raw pointer into the data field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6948) * @s: The seq to print to on error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6949) * @event: the event that the field is for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6950) * @name: The name of the field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6951) * @record: The record with the field name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6952) * @len: place to store the field length.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6953) * @err: print default error if failed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6954) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6955) * Returns a pointer into record->data of the field and places
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6956) * the length of the field in @len.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6957) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6958) * On failure, it returns NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6959) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6960) void *tep_get_field_raw(struct trace_seq *s, struct tep_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6961) const char *name, struct tep_record *record,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6962) int *len, int err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6963) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6964) struct tep_format_field *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6965) void *data = record->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6966) unsigned offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6967) int dummy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6969) if (!event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6970) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6972) field = tep_find_field(event, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6974) if (!field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6975) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6976) trace_seq_printf(s, "<CANT FIND FIELD %s>", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6977) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6978) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6980) /* Allow @len to be NULL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6981) if (!len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6982) len = &dummy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6984) offset = field->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6985) if (field->flags & TEP_FIELD_IS_DYNAMIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6986) offset = tep_read_number(event->tep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6987) data + offset, field->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6988) *len = offset >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6989) offset &= 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6990) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6991) *len = field->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6993) return data + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6996) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6997) * tep_get_field_val - find a field and return its value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6998) * @s: The seq to print to on error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6999) * @event: the event that the field is for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7000) * @name: The name of the field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7001) * @record: The record with the field name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7002) * @val: place to store the value of the field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7003) * @err: print default error if failed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7004) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7005) * Returns 0 on success -1 on field not found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7006) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7007) int tep_get_field_val(struct trace_seq *s, struct tep_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7008) const char *name, struct tep_record *record,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7009) unsigned long long *val, int err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7010) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7011) struct tep_format_field *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7013) if (!event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7014) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7016) field = tep_find_field(event, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7018) return get_field_val(s, field, name, record, val, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7021) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7022) * tep_get_common_field_val - find a common field and return its value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7023) * @s: The seq to print to on error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7024) * @event: the event that the field is for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7025) * @name: The name of the field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7026) * @record: The record with the field name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7027) * @val: place to store the value of the field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7028) * @err: print default error if failed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7029) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7030) * Returns 0 on success -1 on field not found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7031) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7032) int tep_get_common_field_val(struct trace_seq *s, struct tep_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7033) const char *name, struct tep_record *record,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7034) unsigned long long *val, int err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7035) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7036) struct tep_format_field *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7038) if (!event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7039) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7041) field = tep_find_common_field(event, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7043) return get_field_val(s, field, name, record, val, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7046) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7047) * tep_get_any_field_val - find a any field and return its value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7048) * @s: The seq to print to on error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7049) * @event: the event that the field is for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7050) * @name: The name of the field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7051) * @record: The record with the field name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7052) * @val: place to store the value of the field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7053) * @err: print default error if failed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7054) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7055) * Returns 0 on success -1 on field not found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7056) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7057) int tep_get_any_field_val(struct trace_seq *s, struct tep_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7058) const char *name, struct tep_record *record,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7059) unsigned long long *val, int err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7060) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7061) struct tep_format_field *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7063) if (!event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7064) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7066) field = tep_find_any_field(event, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7068) return get_field_val(s, field, name, record, val, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7069) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7071) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7072) * tep_print_num_field - print a field and a format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7073) * @s: The seq to print to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7074) * @fmt: The printf format to print the field with.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7075) * @event: the event that the field is for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7076) * @name: The name of the field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7077) * @record: The record with the field name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7078) * @err: print default error if failed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7079) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7080) * Returns positive value on success, negative in case of an error,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7081) * or 0 if buffer is full.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7082) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7083) int tep_print_num_field(struct trace_seq *s, const char *fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7084) struct tep_event *event, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7085) struct tep_record *record, int err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7086) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7087) struct tep_format_field *field = tep_find_field(event, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7088) unsigned long long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7090) if (!field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7091) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7093) if (tep_read_number_field(field, record->data, &val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7094) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7096) return trace_seq_printf(s, fmt, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7098) failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7099) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7100) trace_seq_printf(s, "CAN'T FIND FIELD \"%s\"", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7101) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7104) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7105) * tep_print_func_field - print a field and a format for function pointers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7106) * @s: The seq to print to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7107) * @fmt: The printf format to print the field with.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7108) * @event: the event that the field is for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7109) * @name: The name of the field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7110) * @record: The record with the field name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7111) * @err: print default error if failed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7112) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7113) * Returns positive value on success, negative in case of an error,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7114) * or 0 if buffer is full.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7115) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7116) int tep_print_func_field(struct trace_seq *s, const char *fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7117) struct tep_event *event, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7118) struct tep_record *record, int err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7120) struct tep_format_field *field = tep_find_field(event, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7121) struct tep_handle *tep = event->tep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7122) unsigned long long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7123) struct func_map *func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7124) char tmp[128];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7126) if (!field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7127) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7129) if (tep_read_number_field(field, record->data, &val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7130) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7132) func = find_func(tep, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7134) if (func)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7135) snprintf(tmp, 128, "%s/0x%llx", func->func, func->addr - val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7136) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7137) sprintf(tmp, "0x%08llx", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7139) return trace_seq_printf(s, fmt, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7141) failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7142) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7143) trace_seq_printf(s, "CAN'T FIND FIELD \"%s\"", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7144) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7147) static void free_func_handle(struct tep_function_handler *func)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7149) struct func_params *params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7151) free(func->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7153) while (func->params) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7154) params = func->params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7155) func->params = params->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7156) free(params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7159) free(func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7162) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7163) * tep_register_print_function - register a helper function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7164) * @tep: a handle to the trace event parser context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7165) * @func: the function to process the helper function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7166) * @ret_type: the return type of the helper function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7167) * @name: the name of the helper function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7168) * @parameters: A list of enum tep_func_arg_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7169) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7170) * Some events may have helper functions in the print format arguments.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7171) * This allows a plugin to dynamically create a way to process one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7172) * of these functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7173) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7174) * The @parameters is a variable list of tep_func_arg_type enums that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7175) * must end with TEP_FUNC_ARG_VOID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7176) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7177) int tep_register_print_function(struct tep_handle *tep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7178) tep_func_handler func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7179) enum tep_func_arg_type ret_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7180) char *name, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7182) struct tep_function_handler *func_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7183) struct func_params **next_param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7184) struct func_params *param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7185) enum tep_func_arg_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7186) va_list ap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7187) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7189) func_handle = find_func_handler(tep, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7190) if (func_handle) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7191) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7192) * This is most like caused by the users own
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7193) * plugins updating the function. This overrides the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7194) * system defaults.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7195) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7196) pr_stat("override of function helper '%s'", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7197) remove_func_handler(tep, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7200) func_handle = calloc(1, sizeof(*func_handle));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7201) if (!func_handle) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7202) do_warning("Failed to allocate function handler");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7203) return TEP_ERRNO__MEM_ALLOC_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7206) func_handle->ret_type = ret_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7207) func_handle->name = strdup(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7208) func_handle->func = func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7209) if (!func_handle->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7210) do_warning("Failed to allocate function name");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7211) free(func_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7212) return TEP_ERRNO__MEM_ALLOC_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7215) next_param = &(func_handle->params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7216) va_start(ap, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7217) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7218) type = va_arg(ap, enum tep_func_arg_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7219) if (type == TEP_FUNC_ARG_VOID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7220) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7222) if (type >= TEP_FUNC_ARG_MAX_TYPES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7223) do_warning("Invalid argument type %d", type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7224) ret = TEP_ERRNO__INVALID_ARG_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7225) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7228) param = malloc(sizeof(*param));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7229) if (!param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7230) do_warning("Failed to allocate function param");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7231) ret = TEP_ERRNO__MEM_ALLOC_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7232) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7234) param->type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7235) param->next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7237) *next_param = param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7238) next_param = &(param->next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7240) func_handle->nr_args++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7242) va_end(ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7244) func_handle->next = tep->func_handlers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7245) tep->func_handlers = func_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7247) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7248) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7249) va_end(ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7250) free_func_handle(func_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7251) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7254) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7255) * tep_unregister_print_function - unregister a helper function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7256) * @tep: a handle to the trace event parser context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7257) * @func: the function to process the helper function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7258) * @name: the name of the helper function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7259) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7260) * This function removes existing print handler for function @name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7261) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7262) * Returns 0 if the handler was removed successully, -1 otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7263) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7264) int tep_unregister_print_function(struct tep_handle *tep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7265) tep_func_handler func, char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7267) struct tep_function_handler *func_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7269) func_handle = find_func_handler(tep, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7270) if (func_handle && func_handle->func == func) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7271) remove_func_handler(tep, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7272) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7274) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7277) static struct tep_event *search_event(struct tep_handle *tep, int id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7278) const char *sys_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7279) const char *event_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7281) struct tep_event *event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7283) if (id >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7284) /* search by id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7285) event = tep_find_event(tep, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7286) if (!event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7287) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7288) if (event_name && (strcmp(event_name, event->name) != 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7289) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7290) if (sys_name && (strcmp(sys_name, event->system) != 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7291) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7292) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7293) event = tep_find_event_by_name(tep, sys_name, event_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7294) if (!event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7295) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7297) return event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7300) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7301) * tep_register_event_handler - register a way to parse an event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7302) * @tep: a handle to the trace event parser context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7303) * @id: the id of the event to register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7304) * @sys_name: the system name the event belongs to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7305) * @event_name: the name of the event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7306) * @func: the function to call to parse the event information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7307) * @context: the data to be passed to @func
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7308) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7309) * This function allows a developer to override the parsing of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7310) * a given event. If for some reason the default print format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7311) * is not sufficient, this function will register a function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7312) * for an event to be used to parse the data instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7313) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7314) * If @id is >= 0, then it is used to find the event.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7315) * else @sys_name and @event_name are used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7316) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7317) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7318) * TEP_REGISTER_SUCCESS_OVERWRITE if an existing handler is overwritten
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7319) * TEP_REGISTER_SUCCESS if a new handler is registered successfully
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7320) * negative TEP_ERRNO_... in case of an error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7321) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7322) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7323) int tep_register_event_handler(struct tep_handle *tep, int id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7324) const char *sys_name, const char *event_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7325) tep_event_handler_func func, void *context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7327) struct tep_event *event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7328) struct event_handler *handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7330) event = search_event(tep, id, sys_name, event_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7331) if (event == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7332) goto not_found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7334) pr_stat("overriding event (%d) %s:%s with new print handler",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7335) event->id, event->system, event->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7337) event->handler = func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7338) event->context = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7339) return TEP_REGISTER_SUCCESS_OVERWRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7341) not_found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7342) /* Save for later use. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7343) handle = calloc(1, sizeof(*handle));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7344) if (!handle) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7345) do_warning("Failed to allocate event handler");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7346) return TEP_ERRNO__MEM_ALLOC_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7349) handle->id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7350) if (event_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7351) handle->event_name = strdup(event_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7352) if (sys_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7353) handle->sys_name = strdup(sys_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7355) if ((event_name && !handle->event_name) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7356) (sys_name && !handle->sys_name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7357) do_warning("Failed to allocate event/sys name");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7358) free((void *)handle->event_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7359) free((void *)handle->sys_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7360) free(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7361) return TEP_ERRNO__MEM_ALLOC_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7364) handle->func = func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7365) handle->next = tep->handlers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7366) tep->handlers = handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7367) handle->context = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7369) return TEP_REGISTER_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7372) static int handle_matches(struct event_handler *handler, int id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7373) const char *sys_name, const char *event_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7374) tep_event_handler_func func, void *context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7376) if (id >= 0 && id != handler->id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7377) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7379) if (event_name && (strcmp(event_name, handler->event_name) != 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7380) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7382) if (sys_name && (strcmp(sys_name, handler->sys_name) != 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7383) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7385) if (func != handler->func || context != handler->context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7386) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7388) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7391) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7392) * tep_unregister_event_handler - unregister an existing event handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7393) * @tep: a handle to the trace event parser context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7394) * @id: the id of the event to unregister
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7395) * @sys_name: the system name the handler belongs to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7396) * @event_name: the name of the event handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7397) * @func: the function to call to parse the event information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7398) * @context: the data to be passed to @func
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7399) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7400) * This function removes existing event handler (parser).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7401) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7402) * If @id is >= 0, then it is used to find the event.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7403) * else @sys_name and @event_name are used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7404) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7405) * Returns 0 if handler was removed successfully, -1 if event was not found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7406) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7407) int tep_unregister_event_handler(struct tep_handle *tep, int id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7408) const char *sys_name, const char *event_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7409) tep_event_handler_func func, void *context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7410) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7411) struct tep_event *event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7412) struct event_handler *handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7413) struct event_handler **next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7415) event = search_event(tep, id, sys_name, event_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7416) if (event == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7417) goto not_found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7419) if (event->handler == func && event->context == context) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7420) pr_stat("removing override handler for event (%d) %s:%s. Going back to default handler.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7421) event->id, event->system, event->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7423) event->handler = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7424) event->context = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7425) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7428) not_found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7429) for (next = &tep->handlers; *next; next = &(*next)->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7430) handle = *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7431) if (handle_matches(handle, id, sys_name, event_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7432) func, context))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7433) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7436) if (!(*next))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7437) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7439) *next = handle->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7440) free_handler(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7442) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7445) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7446) * tep_alloc - create a tep handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7447) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7448) struct tep_handle *tep_alloc(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7449) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7450) struct tep_handle *tep = calloc(1, sizeof(*tep));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7452) if (tep) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7453) tep->ref_count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7454) tep->host_bigendian = tep_is_bigendian();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7457) return tep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7460) void tep_ref(struct tep_handle *tep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7461) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7462) tep->ref_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7465) int tep_get_ref(struct tep_handle *tep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7467) if (tep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7468) return tep->ref_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7469) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7472) __hidden void free_tep_format_field(struct tep_format_field *field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7473) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7474) free(field->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7475) if (field->alias != field->name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7476) free(field->alias);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7477) free(field->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7478) free(field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7481) static void free_format_fields(struct tep_format_field *field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7482) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7483) struct tep_format_field *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7485) while (field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7486) next = field->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7487) free_tep_format_field(field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7488) field = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7492) static void free_formats(struct tep_format *format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7493) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7494) free_format_fields(format->common_fields);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7495) free_format_fields(format->fields);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7498) __hidden void free_tep_event(struct tep_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7499) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7500) free(event->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7501) free(event->system);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7503) free_formats(&event->format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7505) free(event->print_fmt.format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7506) free_args(event->print_fmt.args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7507) free_parse_args(event->print_fmt.print_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7508) free(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7511) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7512) * tep_free - free a tep handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7513) * @tep: the tep handle to free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7514) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7515) void tep_free(struct tep_handle *tep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7516) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7517) struct cmdline_list *cmdlist, *cmdnext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7518) struct func_list *funclist, *funcnext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7519) struct printk_list *printklist, *printknext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7520) struct tep_function_handler *func_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7521) struct event_handler *handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7522) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7524) if (!tep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7525) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7527) cmdlist = tep->cmdlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7528) funclist = tep->funclist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7529) printklist = tep->printklist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7531) tep->ref_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7532) if (tep->ref_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7533) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7535) if (tep->cmdlines) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7536) for (i = 0; i < tep->cmdline_count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7537) free(tep->cmdlines[i].comm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7538) free(tep->cmdlines);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7541) while (cmdlist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7542) cmdnext = cmdlist->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7543) free(cmdlist->comm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7544) free(cmdlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7545) cmdlist = cmdnext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7548) if (tep->func_map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7549) for (i = 0; i < (int)tep->func_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7550) free(tep->func_map[i].func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7551) free(tep->func_map[i].mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7553) free(tep->func_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7556) while (funclist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7557) funcnext = funclist->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7558) free(funclist->func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7559) free(funclist->mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7560) free(funclist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7561) funclist = funcnext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7564) while (tep->func_handlers) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7565) func_handler = tep->func_handlers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7566) tep->func_handlers = func_handler->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7567) free_func_handle(func_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7570) if (tep->printk_map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7571) for (i = 0; i < (int)tep->printk_count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7572) free(tep->printk_map[i].printk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7573) free(tep->printk_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7576) while (printklist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7577) printknext = printklist->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7578) free(printklist->printk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7579) free(printklist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7580) printklist = printknext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7583) for (i = 0; i < tep->nr_events; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7584) free_tep_event(tep->events[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7586) while (tep->handlers) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7587) handle = tep->handlers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7588) tep->handlers = handle->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7589) free_handler(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7592) free(tep->events);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7593) free(tep->sort_events);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7594) free(tep->func_resolver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7595) free_tep_plugin_paths(tep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7597) free(tep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7600) void tep_unref(struct tep_handle *tep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7601) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7602) tep_free(tep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7603) }