Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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) }