Linux Audio

Check our new training course

Loading...
v5.4
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Common code for probe-based Dynamic events.
   4 *
 
 
 
 
 
 
 
 
 
 
 
 
 
   5 * This code was copied from kernel/trace/trace_kprobe.c written by
   6 * Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
   7 *
   8 * Updates to make this generic:
   9 * Copyright (C) IBM Corporation, 2010-2011
  10 * Author:     Srikar Dronamraju
  11 */
  12#define pr_fmt(fmt)	"trace_probe: " fmt
  13
  14#include "trace_probe.h"
  15
  16#undef C
  17#define C(a, b)		b
  18
  19static const char *trace_probe_err_text[] = { ERRORS };
  20
  21static const char *reserved_field_names[] = {
  22	"common_type",
  23	"common_flags",
  24	"common_preempt_count",
  25	"common_pid",
  26	"common_tgid",
  27	FIELD_STRING_IP,
  28	FIELD_STRING_RETIP,
  29	FIELD_STRING_FUNC,
  30};
  31
  32/* Printing  in basic type function template */
  33#define DEFINE_BASIC_PRINT_TYPE_FUNC(tname, type, fmt)			\
  34int PRINT_TYPE_FUNC_NAME(tname)(struct trace_seq *s, void *data, void *ent)\
 
 
  35{									\
  36	trace_seq_printf(s, fmt, *(type *)data);			\
  37	return !trace_seq_has_overflowed(s);				\
  38}									\
  39const char PRINT_TYPE_FMT_NAME(tname)[] = fmt;
  40
  41DEFINE_BASIC_PRINT_TYPE_FUNC(u8,  u8,  "%u")
  42DEFINE_BASIC_PRINT_TYPE_FUNC(u16, u16, "%u")
  43DEFINE_BASIC_PRINT_TYPE_FUNC(u32, u32, "%u")
  44DEFINE_BASIC_PRINT_TYPE_FUNC(u64, u64, "%Lu")
  45DEFINE_BASIC_PRINT_TYPE_FUNC(s8,  s8,  "%d")
  46DEFINE_BASIC_PRINT_TYPE_FUNC(s16, s16, "%d")
  47DEFINE_BASIC_PRINT_TYPE_FUNC(s32, s32, "%d")
  48DEFINE_BASIC_PRINT_TYPE_FUNC(s64, s64, "%Ld")
  49DEFINE_BASIC_PRINT_TYPE_FUNC(x8,  u8,  "0x%x")
  50DEFINE_BASIC_PRINT_TYPE_FUNC(x16, u16, "0x%x")
  51DEFINE_BASIC_PRINT_TYPE_FUNC(x32, u32, "0x%x")
  52DEFINE_BASIC_PRINT_TYPE_FUNC(x64, u64, "0x%Lx")
  53
  54int PRINT_TYPE_FUNC_NAME(symbol)(struct trace_seq *s, void *data, void *ent)
  55{
  56	trace_seq_printf(s, "%pS", (void *)*(unsigned long *)data);
  57	return !trace_seq_has_overflowed(s);
  58}
  59const char PRINT_TYPE_FMT_NAME(symbol)[] = "%pS";
  60
  61/* Print type function for string type */
  62int PRINT_TYPE_FUNC_NAME(string)(struct trace_seq *s, void *data, void *ent)
 
 
  63{
  64	int len = *(u32 *)data >> 16;
  65
  66	if (!len)
  67		trace_seq_puts(s, "(fault)");
  68	else
  69		trace_seq_printf(s, "\"%s\"",
  70				 (const char *)get_loc_data(data, ent));
  71	return !trace_seq_has_overflowed(s);
  72}
  73
  74const char PRINT_TYPE_FMT_NAME(string)[] = "\\\"%s\\\"";
  75
  76/* Fetch type information table */
  77static const struct fetch_type probe_fetch_types[] = {
  78	/* Special types */
  79	__ASSIGN_FETCH_TYPE("string", string, string, sizeof(u32), 1,
  80			    "__data_loc char[]"),
  81	__ASSIGN_FETCH_TYPE("ustring", string, string, sizeof(u32), 1,
  82			    "__data_loc char[]"),
  83	/* Basic types */
  84	ASSIGN_FETCH_TYPE(u8,  u8,  0),
  85	ASSIGN_FETCH_TYPE(u16, u16, 0),
  86	ASSIGN_FETCH_TYPE(u32, u32, 0),
  87	ASSIGN_FETCH_TYPE(u64, u64, 0),
  88	ASSIGN_FETCH_TYPE(s8,  u8,  1),
  89	ASSIGN_FETCH_TYPE(s16, u16, 1),
  90	ASSIGN_FETCH_TYPE(s32, u32, 1),
  91	ASSIGN_FETCH_TYPE(s64, u64, 1),
  92	ASSIGN_FETCH_TYPE_ALIAS(x8,  u8,  u8,  0),
  93	ASSIGN_FETCH_TYPE_ALIAS(x16, u16, u16, 0),
  94	ASSIGN_FETCH_TYPE_ALIAS(x32, u32, u32, 0),
  95	ASSIGN_FETCH_TYPE_ALIAS(x64, u64, u64, 0),
  96	ASSIGN_FETCH_TYPE_ALIAS(symbol, ADDR_FETCH_TYPE, ADDR_FETCH_TYPE, 0),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  97
  98	ASSIGN_FETCH_TYPE_END
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  99};
 100
 101static const struct fetch_type *find_fetch_type(const char *type)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 102{
 103	int i;
 104
 105	if (!type)
 106		type = DEFAULT_FETCH_TYPE_STR;
 107
 108	/* Special case: bitfield */
 109	if (*type == 'b') {
 110		unsigned long bs;
 111
 112		type = strchr(type, '/');
 113		if (!type)
 114			goto fail;
 115
 116		type++;
 117		if (kstrtoul(type, 0, &bs))
 118			goto fail;
 119
 120		switch (bs) {
 121		case 8:
 122			return find_fetch_type("u8");
 123		case 16:
 124			return find_fetch_type("u16");
 125		case 32:
 126			return find_fetch_type("u32");
 127		case 64:
 128			return find_fetch_type("u64");
 129		default:
 130			goto fail;
 131		}
 132	}
 133
 134	for (i = 0; probe_fetch_types[i].name; i++) {
 135		if (strcmp(type, probe_fetch_types[i].name) == 0)
 136			return &probe_fetch_types[i];
 137	}
 138
 139fail:
 140	return NULL;
 141}
 142
 143static struct trace_probe_log trace_probe_log;
 144
 145void trace_probe_log_init(const char *subsystem, int argc, const char **argv)
 146{
 147	trace_probe_log.subsystem = subsystem;
 148	trace_probe_log.argc = argc;
 149	trace_probe_log.argv = argv;
 150	trace_probe_log.index = 0;
 151}
 152
 153void trace_probe_log_clear(void)
 
 154{
 155	memset(&trace_probe_log, 0, sizeof(trace_probe_log));
 156}
 157
 158void trace_probe_log_set_index(int index)
 
 
 159{
 160	trace_probe_log.index = index;
 161}
 162
 163void __trace_probe_log_err(int offset, int err_type)
 164{
 165	char *command, *p;
 166	int i, len = 0, pos = 0;
 167
 168	if (!trace_probe_log.argv)
 169		return;
 170
 171	/* Recalcurate the length and allocate buffer */
 172	for (i = 0; i < trace_probe_log.argc; i++) {
 173		if (i == trace_probe_log.index)
 174			pos = len;
 175		len += strlen(trace_probe_log.argv[i]) + 1;
 176	}
 177	command = kzalloc(len, GFP_KERNEL);
 178	if (!command)
 179		return;
 180
 181	if (trace_probe_log.index >= trace_probe_log.argc) {
 182		/**
 183		 * Set the error position is next to the last arg + space.
 184		 * Note that len includes the terminal null and the cursor
 185		 * appaers at pos + 1.
 186		 */
 187		pos = len;
 188		offset = 0;
 189	}
 190
 191	/* And make a command string from argv array */
 192	p = command;
 193	for (i = 0; i < trace_probe_log.argc; i++) {
 194		len = strlen(trace_probe_log.argv[i]);
 195		strcpy(p, trace_probe_log.argv[i]);
 196		p[len] = ' ';
 197		p += len + 1;
 198	}
 199	*(p - 1) = '\0';
 200
 201	tracing_log_err(NULL, trace_probe_log.subsystem, command,
 202			trace_probe_err_text, err_type, pos + offset);
 203
 204	kfree(command);
 205}
 206
 207/* Split symbol and offset. */
 208int traceprobe_split_symbol_offset(char *symbol, long *offset)
 209{
 210	char *tmp;
 211	int ret;
 212
 213	if (!offset)
 214		return -EINVAL;
 215
 216	tmp = strpbrk(symbol, "+-");
 217	if (tmp) {
 218		ret = kstrtol(tmp, 0, offset);
 
 219		if (ret)
 220			return ret;
 
 221		*tmp = '\0';
 222	} else
 223		*offset = 0;
 224
 225	return 0;
 226}
 227
 228/* @buf must has MAX_EVENT_NAME_LEN size */
 229int traceprobe_parse_event_name(const char **pevent, const char **pgroup,
 230				char *buf, int offset)
 231{
 232	const char *slash, *event = *pevent;
 233	int len;
 234
 235	slash = strchr(event, '/');
 236	if (slash) {
 237		if (slash == event) {
 238			trace_probe_log_err(offset, NO_GROUP_NAME);
 239			return -EINVAL;
 240		}
 241		if (slash - event + 1 > MAX_EVENT_NAME_LEN) {
 242			trace_probe_log_err(offset, GROUP_TOO_LONG);
 243			return -EINVAL;
 244		}
 245		strlcpy(buf, event, slash - event + 1);
 246		if (!is_good_name(buf)) {
 247			trace_probe_log_err(offset, BAD_GROUP_NAME);
 248			return -EINVAL;
 249		}
 250		*pgroup = buf;
 251		*pevent = slash + 1;
 252		offset += slash - event + 1;
 253		event = *pevent;
 254	}
 255	len = strlen(event);
 256	if (len == 0) {
 257		trace_probe_log_err(offset, NO_EVENT_NAME);
 258		return -EINVAL;
 259	} else if (len > MAX_EVENT_NAME_LEN) {
 260		trace_probe_log_err(offset, EVENT_TOO_LONG);
 261		return -EINVAL;
 262	}
 263	if (!is_good_name(event)) {
 264		trace_probe_log_err(offset, BAD_EVENT_NAME);
 265		return -EINVAL;
 266	}
 267	return 0;
 268}
 269
 270#define PARAM_MAX_STACK (THREAD_SIZE / sizeof(unsigned long))
 271
 272static int parse_probe_vars(char *arg, const struct fetch_type *t,
 273			struct fetch_insn *code, unsigned int flags, int offs)
 
 274{
 275	unsigned long param;
 276	int ret = 0;
 277	int len;
 278
 279	if (strcmp(arg, "retval") == 0) {
 280		if (flags & TPARG_FL_RETURN) {
 281			code->op = FETCH_OP_RETVAL;
 282		} else {
 283			trace_probe_log_err(offs, RETVAL_ON_PROBE);
 284			ret = -EINVAL;
 285		}
 286	} else if ((len = str_has_prefix(arg, "stack"))) {
 287		if (arg[len] == '\0') {
 288			code->op = FETCH_OP_STACKP;
 289		} else if (isdigit(arg[len])) {
 290			ret = kstrtoul(arg + len, 10, &param);
 291			if (ret) {
 292				goto inval_var;
 293			} else if ((flags & TPARG_FL_KERNEL) &&
 294				    param > PARAM_MAX_STACK) {
 295				trace_probe_log_err(offs, BAD_STACK_NUM);
 
 296				ret = -EINVAL;
 297			} else {
 298				code->op = FETCH_OP_STACK;
 299				code->param = (unsigned int)param;
 300			}
 301		} else
 302			goto inval_var;
 303	} else if (strcmp(arg, "comm") == 0) {
 304		code->op = FETCH_OP_COMM;
 305#ifdef CONFIG_HAVE_FUNCTION_ARG_ACCESS_API
 306	} else if (((flags & TPARG_FL_MASK) ==
 307		    (TPARG_FL_KERNEL | TPARG_FL_FENTRY)) &&
 308		   (len = str_has_prefix(arg, "arg"))) {
 309		ret = kstrtoul(arg + len, 10, &param);
 310		if (ret) {
 311			goto inval_var;
 312		} else if (!param || param > PARAM_MAX_STACK) {
 313			trace_probe_log_err(offs, BAD_ARG_NUM);
 314			return -EINVAL;
 315		}
 316		code->op = FETCH_OP_ARG;
 317		code->param = (unsigned int)param - 1;
 318#endif
 319	} else
 320		goto inval_var;
 321
 322	return ret;
 323
 324inval_var:
 325	trace_probe_log_err(offs, BAD_VAR);
 326	return -EINVAL;
 327}
 328
 329static int str_to_immediate(char *str, unsigned long *imm)
 330{
 331	if (isdigit(str[0]))
 332		return kstrtoul(str, 0, imm);
 333	else if (str[0] == '-')
 334		return kstrtol(str, 0, (long *)imm);
 335	else if (str[0] == '+')
 336		return kstrtol(str + 1, 0, (long *)imm);
 337	return -EINVAL;
 338}
 339
 340static int __parse_imm_string(char *str, char **pbuf, int offs)
 341{
 342	size_t len = strlen(str);
 343
 344	if (str[len - 1] != '"') {
 345		trace_probe_log_err(offs + len, IMMSTR_NO_CLOSE);
 346		return -EINVAL;
 347	}
 348	*pbuf = kstrndup(str, len - 1, GFP_KERNEL);
 349	return 0;
 350}
 351
 352/* Recursive argument parser */
 353static int
 354parse_probe_arg(char *arg, const struct fetch_type *type,
 355		struct fetch_insn **pcode, struct fetch_insn *end,
 356		unsigned int flags, int offs)
 357{
 358	struct fetch_insn *code = *pcode;
 359	unsigned long param;
 360	int deref = FETCH_OP_DEREF;
 361	long offset = 0;
 362	char *tmp;
 363	int ret = 0;
 364
 
 
 
 365	switch (arg[0]) {
 366	case '$':
 367		ret = parse_probe_vars(arg + 1, type, code, flags, offs);
 368		break;
 369
 370	case '%':	/* named register */
 371		ret = regs_query_register_offset(arg + 1);
 372		if (ret >= 0) {
 373			code->op = FETCH_OP_REG;
 374			code->param = (unsigned int)ret;
 375			ret = 0;
 376		} else
 377			trace_probe_log_err(offs, BAD_REG_NAME);
 378		break;
 379
 380	case '@':	/* memory, file-offset or symbol */
 381		if (isdigit(arg[1])) {
 382			ret = kstrtoul(arg + 1, 0, &param);
 383			if (ret) {
 384				trace_probe_log_err(offs, BAD_MEM_ADDR);
 385				break;
 386			}
 387			/* load address */
 388			code->op = FETCH_OP_IMM;
 389			code->immediate = param;
 390		} else if (arg[1] == '+') {
 391			/* kprobes don't support file offsets */
 392			if (flags & TPARG_FL_KERNEL) {
 393				trace_probe_log_err(offs, FILE_ON_KPROBE);
 394				return -EINVAL;
 395			}
 396			ret = kstrtol(arg + 2, 0, &offset);
 397			if (ret) {
 398				trace_probe_log_err(offs, BAD_FILE_OFFS);
 399				break;
 400			}
 401
 402			code->op = FETCH_OP_FOFFS;
 403			code->immediate = (unsigned long)offset;  // imm64?
 404		} else {
 405			/* uprobes don't support symbols */
 406			if (!(flags & TPARG_FL_KERNEL)) {
 407				trace_probe_log_err(offs, SYM_ON_UPROBE);
 408				return -EINVAL;
 409			}
 410			/* Preserve symbol for updating */
 411			code->op = FETCH_NOP_SYMBOL;
 412			code->data = kstrdup(arg + 1, GFP_KERNEL);
 413			if (!code->data)
 414				return -ENOMEM;
 415			if (++code == end) {
 416				trace_probe_log_err(offs, TOO_MANY_OPS);
 417				return -EINVAL;
 418			}
 419			code->op = FETCH_OP_IMM;
 420			code->immediate = 0;
 421		}
 422		/* These are fetching from memory */
 423		if (++code == end) {
 424			trace_probe_log_err(offs, TOO_MANY_OPS);
 425			return -EINVAL;
 426		}
 427		*pcode = code;
 428		code->op = FETCH_OP_DEREF;
 429		code->offset = offset;
 430		break;
 431
 432	case '+':	/* deref memory */
 
 433	case '-':
 434		if (arg[1] == 'u') {
 435			deref = FETCH_OP_UDEREF;
 436			arg[1] = arg[0];
 437			arg++;
 438		}
 439		if (arg[0] == '+')
 440			arg++;	/* Skip '+', because kstrtol() rejects it. */
 441		tmp = strchr(arg, '(');
 442		if (!tmp) {
 443			trace_probe_log_err(offs, DEREF_NEED_BRACE);
 444			return -EINVAL;
 445		}
 446		*tmp = '\0';
 447		ret = kstrtol(arg, 0, &offset);
 448		if (ret) {
 449			trace_probe_log_err(offs, BAD_DEREF_OFFS);
 450			break;
 451		}
 452		offs += (tmp + 1 - arg) + (arg[0] != '-' ? 1 : 0);
 453		arg = tmp + 1;
 454		tmp = strrchr(arg, ')');
 455		if (!tmp) {
 456			trace_probe_log_err(offs + strlen(arg),
 457					    DEREF_OPEN_BRACE);
 458			return -EINVAL;
 459		} else {
 460			const struct fetch_type *t2 = find_fetch_type(NULL);
 461
 
 
 
 
 
 462			*tmp = '\0';
 463			ret = parse_probe_arg(arg, t2, &code, end, flags, offs);
 464			if (ret)
 465				break;
 466			if (code->op == FETCH_OP_COMM ||
 467			    code->op == FETCH_OP_DATA) {
 468				trace_probe_log_err(offs, COMM_CANT_DEREF);
 469				return -EINVAL;
 470			}
 471			if (++code == end) {
 472				trace_probe_log_err(offs, TOO_MANY_OPS);
 473				return -EINVAL;
 474			}
 475			*pcode = code;
 476
 477			code->op = deref;
 478			code->offset = offset;
 479		}
 480		break;
 481	case '\\':	/* Immediate value */
 482		if (arg[1] == '"') {	/* Immediate string */
 483			ret = __parse_imm_string(arg + 2, &tmp, offs + 2);
 484			if (ret)
 485				break;
 486			code->op = FETCH_OP_DATA;
 487			code->data = tmp;
 488		} else {
 489			ret = str_to_immediate(arg + 1, &code->immediate);
 490			if (ret)
 491				trace_probe_log_err(offs + 1, BAD_IMM);
 492			else
 493				code->op = FETCH_OP_IMM;
 
 
 494		}
 495		break;
 496	}
 497	if (!ret && code->op == FETCH_OP_NOP) {
 498		/* Parsed, but do not find fetch method */
 499		trace_probe_log_err(offs, BAD_FETCH_ARG);
 500		ret = -EINVAL;
 501	}
 
 502	return ret;
 503}
 504
 505#define BYTES_TO_BITS(nb)	((BITS_PER_LONG * (nb)) / sizeof(long))
 506
 507/* Bitfield type needs to be parsed into a fetch function */
 508static int __parse_bitfield_probe_arg(const char *bf,
 509				      const struct fetch_type *t,
 510				      struct fetch_insn **pcode)
 511{
 512	struct fetch_insn *code = *pcode;
 513	unsigned long bw, bo;
 514	char *tail;
 515
 516	if (*bf != 'b')
 517		return 0;
 518
 
 
 
 
 
 
 
 519	bw = simple_strtoul(bf + 1, &tail, 0);	/* Use simple one */
 520
 521	if (bw == 0 || *tail != '@')
 522		return -EINVAL;
 523
 524	bf = tail + 1;
 525	bo = simple_strtoul(bf, &tail, 0);
 526
 527	if (tail == bf || *tail != '/')
 528		return -EINVAL;
 529	code++;
 530	if (code->op != FETCH_OP_NOP)
 531		return -EINVAL;
 532	*pcode = code;
 533
 534	code->op = FETCH_OP_MOD_BF;
 535	code->lshift = BYTES_TO_BITS(t->size) - (bw + bo);
 536	code->rshift = BYTES_TO_BITS(t->size) - bw;
 537	code->basesize = t->size;
 538
 539	return (BYTES_TO_BITS(t->size) < (bw + bo)) ? -EINVAL : 0;
 540}
 541
 542/* String length checking wrapper */
 543static int traceprobe_parse_probe_arg_body(char *arg, ssize_t *size,
 544		struct probe_arg *parg, unsigned int flags, int offset)
 545{
 546	struct fetch_insn *code, *scode, *tmp = NULL;
 547	char *t, *t2, *t3;
 548	int ret, len;
 549
 550	len = strlen(arg);
 551	if (len > MAX_ARGSTR_LEN) {
 552		trace_probe_log_err(offset, ARG_TOO_LONG);
 553		return -EINVAL;
 554	} else if (len == 0) {
 555		trace_probe_log_err(offset, NO_ARG_BODY);
 556		return -EINVAL;
 557	}
 558
 
 
 
 
 559	parg->comm = kstrdup(arg, GFP_KERNEL);
 560	if (!parg->comm)
 
 561		return -ENOMEM;
 562
 563	t = strchr(arg, ':');
 564	if (t) {
 565		*t = '\0';
 566		t2 = strchr(++t, '[');
 567		if (t2) {
 568			*t2++ = '\0';
 569			t3 = strchr(t2, ']');
 570			if (!t3) {
 571				offset += t2 + strlen(t2) - arg;
 572				trace_probe_log_err(offset,
 573						    ARRAY_NO_CLOSE);
 574				return -EINVAL;
 575			} else if (t3[1] != '\0') {
 576				trace_probe_log_err(offset + t3 + 1 - arg,
 577						    BAD_ARRAY_SUFFIX);
 578				return -EINVAL;
 579			}
 580			*t3 = '\0';
 581			if (kstrtouint(t2, 0, &parg->count) || !parg->count) {
 582				trace_probe_log_err(offset + t2 - arg,
 583						    BAD_ARRAY_NUM);
 584				return -EINVAL;
 585			}
 586			if (parg->count > MAX_ARRAY_LEN) {
 587				trace_probe_log_err(offset + t2 - arg,
 588						    ARRAY_TOO_BIG);
 589				return -EINVAL;
 590			}
 591		}
 592	}
 593
 594	/*
 595	 * Since $comm and immediate string can not be dereferred,
 596	 * we can find those by strcmp.
 597	 */
 598	if (strcmp(arg, "$comm") == 0 || strncmp(arg, "\\\"", 2) == 0) {
 599		/* The type of $comm must be "string", and not an array. */
 600		if (parg->count || (t && strcmp(t, "string")))
 601			return -EINVAL;
 602		parg->type = find_fetch_type("string");
 603	} else
 604		parg->type = find_fetch_type(t);
 605	if (!parg->type) {
 606		trace_probe_log_err(offset + (t ? (t - arg) : 0), BAD_TYPE);
 607		return -EINVAL;
 608	}
 609	parg->offset = *size;
 610	*size += parg->type->size * (parg->count ?: 1);
 
 611
 612	if (parg->count) {
 613		len = strlen(parg->type->fmttype) + 6;
 614		parg->fmt = kmalloc(len, GFP_KERNEL);
 615		if (!parg->fmt)
 616			return -ENOMEM;
 617		snprintf(parg->fmt, len, "%s[%d]", parg->type->fmttype,
 618			 parg->count);
 619	}
 620
 621	code = tmp = kcalloc(FETCH_INSN_MAX, sizeof(*code), GFP_KERNEL);
 622	if (!code)
 623		return -ENOMEM;
 624	code[FETCH_INSN_MAX - 1].op = FETCH_OP_END;
 625
 626	ret = parse_probe_arg(arg, parg->type, &code, &code[FETCH_INSN_MAX - 1],
 627			      flags, offset);
 628	if (ret)
 629		goto fail;
 630
 631	/* Store operation */
 632	if (!strcmp(parg->type->name, "string") ||
 633	    !strcmp(parg->type->name, "ustring")) {
 634		if (code->op != FETCH_OP_DEREF && code->op != FETCH_OP_UDEREF &&
 635		    code->op != FETCH_OP_IMM && code->op != FETCH_OP_COMM &&
 636		    code->op != FETCH_OP_DATA) {
 637			trace_probe_log_err(offset + (t ? (t - arg) : 0),
 638					    BAD_STRING);
 639			ret = -EINVAL;
 640			goto fail;
 641		}
 642		if ((code->op == FETCH_OP_IMM || code->op == FETCH_OP_COMM) ||
 643		     parg->count) {
 644			/*
 645			 * IMM, DATA and COMM is pointing actual address, those
 646			 * must be kept, and if parg->count != 0, this is an
 647			 * array of string pointers instead of string address
 648			 * itself.
 649			 */
 650			code++;
 651			if (code->op != FETCH_OP_NOP) {
 652				trace_probe_log_err(offset, TOO_MANY_OPS);
 653				ret = -EINVAL;
 654				goto fail;
 655			}
 656		}
 657		/* If op == DEREF, replace it with STRING */
 658		if (!strcmp(parg->type->name, "ustring") ||
 659		    code->op == FETCH_OP_UDEREF)
 660			code->op = FETCH_OP_ST_USTRING;
 661		else
 662			code->op = FETCH_OP_ST_STRING;
 663		code->size = parg->type->size;
 664		parg->dynamic = true;
 665	} else if (code->op == FETCH_OP_DEREF) {
 666		code->op = FETCH_OP_ST_MEM;
 667		code->size = parg->type->size;
 668	} else if (code->op == FETCH_OP_UDEREF) {
 669		code->op = FETCH_OP_ST_UMEM;
 670		code->size = parg->type->size;
 671	} else {
 672		code++;
 673		if (code->op != FETCH_OP_NOP) {
 674			trace_probe_log_err(offset, TOO_MANY_OPS);
 675			ret = -EINVAL;
 676			goto fail;
 677		}
 678		code->op = FETCH_OP_ST_RAW;
 679		code->size = parg->type->size;
 680	}
 681	scode = code;
 682	/* Modify operation */
 683	if (t != NULL) {
 684		ret = __parse_bitfield_probe_arg(t, parg->type, &code);
 685		if (ret) {
 686			trace_probe_log_err(offset + t - arg, BAD_BITFIELD);
 687			goto fail;
 688		}
 689	}
 690	/* Loop(Array) operation */
 691	if (parg->count) {
 692		if (scode->op != FETCH_OP_ST_MEM &&
 693		    scode->op != FETCH_OP_ST_STRING &&
 694		    scode->op != FETCH_OP_ST_USTRING) {
 695			trace_probe_log_err(offset + (t ? (t - arg) : 0),
 696					    BAD_STRING);
 697			ret = -EINVAL;
 698			goto fail;
 699		}
 700		code++;
 701		if (code->op != FETCH_OP_NOP) {
 702			trace_probe_log_err(offset, TOO_MANY_OPS);
 703			ret = -EINVAL;
 704			goto fail;
 705		}
 706		code->op = FETCH_OP_LP_ARRAY;
 707		code->param = parg->count;
 708	}
 709	code++;
 710	code->op = FETCH_OP_END;
 711
 712	/* Shrink down the code buffer */
 713	parg->code = kcalloc(code - tmp + 1, sizeof(*code), GFP_KERNEL);
 714	if (!parg->code)
 715		ret = -ENOMEM;
 716	else
 717		memcpy(parg->code, tmp, sizeof(*code) * (code - tmp + 1));
 718
 719fail:
 720	if (ret) {
 721		for (code = tmp; code < tmp + FETCH_INSN_MAX; code++)
 722			if (code->op == FETCH_NOP_SYMBOL ||
 723			    code->op == FETCH_OP_DATA)
 724				kfree(code->data);
 725	}
 726	kfree(tmp);
 727
 728	return ret;
 729}
 730
 731/* Return 1 if name is reserved or already used by another argument */
 732static int traceprobe_conflict_field_name(const char *name,
 733					  struct probe_arg *args, int narg)
 734{
 735	int i;
 736
 737	for (i = 0; i < ARRAY_SIZE(reserved_field_names); i++)
 738		if (strcmp(reserved_field_names[i], name) == 0)
 739			return 1;
 740
 741	for (i = 0; i < narg; i++)
 742		if (strcmp(args[i].name, name) == 0)
 743			return 1;
 744
 745	return 0;
 746}
 747
 748int traceprobe_parse_probe_arg(struct trace_probe *tp, int i, char *arg,
 749				unsigned int flags)
 750{
 751	struct probe_arg *parg = &tp->args[i];
 752	char *body;
 753
 754	/* Increment count for freeing args in error case */
 755	tp->nr_args++;
 756
 757	body = strchr(arg, '=');
 758	if (body) {
 759		if (body - arg > MAX_ARG_NAME_LEN) {
 760			trace_probe_log_err(0, ARG_NAME_TOO_LONG);
 761			return -EINVAL;
 762		} else if (body == arg) {
 763			trace_probe_log_err(0, NO_ARG_NAME);
 764			return -EINVAL;
 765		}
 766		parg->name = kmemdup_nul(arg, body - arg, GFP_KERNEL);
 767		body++;
 768	} else {
 769		/* If argument name is omitted, set "argN" */
 770		parg->name = kasprintf(GFP_KERNEL, "arg%d", i + 1);
 771		body = arg;
 772	}
 773	if (!parg->name)
 774		return -ENOMEM;
 775
 776	if (!is_good_name(parg->name)) {
 777		trace_probe_log_err(0, BAD_ARG_NAME);
 778		return -EINVAL;
 779	}
 780	if (traceprobe_conflict_field_name(parg->name, tp->args, i)) {
 781		trace_probe_log_err(0, USED_ARG_NAME);
 782		return -EINVAL;
 783	}
 784	/* Parse fetch argument */
 785	return traceprobe_parse_probe_arg_body(body, &tp->size, parg, flags,
 786					       body - arg);
 787}
 788
 789void traceprobe_free_probe_arg(struct probe_arg *arg)
 790{
 791	struct fetch_insn *code = arg->code;
 
 
 
 
 
 792
 793	while (code && code->op != FETCH_OP_END) {
 794		if (code->op == FETCH_NOP_SYMBOL ||
 795		    code->op == FETCH_OP_DATA)
 796			kfree(code->data);
 797		code++;
 798	}
 799	kfree(arg->code);
 800	kfree(arg->name);
 801	kfree(arg->comm);
 802	kfree(arg->fmt);
 803}
 804
 805int traceprobe_update_arg(struct probe_arg *arg)
 806{
 807	struct fetch_insn *code = arg->code;
 808	long offset;
 809	char *tmp;
 810	char c;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 811	int ret = 0;
 
 
 812
 813	while (code && code->op != FETCH_OP_END) {
 814		if (code->op == FETCH_NOP_SYMBOL) {
 815			if (code[1].op != FETCH_OP_IMM)
 816				return -EINVAL;
 817
 818			tmp = strpbrk(code->data, "+-");
 819			if (tmp)
 820				c = *tmp;
 821			ret = traceprobe_split_symbol_offset(code->data,
 822							     &offset);
 823			if (ret)
 824				return ret;
 825
 826			code[1].immediate =
 827				(unsigned long)kallsyms_lookup_name(code->data);
 828			if (tmp)
 829				*tmp = c;
 830			if (!code[1].immediate)
 831				return -ENOENT;
 832			code[1].immediate += offset;
 833		}
 834		code++;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 835	}
 836	return 0;
 
 
 
 
 
 837}
 838
 839/* When len=0, we just calculate the needed length */
 840#define LEN_OR_ZERO (len ? len - pos : 0)
 841static int __set_print_fmt(struct trace_probe *tp, char *buf, int len,
 842			   bool is_return)
 843{
 844	struct probe_arg *parg;
 845	int i, j;
 846	int pos = 0;
 
 847	const char *fmt, *arg;
 848
 849	if (!is_return) {
 850		fmt = "(%lx)";
 851		arg = "REC->" FIELD_STRING_IP;
 852	} else {
 853		fmt = "(%lx <- %lx)";
 854		arg = "REC->" FIELD_STRING_FUNC ", REC->" FIELD_STRING_RETIP;
 855	}
 856
 
 
 
 857	pos += snprintf(buf + pos, LEN_OR_ZERO, "\"%s", fmt);
 858
 859	for (i = 0; i < tp->nr_args; i++) {
 860		parg = tp->args + i;
 861		pos += snprintf(buf + pos, LEN_OR_ZERO, " %s=", parg->name);
 862		if (parg->count) {
 863			pos += snprintf(buf + pos, LEN_OR_ZERO, "{%s",
 864					parg->type->fmt);
 865			for (j = 1; j < parg->count; j++)
 866				pos += snprintf(buf + pos, LEN_OR_ZERO, ",%s",
 867						parg->type->fmt);
 868			pos += snprintf(buf + pos, LEN_OR_ZERO, "}");
 869		} else
 870			pos += snprintf(buf + pos, LEN_OR_ZERO, "%s",
 871					parg->type->fmt);
 872	}
 873
 874	pos += snprintf(buf + pos, LEN_OR_ZERO, "\", %s", arg);
 875
 876	for (i = 0; i < tp->nr_args; i++) {
 877		parg = tp->args + i;
 878		if (parg->count) {
 879			if (strcmp(parg->type->name, "string") == 0)
 880				fmt = ", __get_str(%s[%d])";
 881			else
 882				fmt = ", REC->%s[%d]";
 883			for (j = 0; j < parg->count; j++)
 884				pos += snprintf(buf + pos, LEN_OR_ZERO,
 885						fmt, parg->name, j);
 886		} else {
 887			if (strcmp(parg->type->name, "string") == 0)
 888				fmt = ", __get_str(%s)";
 889			else
 890				fmt = ", REC->%s";
 891			pos += snprintf(buf + pos, LEN_OR_ZERO,
 892					fmt, parg->name);
 893		}
 
 
 
 894	}
 895
 
 
 896	/* return the length of print_fmt */
 897	return pos;
 898}
 899#undef LEN_OR_ZERO
 900
 901int traceprobe_set_print_fmt(struct trace_probe *tp, bool is_return)
 902{
 903	struct trace_event_call *call = trace_probe_event_call(tp);
 904	int len;
 905	char *print_fmt;
 906
 907	/* First: called with 0 length to calculate the needed length */
 908	len = __set_print_fmt(tp, NULL, 0, is_return);
 909	print_fmt = kmalloc(len + 1, GFP_KERNEL);
 910	if (!print_fmt)
 911		return -ENOMEM;
 912
 913	/* Second: actually write the @print_fmt */
 914	__set_print_fmt(tp, print_fmt, len + 1, is_return);
 915	call->print_fmt = print_fmt;
 916
 917	return 0;
 918}
 919
 920int traceprobe_define_arg_fields(struct trace_event_call *event_call,
 921				 size_t offset, struct trace_probe *tp)
 922{
 923	int ret, i;
 924
 925	/* Set argument names as fields */
 926	for (i = 0; i < tp->nr_args; i++) {
 927		struct probe_arg *parg = &tp->args[i];
 928		const char *fmt = parg->type->fmttype;
 929		int size = parg->type->size;
 930
 931		if (parg->fmt)
 932			fmt = parg->fmt;
 933		if (parg->count)
 934			size *= parg->count;
 935		ret = trace_define_field(event_call, fmt, parg->name,
 936					 offset + parg->offset, size,
 937					 parg->type->is_signed,
 938					 FILTER_OTHER);
 939		if (ret)
 940			return ret;
 941	}
 942	return 0;
 943}
 944
 945static void trace_probe_event_free(struct trace_probe_event *tpe)
 946{
 947	kfree(tpe->class.system);
 948	kfree(tpe->call.name);
 949	kfree(tpe->call.print_fmt);
 950	kfree(tpe);
 951}
 952
 953int trace_probe_append(struct trace_probe *tp, struct trace_probe *to)
 954{
 955	if (trace_probe_has_sibling(tp))
 956		return -EBUSY;
 957
 958	list_del_init(&tp->list);
 959	trace_probe_event_free(tp->event);
 960
 961	tp->event = to->event;
 962	list_add_tail(&tp->list, trace_probe_probe_list(to));
 963
 964	return 0;
 965}
 966
 967void trace_probe_unlink(struct trace_probe *tp)
 968{
 969	list_del_init(&tp->list);
 970	if (list_empty(trace_probe_probe_list(tp)))
 971		trace_probe_event_free(tp->event);
 972	tp->event = NULL;
 973}
 974
 975void trace_probe_cleanup(struct trace_probe *tp)
 976{
 977	int i;
 978
 979	for (i = 0; i < tp->nr_args; i++)
 980		traceprobe_free_probe_arg(&tp->args[i]);
 981
 982	if (tp->event)
 983		trace_probe_unlink(tp);
 984}
 985
 986int trace_probe_init(struct trace_probe *tp, const char *event,
 987		     const char *group)
 988{
 989	struct trace_event_call *call;
 990	int ret = 0;
 991
 992	if (!event || !group)
 993		return -EINVAL;
 994
 995	tp->event = kzalloc(sizeof(struct trace_probe_event), GFP_KERNEL);
 996	if (!tp->event)
 997		return -ENOMEM;
 998
 999	INIT_LIST_HEAD(&tp->event->files);
1000	INIT_LIST_HEAD(&tp->event->class.fields);
1001	INIT_LIST_HEAD(&tp->event->probes);
1002	INIT_LIST_HEAD(&tp->list);
1003	list_add(&tp->event->probes, &tp->list);
1004
1005	call = trace_probe_event_call(tp);
1006	call->class = &tp->event->class;
1007	call->name = kstrdup(event, GFP_KERNEL);
1008	if (!call->name) {
1009		ret = -ENOMEM;
1010		goto error;
1011	}
1012
1013	tp->event->class.system = kstrdup(group, GFP_KERNEL);
1014	if (!tp->event->class.system) {
1015		ret = -ENOMEM;
1016		goto error;
1017	}
1018
1019	return 0;
1020
1021error:
1022	trace_probe_cleanup(tp);
1023	return ret;
1024}
1025
1026int trace_probe_register_event_call(struct trace_probe *tp)
1027{
1028	struct trace_event_call *call = trace_probe_event_call(tp);
1029	int ret;
1030
1031	ret = register_trace_event(&call->event);
1032	if (!ret)
1033		return -ENODEV;
1034
1035	ret = trace_add_event_call(call);
1036	if (ret)
1037		unregister_trace_event(&call->event);
1038
1039	return ret;
1040}
1041
1042int trace_probe_add_file(struct trace_probe *tp, struct trace_event_file *file)
1043{
1044	struct event_file_link *link;
1045
1046	link = kmalloc(sizeof(*link), GFP_KERNEL);
1047	if (!link)
1048		return -ENOMEM;
1049
1050	link->file = file;
1051	INIT_LIST_HEAD(&link->list);
1052	list_add_tail_rcu(&link->list, &tp->event->files);
1053	trace_probe_set_flag(tp, TP_FLAG_TRACE);
1054	return 0;
1055}
1056
1057struct event_file_link *trace_probe_get_file_link(struct trace_probe *tp,
1058						  struct trace_event_file *file)
1059{
1060	struct event_file_link *link;
1061
1062	trace_probe_for_each_link(link, tp) {
1063		if (link->file == file)
1064			return link;
1065	}
1066
1067	return NULL;
1068}
1069
1070int trace_probe_remove_file(struct trace_probe *tp,
1071			    struct trace_event_file *file)
1072{
1073	struct event_file_link *link;
1074
1075	link = trace_probe_get_file_link(tp, file);
1076	if (!link)
1077		return -ENOENT;
1078
1079	list_del_rcu(&link->list);
1080	synchronize_rcu();
1081	kfree(link);
1082
1083	if (list_empty(&tp->event->files))
1084		trace_probe_clear_flag(tp, TP_FLAG_TRACE);
1085
1086	return 0;
1087}
1088
1089/*
1090 * Return the smallest index of different type argument (start from 1).
1091 * If all argument types and name are same, return 0.
1092 */
1093int trace_probe_compare_arg_type(struct trace_probe *a, struct trace_probe *b)
1094{
1095	int i;
1096
1097	/* In case of more arguments */
1098	if (a->nr_args < b->nr_args)
1099		return a->nr_args + 1;
1100	if (a->nr_args > b->nr_args)
1101		return b->nr_args + 1;
1102
1103	for (i = 0; i < a->nr_args; i++) {
1104		if ((b->nr_args <= i) ||
1105		    ((a->args[i].type != b->args[i].type) ||
1106		     (a->args[i].count != b->args[i].count) ||
1107		     strcmp(a->args[i].name, b->args[i].name)))
1108			return i + 1;
1109	}
1110
1111	return 0;
1112}
1113
1114bool trace_probe_match_command_args(struct trace_probe *tp,
1115				    int argc, const char **argv)
1116{
1117	char buf[MAX_ARGSTR_LEN + 1];
1118	int i;
1119
1120	if (tp->nr_args < argc)
1121		return false;
1122
1123	for (i = 0; i < argc; i++) {
1124		snprintf(buf, sizeof(buf), "%s=%s",
1125			 tp->args[i].name, tp->args[i].comm);
1126		if (strcmp(buf, argv[i]))
1127			return false;
1128	}
1129	return true;
1130}
v3.15
 
  1/*
  2 * Common code for probe-based Dynamic events.
  3 *
  4 * This program is free software; you can redistribute it and/or modify
  5 * it under the terms of the GNU General Public License version 2 as
  6 * published by the Free Software Foundation.
  7 *
  8 * This program is distributed in the hope that it will be useful,
  9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 11 * GNU General Public License for more details.
 12 *
 13 * You should have received a copy of the GNU General Public License
 14 * along with this program; if not, write to the Free Software
 15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 16 *
 17 * This code was copied from kernel/trace/trace_kprobe.c written by
 18 * Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
 19 *
 20 * Updates to make this generic:
 21 * Copyright (C) IBM Corporation, 2010-2011
 22 * Author:     Srikar Dronamraju
 23 */
 
 24
 25#include "trace_probe.h"
 26
 27const char *reserved_field_names[] = {
 
 
 
 
 
 28	"common_type",
 29	"common_flags",
 30	"common_preempt_count",
 31	"common_pid",
 32	"common_tgid",
 33	FIELD_STRING_IP,
 34	FIELD_STRING_RETIP,
 35	FIELD_STRING_FUNC,
 36};
 37
 38/* Printing  in basic type function template */
 39#define DEFINE_BASIC_PRINT_TYPE_FUNC(type, fmt)				\
 40__kprobes int PRINT_TYPE_FUNC_NAME(type)(struct trace_seq *s,	\
 41						const char *name,	\
 42						void *data, void *ent)	\
 43{									\
 44	return trace_seq_printf(s, " %s=" fmt, name, *(type *)data);	\
 
 45}									\
 46const char PRINT_TYPE_FMT_NAME(type)[] = fmt;
 47
 48DEFINE_BASIC_PRINT_TYPE_FUNC(u8 , "0x%x")
 49DEFINE_BASIC_PRINT_TYPE_FUNC(u16, "0x%x")
 50DEFINE_BASIC_PRINT_TYPE_FUNC(u32, "0x%x")
 51DEFINE_BASIC_PRINT_TYPE_FUNC(u64, "0x%Lx")
 52DEFINE_BASIC_PRINT_TYPE_FUNC(s8,  "%d")
 53DEFINE_BASIC_PRINT_TYPE_FUNC(s16, "%d")
 54DEFINE_BASIC_PRINT_TYPE_FUNC(s32, "%d")
 55DEFINE_BASIC_PRINT_TYPE_FUNC(s64, "%Ld")
 
 
 
 
 
 
 
 
 
 
 
 56
 57/* Print type function for string type */
 58__kprobes int PRINT_TYPE_FUNC_NAME(string)(struct trace_seq *s,
 59						  const char *name,
 60						  void *data, void *ent)
 61{
 62	int len = *(u32 *)data >> 16;
 63
 64	if (!len)
 65		return trace_seq_printf(s, " %s=(fault)", name);
 66	else
 67		return trace_seq_printf(s, " %s=\"%s\"", name,
 68					(const char *)get_loc_data(data, ent));
 
 69}
 70
 71const char PRINT_TYPE_FMT_NAME(string)[] = "\\\"%s\\\"";
 72
 73#define CHECK_FETCH_FUNCS(method, fn)			\
 74	(((FETCH_FUNC_NAME(method, u8) == fn) ||	\
 75	  (FETCH_FUNC_NAME(method, u16) == fn) ||	\
 76	  (FETCH_FUNC_NAME(method, u32) == fn) ||	\
 77	  (FETCH_FUNC_NAME(method, u64) == fn) ||	\
 78	  (FETCH_FUNC_NAME(method, string) == fn) ||	\
 79	  (FETCH_FUNC_NAME(method, string_size) == fn)) \
 80	 && (fn != NULL))
 81
 82/* Data fetch function templates */
 83#define DEFINE_FETCH_reg(type)						\
 84__kprobes void FETCH_FUNC_NAME(reg, type)(struct pt_regs *regs,		\
 85					void *offset, void *dest)	\
 86{									\
 87	*(type *)dest = (type)regs_get_register(regs,			\
 88				(unsigned int)((unsigned long)offset));	\
 89}
 90DEFINE_BASIC_FETCH_FUNCS(reg)
 91/* No string on the register */
 92#define fetch_reg_string	NULL
 93#define fetch_reg_string_size	NULL
 94
 95#define DEFINE_FETCH_retval(type)					\
 96__kprobes void FETCH_FUNC_NAME(retval, type)(struct pt_regs *regs,	\
 97					  void *dummy, void *dest)	\
 98{									\
 99	*(type *)dest = (type)regs_return_value(regs);			\
100}
101DEFINE_BASIC_FETCH_FUNCS(retval)
102/* No string on the retval */
103#define fetch_retval_string		NULL
104#define fetch_retval_string_size	NULL
105
106/* Dereference memory access function */
107struct deref_fetch_param {
108	struct fetch_param	orig;
109	long			offset;
110	fetch_func_t		fetch;
111	fetch_func_t		fetch_size;
112};
113
114#define DEFINE_FETCH_deref(type)					\
115__kprobes void FETCH_FUNC_NAME(deref, type)(struct pt_regs *regs,	\
116					    void *data, void *dest)	\
117{									\
118	struct deref_fetch_param *dprm = data;				\
119	unsigned long addr;						\
120	call_fetch(&dprm->orig, regs, &addr);				\
121	if (addr) {							\
122		addr += dprm->offset;					\
123		dprm->fetch(regs, (void *)addr, dest);			\
124	} else								\
125		*(type *)dest = 0;					\
126}
127DEFINE_BASIC_FETCH_FUNCS(deref)
128DEFINE_FETCH_deref(string)
129
130__kprobes void FETCH_FUNC_NAME(deref, string_size)(struct pt_regs *regs,
131						   void *data, void *dest)
132{
133	struct deref_fetch_param *dprm = data;
134	unsigned long addr;
135
136	call_fetch(&dprm->orig, regs, &addr);
137	if (addr && dprm->fetch_size) {
138		addr += dprm->offset;
139		dprm->fetch_size(regs, (void *)addr, dest);
140	} else
141		*(string_size *)dest = 0;
142}
143
144static __kprobes void update_deref_fetch_param(struct deref_fetch_param *data)
145{
146	if (CHECK_FETCH_FUNCS(deref, data->orig.fn))
147		update_deref_fetch_param(data->orig.data);
148	else if (CHECK_FETCH_FUNCS(symbol, data->orig.fn))
149		update_symbol_cache(data->orig.data);
150}
151
152static __kprobes void free_deref_fetch_param(struct deref_fetch_param *data)
153{
154	if (CHECK_FETCH_FUNCS(deref, data->orig.fn))
155		free_deref_fetch_param(data->orig.data);
156	else if (CHECK_FETCH_FUNCS(symbol, data->orig.fn))
157		free_symbol_cache(data->orig.data);
158	kfree(data);
159}
160
161/* Bitfield fetch function */
162struct bitfield_fetch_param {
163	struct fetch_param	orig;
164	unsigned char		hi_shift;
165	unsigned char		low_shift;
166};
167
168#define DEFINE_FETCH_bitfield(type)					\
169__kprobes void FETCH_FUNC_NAME(bitfield, type)(struct pt_regs *regs,	\
170					    void *data, void *dest)	\
171{									\
172	struct bitfield_fetch_param *bprm = data;			\
173	type buf = 0;							\
174	call_fetch(&bprm->orig, regs, &buf);				\
175	if (buf) {							\
176		buf <<= bprm->hi_shift;					\
177		buf >>= bprm->low_shift;				\
178	}								\
179	*(type *)dest = buf;						\
180}
181
182DEFINE_BASIC_FETCH_FUNCS(bitfield)
183#define fetch_bitfield_string		NULL
184#define fetch_bitfield_string_size	NULL
185
186static __kprobes void
187update_bitfield_fetch_param(struct bitfield_fetch_param *data)
188{
189	/*
190	 * Don't check the bitfield itself, because this must be the
191	 * last fetch function.
192	 */
193	if (CHECK_FETCH_FUNCS(deref, data->orig.fn))
194		update_deref_fetch_param(data->orig.data);
195	else if (CHECK_FETCH_FUNCS(symbol, data->orig.fn))
196		update_symbol_cache(data->orig.data);
197}
198
199static __kprobes void
200free_bitfield_fetch_param(struct bitfield_fetch_param *data)
201{
202	/*
203	 * Don't check the bitfield itself, because this must be the
204	 * last fetch function.
205	 */
206	if (CHECK_FETCH_FUNCS(deref, data->orig.fn))
207		free_deref_fetch_param(data->orig.data);
208	else if (CHECK_FETCH_FUNCS(symbol, data->orig.fn))
209		free_symbol_cache(data->orig.data);
210
211	kfree(data);
212}
213
214static const struct fetch_type *find_fetch_type(const char *type,
215						const struct fetch_type *ftbl)
216{
217	int i;
218
219	if (!type)
220		type = DEFAULT_FETCH_TYPE_STR;
221
222	/* Special case: bitfield */
223	if (*type == 'b') {
224		unsigned long bs;
225
226		type = strchr(type, '/');
227		if (!type)
228			goto fail;
229
230		type++;
231		if (kstrtoul(type, 0, &bs))
232			goto fail;
233
234		switch (bs) {
235		case 8:
236			return find_fetch_type("u8", ftbl);
237		case 16:
238			return find_fetch_type("u16", ftbl);
239		case 32:
240			return find_fetch_type("u32", ftbl);
241		case 64:
242			return find_fetch_type("u64", ftbl);
243		default:
244			goto fail;
245		}
246	}
247
248	for (i = 0; ftbl[i].name; i++) {
249		if (strcmp(type, ftbl[i].name) == 0)
250			return &ftbl[i];
251	}
252
253fail:
254	return NULL;
255}
256
257/* Special function : only accept unsigned long */
258static __kprobes void fetch_kernel_stack_address(struct pt_regs *regs,
259						 void *dummy, void *dest)
260{
261	*(unsigned long *)dest = kernel_stack_pointer(regs);
 
 
 
262}
263
264static __kprobes void fetch_user_stack_address(struct pt_regs *regs,
265					       void *dummy, void *dest)
266{
267	*(unsigned long *)dest = user_stack_pointer(regs);
268}
269
270static fetch_func_t get_fetch_size_function(const struct fetch_type *type,
271					    fetch_func_t orig_fn,
272					    const struct fetch_type *ftbl)
273{
274	int i;
 
 
 
 
 
 
 
 
 
275
276	if (type != &ftbl[FETCH_TYPE_STRING])
277		return NULL;	/* Only string type needs size function */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
278
279	for (i = 0; i < FETCH_MTD_END; i++)
280		if (type->fetch[i] == orig_fn)
281			return ftbl[FETCH_TYPE_STRSIZE].fetch[i];
 
 
 
 
 
 
282
283	WARN_ON(1);	/* This should not happen */
 
284
285	return NULL;
286}
287
288/* Split symbol and offset. */
289int traceprobe_split_symbol_offset(char *symbol, unsigned long *offset)
290{
291	char *tmp;
292	int ret;
293
294	if (!offset)
295		return -EINVAL;
296
297	tmp = strchr(symbol, '+');
298	if (tmp) {
299		/* skip sign because kstrtoul doesn't accept '+' */
300		ret = kstrtoul(tmp + 1, 0, offset);
301		if (ret)
302			return ret;
303
304		*tmp = '\0';
305	} else
306		*offset = 0;
307
308	return 0;
309}
310
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
311#define PARAM_MAX_STACK (THREAD_SIZE / sizeof(unsigned long))
312
313static int parse_probe_vars(char *arg, const struct fetch_type *t,
314			    struct fetch_param *f, bool is_return,
315			    bool is_kprobe)
316{
 
317	int ret = 0;
318	unsigned long param;
319
320	if (strcmp(arg, "retval") == 0) {
321		if (is_return)
322			f->fn = t->fetch[FETCH_MTD_retval];
323		else
 
324			ret = -EINVAL;
325	} else if (strncmp(arg, "stack", 5) == 0) {
326		if (arg[5] == '\0') {
327			if (strcmp(t->name, DEFAULT_FETCH_TYPE_STR))
328				return -EINVAL;
329
330			if (is_kprobe)
331				f->fn = fetch_kernel_stack_address;
332			else
333				f->fn = fetch_user_stack_address;
334		} else if (isdigit(arg[5])) {
335			ret = kstrtoul(arg + 5, 10, &param);
336			if (ret || (is_kprobe && param > PARAM_MAX_STACK))
337				ret = -EINVAL;
338			else {
339				f->fn = t->fetch[FETCH_MTD_stack];
340				f->data = (void *)param;
341			}
342		} else
343			ret = -EINVAL;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
344	} else
345		ret = -EINVAL;
346
347	return ret;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
348}
349
350/* Recursive argument parser */
351static int parse_probe_arg(char *arg, const struct fetch_type *t,
352		     struct fetch_param *f, bool is_return, bool is_kprobe)
 
 
353{
354	const struct fetch_type *ftbl;
355	unsigned long param;
356	long offset;
 
357	char *tmp;
358	int ret = 0;
359
360	ftbl = is_kprobe ? kprobes_fetch_type_table : uprobes_fetch_type_table;
361	BUG_ON(ftbl == NULL);
362
363	switch (arg[0]) {
364	case '$':
365		ret = parse_probe_vars(arg + 1, t, f, is_return, is_kprobe);
366		break;
367
368	case '%':	/* named register */
369		ret = regs_query_register_offset(arg + 1);
370		if (ret >= 0) {
371			f->fn = t->fetch[FETCH_MTD_reg];
372			f->data = (void *)(unsigned long)ret;
373			ret = 0;
374		}
 
375		break;
376
377	case '@':	/* memory, file-offset or symbol */
378		if (isdigit(arg[1])) {
379			ret = kstrtoul(arg + 1, 0, &param);
380			if (ret)
 
381				break;
382
383			f->fn = t->fetch[FETCH_MTD_memory];
384			f->data = (void *)param;
 
385		} else if (arg[1] == '+') {
386			/* kprobes don't support file offsets */
387			if (is_kprobe)
 
388				return -EINVAL;
389
390			ret = kstrtol(arg + 2, 0, &offset);
391			if (ret)
 
392				break;
 
393
394			f->fn = t->fetch[FETCH_MTD_file_offset];
395			f->data = (void *)offset;
396		} else {
397			/* uprobes don't support symbols */
398			if (!is_kprobe)
 
 
 
 
 
 
 
 
 
 
399				return -EINVAL;
400
401			ret = traceprobe_split_symbol_offset(arg + 1, &offset);
402			if (ret)
403				break;
404
405			f->data = alloc_symbol_cache(arg + 1, offset);
406			if (f->data)
407				f->fn = t->fetch[FETCH_MTD_symbol];
408		}
 
 
 
409		break;
410
411	case '+':	/* deref memory */
412		arg++;	/* Skip '+', because kstrtol() rejects it. */
413	case '-':
 
 
 
 
 
 
 
414		tmp = strchr(arg, '(');
415		if (!tmp)
416			break;
417
 
418		*tmp = '\0';
419		ret = kstrtol(arg, 0, &offset);
420
421		if (ret)
422			break;
423
 
424		arg = tmp + 1;
425		tmp = strrchr(arg, ')');
 
 
 
 
 
 
426
427		if (tmp) {
428			struct deref_fetch_param	*dprm;
429			const struct fetch_type		*t2;
430
431			t2 = find_fetch_type(NULL, ftbl);
432			*tmp = '\0';
433			dprm = kzalloc(sizeof(struct deref_fetch_param), GFP_KERNEL);
 
 
 
 
 
 
 
 
 
 
 
 
434
435			if (!dprm)
436				return -ENOMEM;
437
438			dprm->offset = offset;
439			dprm->fetch = t->fetch[FETCH_MTD_memory];
440			dprm->fetch_size = get_fetch_size_function(t,
441							dprm->fetch, ftbl);
442			ret = parse_probe_arg(arg, t2, &dprm->orig, is_return,
443							is_kprobe);
 
 
 
 
444			if (ret)
445				kfree(dprm);
446			else {
447				f->fn = t->fetch[FETCH_MTD_deref];
448				f->data = (void *)dprm;
449			}
450		}
451		break;
452	}
453	if (!ret && !f->fn) {	/* Parsed, but do not find fetch method */
454		pr_info("%s type has no corresponding fetch method.\n", t->name);
 
455		ret = -EINVAL;
456	}
457
458	return ret;
459}
460
461#define BYTES_TO_BITS(nb)	((BITS_PER_LONG * (nb)) / sizeof(long))
462
463/* Bitfield type needs to be parsed into a fetch function */
464static int __parse_bitfield_probe_arg(const char *bf,
465				      const struct fetch_type *t,
466				      struct fetch_param *f)
467{
468	struct bitfield_fetch_param *bprm;
469	unsigned long bw, bo;
470	char *tail;
471
472	if (*bf != 'b')
473		return 0;
474
475	bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);
476	if (!bprm)
477		return -ENOMEM;
478
479	bprm->orig = *f;
480	f->fn = t->fetch[FETCH_MTD_bitfield];
481	f->data = (void *)bprm;
482	bw = simple_strtoul(bf + 1, &tail, 0);	/* Use simple one */
483
484	if (bw == 0 || *tail != '@')
485		return -EINVAL;
486
487	bf = tail + 1;
488	bo = simple_strtoul(bf, &tail, 0);
489
490	if (tail == bf || *tail != '/')
491		return -EINVAL;
 
 
 
 
492
493	bprm->hi_shift = BYTES_TO_BITS(t->size) - (bw + bo);
494	bprm->low_shift = bprm->hi_shift + bo;
 
 
495
496	return (BYTES_TO_BITS(t->size) < (bw + bo)) ? -EINVAL : 0;
497}
498
499/* String length checking wrapper */
500int traceprobe_parse_probe_arg(char *arg, ssize_t *size,
501		struct probe_arg *parg, bool is_return, bool is_kprobe)
502{
503	const struct fetch_type *ftbl;
504	const char *t;
505	int ret;
506
507	ftbl = is_kprobe ? kprobes_fetch_type_table : uprobes_fetch_type_table;
508	BUG_ON(ftbl == NULL);
 
 
 
 
 
 
509
510	if (strlen(arg) > MAX_ARGSTR_LEN) {
511		pr_info("Argument is too long.: %s\n",  arg);
512		return -ENOSPC;
513	}
514	parg->comm = kstrdup(arg, GFP_KERNEL);
515	if (!parg->comm) {
516		pr_info("Failed to allocate memory for command '%s'.\n", arg);
517		return -ENOMEM;
518	}
519	t = strchr(parg->comm, ':');
520	if (t) {
521		arg[t - parg->comm] = '\0';
522		t++;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
523	}
524	parg->type = find_fetch_type(t, ftbl);
 
 
 
 
 
 
 
 
 
 
 
525	if (!parg->type) {
526		pr_info("Unsupported type: %s\n", t);
527		return -EINVAL;
528	}
529	parg->offset = *size;
530	*size += parg->type->size;
531	ret = parse_probe_arg(arg, parg->type, &parg->fetch, is_return, is_kprobe);
532
533	if (ret >= 0 && t != NULL)
534		ret = __parse_bitfield_probe_arg(t, parg->type, &parg->fetch);
 
 
 
 
 
 
 
 
 
 
 
535
536	if (ret >= 0) {
537		parg->fetch_size.fn = get_fetch_size_function(parg->type,
538							      parg->fetch.fn,
539							      ftbl);
540		parg->fetch_size.data = parg->fetch.data;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
541	}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
542
543	return ret;
544}
545
546/* Return 1 if name is reserved or already used by another argument */
547int traceprobe_conflict_field_name(const char *name,
548			       struct probe_arg *args, int narg)
549{
550	int i;
551
552	for (i = 0; i < ARRAY_SIZE(reserved_field_names); i++)
553		if (strcmp(reserved_field_names[i], name) == 0)
554			return 1;
555
556	for (i = 0; i < narg; i++)
557		if (strcmp(args[i].name, name) == 0)
558			return 1;
559
560	return 0;
561}
562
563void traceprobe_update_arg(struct probe_arg *arg)
 
564{
565	if (CHECK_FETCH_FUNCS(bitfield, arg->fetch.fn))
566		update_bitfield_fetch_param(arg->fetch.data);
567	else if (CHECK_FETCH_FUNCS(deref, arg->fetch.fn))
568		update_deref_fetch_param(arg->fetch.data);
569	else if (CHECK_FETCH_FUNCS(symbol, arg->fetch.fn))
570		update_symbol_cache(arg->fetch.data);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
571}
572
573void traceprobe_free_probe_arg(struct probe_arg *arg)
574{
575	if (CHECK_FETCH_FUNCS(bitfield, arg->fetch.fn))
576		free_bitfield_fetch_param(arg->fetch.data);
577	else if (CHECK_FETCH_FUNCS(deref, arg->fetch.fn))
578		free_deref_fetch_param(arg->fetch.data);
579	else if (CHECK_FETCH_FUNCS(symbol, arg->fetch.fn))
580		free_symbol_cache(arg->fetch.data);
581
 
 
 
 
 
 
 
582	kfree(arg->name);
583	kfree(arg->comm);
 
584}
585
586int traceprobe_command(const char *buf, int (*createfn)(int, char **))
587{
588	char **argv;
589	int argc, ret;
590
591	argc = 0;
592	ret = 0;
593	argv = argv_split(GFP_KERNEL, buf, &argc);
594	if (!argv)
595		return -ENOMEM;
596
597	if (argc)
598		ret = createfn(argc, argv);
599
600	argv_free(argv);
601
602	return ret;
603}
604
605#define WRITE_BUFSIZE  4096
606
607ssize_t traceprobe_probes_write(struct file *file, const char __user *buffer,
608				size_t count, loff_t *ppos,
609				int (*createfn)(int, char **))
610{
611	char *kbuf, *tmp;
612	int ret = 0;
613	size_t done = 0;
614	size_t size;
615
616	kbuf = kmalloc(WRITE_BUFSIZE, GFP_KERNEL);
617	if (!kbuf)
618		return -ENOMEM;
 
619
620	while (done < count) {
621		size = count - done;
622
623		if (size >= WRITE_BUFSIZE)
624			size = WRITE_BUFSIZE - 1;
 
 
625
626		if (copy_from_user(kbuf, buffer + done, size)) {
627			ret = -EFAULT;
628			goto out;
 
 
 
 
629		}
630		kbuf[size] = '\0';
631		tmp = strchr(kbuf, '\n');
632
633		if (tmp) {
634			*tmp = '\0';
635			size = tmp - kbuf + 1;
636		} else if (done + size < count) {
637			pr_warning("Line length is too long: "
638				   "Should be less than %d.", WRITE_BUFSIZE);
639			ret = -EINVAL;
640			goto out;
641		}
642		done += size;
643		/* Remove comments */
644		tmp = strchr(kbuf, '#');
645
646		if (tmp)
647			*tmp = '\0';
648
649		ret = traceprobe_command(kbuf, createfn);
650		if (ret)
651			goto out;
652	}
653	ret = done;
654
655out:
656	kfree(kbuf);
657
658	return ret;
659}
660
 
 
661static int __set_print_fmt(struct trace_probe *tp, char *buf, int len,
662			   bool is_return)
663{
664	int i;
 
665	int pos = 0;
666
667	const char *fmt, *arg;
668
669	if (!is_return) {
670		fmt = "(%lx)";
671		arg = "REC->" FIELD_STRING_IP;
672	} else {
673		fmt = "(%lx <- %lx)";
674		arg = "REC->" FIELD_STRING_FUNC ", REC->" FIELD_STRING_RETIP;
675	}
676
677	/* When len=0, we just calculate the needed length */
678#define LEN_OR_ZERO (len ? len - pos : 0)
679
680	pos += snprintf(buf + pos, LEN_OR_ZERO, "\"%s", fmt);
681
682	for (i = 0; i < tp->nr_args; i++) {
683		pos += snprintf(buf + pos, LEN_OR_ZERO, " %s=%s",
684				tp->args[i].name, tp->args[i].type->fmt);
 
 
 
 
 
 
 
 
 
 
685	}
686
687	pos += snprintf(buf + pos, LEN_OR_ZERO, "\", %s", arg);
688
689	for (i = 0; i < tp->nr_args; i++) {
690		if (strcmp(tp->args[i].type->name, "string") == 0)
 
 
 
 
 
 
 
 
 
 
 
 
 
691			pos += snprintf(buf + pos, LEN_OR_ZERO,
692					", __get_str(%s)",
693					tp->args[i].name);
694		else
695			pos += snprintf(buf + pos, LEN_OR_ZERO, ", REC->%s",
696					tp->args[i].name);
697	}
698
699#undef LEN_OR_ZERO
700
701	/* return the length of print_fmt */
702	return pos;
703}
 
704
705int set_print_fmt(struct trace_probe *tp, bool is_return)
706{
 
707	int len;
708	char *print_fmt;
709
710	/* First: called with 0 length to calculate the needed length */
711	len = __set_print_fmt(tp, NULL, 0, is_return);
712	print_fmt = kmalloc(len + 1, GFP_KERNEL);
713	if (!print_fmt)
714		return -ENOMEM;
715
716	/* Second: actually write the @print_fmt */
717	__set_print_fmt(tp, print_fmt, len + 1, is_return);
718	tp->call.print_fmt = print_fmt;
 
 
 
 
 
 
 
 
719
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
720	return 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
721}