xref: /openbmc/linux/kernel/trace/trace_probe.c (revision 5ec17af7)
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 const char *reserved_field_names[] = {
17 	"common_type",
18 	"common_flags",
19 	"common_preempt_count",
20 	"common_pid",
21 	"common_tgid",
22 	FIELD_STRING_IP,
23 	FIELD_STRING_RETIP,
24 	FIELD_STRING_FUNC,
25 };
26 
27 /* Printing  in basic type function template */
28 #define DEFINE_BASIC_PRINT_TYPE_FUNC(tname, type, fmt)			\
29 int PRINT_TYPE_FUNC_NAME(tname)(struct trace_seq *s, void *data, void *ent)\
30 {									\
31 	trace_seq_printf(s, fmt, *(type *)data);			\
32 	return !trace_seq_has_overflowed(s);				\
33 }									\
34 const char PRINT_TYPE_FMT_NAME(tname)[] = fmt;
35 
36 DEFINE_BASIC_PRINT_TYPE_FUNC(u8,  u8,  "%u")
37 DEFINE_BASIC_PRINT_TYPE_FUNC(u16, u16, "%u")
38 DEFINE_BASIC_PRINT_TYPE_FUNC(u32, u32, "%u")
39 DEFINE_BASIC_PRINT_TYPE_FUNC(u64, u64, "%Lu")
40 DEFINE_BASIC_PRINT_TYPE_FUNC(s8,  s8,  "%d")
41 DEFINE_BASIC_PRINT_TYPE_FUNC(s16, s16, "%d")
42 DEFINE_BASIC_PRINT_TYPE_FUNC(s32, s32, "%d")
43 DEFINE_BASIC_PRINT_TYPE_FUNC(s64, s64, "%Ld")
44 DEFINE_BASIC_PRINT_TYPE_FUNC(x8,  u8,  "0x%x")
45 DEFINE_BASIC_PRINT_TYPE_FUNC(x16, u16, "0x%x")
46 DEFINE_BASIC_PRINT_TYPE_FUNC(x32, u32, "0x%x")
47 DEFINE_BASIC_PRINT_TYPE_FUNC(x64, u64, "0x%Lx")
48 
49 int PRINT_TYPE_FUNC_NAME(symbol)(struct trace_seq *s, void *data, void *ent)
50 {
51 	trace_seq_printf(s, "%pS", (void *)*(unsigned long *)data);
52 	return !trace_seq_has_overflowed(s);
53 }
54 const char PRINT_TYPE_FMT_NAME(symbol)[] = "%pS";
55 
56 /* Print type function for string type */
57 int PRINT_TYPE_FUNC_NAME(string)(struct trace_seq *s, void *data, void *ent)
58 {
59 	int len = *(u32 *)data >> 16;
60 
61 	if (!len)
62 		trace_seq_puts(s, "(fault)");
63 	else
64 		trace_seq_printf(s, "\"%s\"",
65 				 (const char *)get_loc_data(data, ent));
66 	return !trace_seq_has_overflowed(s);
67 }
68 
69 const char PRINT_TYPE_FMT_NAME(string)[] = "\\\"%s\\\"";
70 
71 /* Fetch type information table */
72 static const struct fetch_type probe_fetch_types[] = {
73 	/* Special types */
74 	__ASSIGN_FETCH_TYPE("string", string, string, sizeof(u32), 1,
75 			    "__data_loc char[]"),
76 	/* Basic types */
77 	ASSIGN_FETCH_TYPE(u8,  u8,  0),
78 	ASSIGN_FETCH_TYPE(u16, u16, 0),
79 	ASSIGN_FETCH_TYPE(u32, u32, 0),
80 	ASSIGN_FETCH_TYPE(u64, u64, 0),
81 	ASSIGN_FETCH_TYPE(s8,  u8,  1),
82 	ASSIGN_FETCH_TYPE(s16, u16, 1),
83 	ASSIGN_FETCH_TYPE(s32, u32, 1),
84 	ASSIGN_FETCH_TYPE(s64, u64, 1),
85 	ASSIGN_FETCH_TYPE_ALIAS(x8,  u8,  u8,  0),
86 	ASSIGN_FETCH_TYPE_ALIAS(x16, u16, u16, 0),
87 	ASSIGN_FETCH_TYPE_ALIAS(x32, u32, u32, 0),
88 	ASSIGN_FETCH_TYPE_ALIAS(x64, u64, u64, 0),
89 	ASSIGN_FETCH_TYPE_ALIAS(symbol, ADDR_FETCH_TYPE, ADDR_FETCH_TYPE, 0),
90 
91 	ASSIGN_FETCH_TYPE_END
92 };
93 
94 static const struct fetch_type *find_fetch_type(const char *type)
95 {
96 	int i;
97 
98 	if (!type)
99 		type = DEFAULT_FETCH_TYPE_STR;
100 
101 	/* Special case: bitfield */
102 	if (*type == 'b') {
103 		unsigned long bs;
104 
105 		type = strchr(type, '/');
106 		if (!type)
107 			goto fail;
108 
109 		type++;
110 		if (kstrtoul(type, 0, &bs))
111 			goto fail;
112 
113 		switch (bs) {
114 		case 8:
115 			return find_fetch_type("u8");
116 		case 16:
117 			return find_fetch_type("u16");
118 		case 32:
119 			return find_fetch_type("u32");
120 		case 64:
121 			return find_fetch_type("u64");
122 		default:
123 			goto fail;
124 		}
125 	}
126 
127 	for (i = 0; probe_fetch_types[i].name; i++) {
128 		if (strcmp(type, probe_fetch_types[i].name) == 0)
129 			return &probe_fetch_types[i];
130 	}
131 
132 fail:
133 	return NULL;
134 }
135 
136 /* Split symbol and offset. */
137 int traceprobe_split_symbol_offset(char *symbol, long *offset)
138 {
139 	char *tmp;
140 	int ret;
141 
142 	if (!offset)
143 		return -EINVAL;
144 
145 	tmp = strpbrk(symbol, "+-");
146 	if (tmp) {
147 		ret = kstrtol(tmp, 0, offset);
148 		if (ret)
149 			return ret;
150 		*tmp = '\0';
151 	} else
152 		*offset = 0;
153 
154 	return 0;
155 }
156 
157 #define PARAM_MAX_STACK (THREAD_SIZE / sizeof(unsigned long))
158 
159 static int parse_probe_vars(char *arg, const struct fetch_type *t,
160 			    struct fetch_insn *code, unsigned int flags)
161 {
162 	int ret = 0;
163 	unsigned long param;
164 
165 	if (strcmp(arg, "retval") == 0) {
166 		if (flags & TPARG_FL_RETURN)
167 			code->op = FETCH_OP_RETVAL;
168 		else
169 			ret = -EINVAL;
170 	} else if (strncmp(arg, "stack", 5) == 0) {
171 		if (arg[5] == '\0') {
172 			code->op = FETCH_OP_STACKP;
173 		} else if (isdigit(arg[5])) {
174 			ret = kstrtoul(arg + 5, 10, &param);
175 			if (ret || ((flags & TPARG_FL_KERNEL) &&
176 				    param > PARAM_MAX_STACK))
177 				ret = -EINVAL;
178 			else {
179 				code->op = FETCH_OP_STACK;
180 				code->param = (unsigned int)param;
181 			}
182 		} else
183 			ret = -EINVAL;
184 	} else if (strcmp(arg, "comm") == 0) {
185 		code->op = FETCH_OP_COMM;
186 #ifdef CONFIG_HAVE_FUNCTION_ARG_ACCESS_API
187 	} else if (((flags & TPARG_FL_MASK) ==
188 		    (TPARG_FL_KERNEL | TPARG_FL_FENTRY)) &&
189 		   strncmp(arg, "arg", 3) == 0) {
190 		if (!isdigit(arg[3]))
191 			return -EINVAL;
192 		ret = kstrtoul(arg + 3, 10, &param);
193 		if (ret || !param || param > PARAM_MAX_STACK)
194 			return -EINVAL;
195 		code->op = FETCH_OP_ARG;
196 		code->param = (unsigned int)param - 1;
197 #endif
198 	} else
199 		ret = -EINVAL;
200 
201 	return ret;
202 }
203 
204 /* Recursive argument parser */
205 static int
206 parse_probe_arg(char *arg, const struct fetch_type *type,
207 		struct fetch_insn **pcode, struct fetch_insn *end,
208 		unsigned int flags)
209 {
210 	struct fetch_insn *code = *pcode;
211 	unsigned long param;
212 	long offset = 0;
213 	char *tmp;
214 	int ret = 0;
215 
216 	switch (arg[0]) {
217 	case '$':
218 		ret = parse_probe_vars(arg + 1, type, code, flags);
219 		break;
220 
221 	case '%':	/* named register */
222 		ret = regs_query_register_offset(arg + 1);
223 		if (ret >= 0) {
224 			code->op = FETCH_OP_REG;
225 			code->param = (unsigned int)ret;
226 			ret = 0;
227 		}
228 		break;
229 
230 	case '@':	/* memory, file-offset or symbol */
231 		if (isdigit(arg[1])) {
232 			ret = kstrtoul(arg + 1, 0, &param);
233 			if (ret)
234 				break;
235 			/* load address */
236 			code->op = FETCH_OP_IMM;
237 			code->immediate = param;
238 		} else if (arg[1] == '+') {
239 			/* kprobes don't support file offsets */
240 			if (flags & TPARG_FL_KERNEL)
241 				return -EINVAL;
242 
243 			ret = kstrtol(arg + 2, 0, &offset);
244 			if (ret)
245 				break;
246 
247 			code->op = FETCH_OP_FOFFS;
248 			code->immediate = (unsigned long)offset;  // imm64?
249 		} else {
250 			/* uprobes don't support symbols */
251 			if (!(flags & TPARG_FL_KERNEL))
252 				return -EINVAL;
253 
254 			/* Preserve symbol for updating */
255 			code->op = FETCH_NOP_SYMBOL;
256 			code->data = kstrdup(arg + 1, GFP_KERNEL);
257 			if (!code->data)
258 				return -ENOMEM;
259 			if (++code == end)
260 				return -E2BIG;
261 
262 			code->op = FETCH_OP_IMM;
263 			code->immediate = 0;
264 		}
265 		/* These are fetching from memory */
266 		if (++code == end)
267 			return -E2BIG;
268 		*pcode = code;
269 		code->op = FETCH_OP_DEREF;
270 		code->offset = offset;
271 		break;
272 
273 	case '+':	/* deref memory */
274 		arg++;	/* Skip '+', because kstrtol() rejects it. */
275 	case '-':
276 		tmp = strchr(arg, '(');
277 		if (!tmp)
278 			return -EINVAL;
279 
280 		*tmp = '\0';
281 		ret = kstrtol(arg, 0, &offset);
282 		if (ret)
283 			break;
284 
285 		arg = tmp + 1;
286 		tmp = strrchr(arg, ')');
287 
288 		if (tmp) {
289 			const struct fetch_type *t2 = find_fetch_type(NULL);
290 
291 			*tmp = '\0';
292 			ret = parse_probe_arg(arg, t2, &code, end, flags);
293 			if (ret)
294 				break;
295 			if (code->op == FETCH_OP_COMM)
296 				return -EINVAL;
297 			if (++code == end)
298 				return -E2BIG;
299 			*pcode = code;
300 
301 			code->op = FETCH_OP_DEREF;
302 			code->offset = offset;
303 		}
304 		break;
305 	}
306 	if (!ret && code->op == FETCH_OP_NOP) {
307 		/* Parsed, but do not find fetch method */
308 		ret = -EINVAL;
309 	}
310 	return ret;
311 }
312 
313 #define BYTES_TO_BITS(nb)	((BITS_PER_LONG * (nb)) / sizeof(long))
314 
315 /* Bitfield type needs to be parsed into a fetch function */
316 static int __parse_bitfield_probe_arg(const char *bf,
317 				      const struct fetch_type *t,
318 				      struct fetch_insn **pcode)
319 {
320 	struct fetch_insn *code = *pcode;
321 	unsigned long bw, bo;
322 	char *tail;
323 
324 	if (*bf != 'b')
325 		return 0;
326 
327 	bw = simple_strtoul(bf + 1, &tail, 0);	/* Use simple one */
328 
329 	if (bw == 0 || *tail != '@')
330 		return -EINVAL;
331 
332 	bf = tail + 1;
333 	bo = simple_strtoul(bf, &tail, 0);
334 
335 	if (tail == bf || *tail != '/')
336 		return -EINVAL;
337 	code++;
338 	if (code->op != FETCH_OP_NOP)
339 		return -E2BIG;
340 	*pcode = code;
341 
342 	code->op = FETCH_OP_MOD_BF;
343 	code->lshift = BYTES_TO_BITS(t->size) - (bw + bo);
344 	code->rshift = BYTES_TO_BITS(t->size) - bw;
345 	code->basesize = t->size;
346 
347 	return (BYTES_TO_BITS(t->size) < (bw + bo)) ? -EINVAL : 0;
348 }
349 
350 /* String length checking wrapper */
351 int traceprobe_parse_probe_arg(char *arg, ssize_t *size,
352 		struct probe_arg *parg, unsigned int flags)
353 {
354 	struct fetch_insn *code, *scode, *tmp = NULL;
355 	char *t, *t2;
356 	int ret, len;
357 
358 	if (strlen(arg) > MAX_ARGSTR_LEN) {
359 		pr_info("Argument is too long.: %s\n",  arg);
360 		return -ENOSPC;
361 	}
362 	parg->comm = kstrdup(arg, GFP_KERNEL);
363 	if (!parg->comm) {
364 		pr_info("Failed to allocate memory for command '%s'.\n", arg);
365 		return -ENOMEM;
366 	}
367 	t = strchr(arg, ':');
368 	if (t) {
369 		*t = '\0';
370 		t2 = strchr(++t, '[');
371 		if (t2) {
372 			*t2 = '\0';
373 			parg->count = simple_strtoul(t2 + 1, &t2, 0);
374 			if (strcmp(t2, "]") || parg->count == 0)
375 				return -EINVAL;
376 			if (parg->count > MAX_ARRAY_LEN)
377 				return -E2BIG;
378 		}
379 	}
380 	/*
381 	 * The default type of $comm should be "string", and it can't be
382 	 * dereferenced.
383 	 */
384 	if (!t && strcmp(arg, "$comm") == 0)
385 		parg->type = find_fetch_type("string");
386 	else
387 		parg->type = find_fetch_type(t);
388 	if (!parg->type) {
389 		pr_info("Unsupported type: %s\n", t);
390 		return -EINVAL;
391 	}
392 	parg->offset = *size;
393 	*size += parg->type->size * (parg->count ?: 1);
394 
395 	if (parg->count) {
396 		len = strlen(parg->type->fmttype) + 6;
397 		parg->fmt = kmalloc(len, GFP_KERNEL);
398 		if (!parg->fmt)
399 			return -ENOMEM;
400 		snprintf(parg->fmt, len, "%s[%d]", parg->type->fmttype,
401 			 parg->count);
402 	}
403 
404 	code = tmp = kzalloc(sizeof(*code) * FETCH_INSN_MAX, GFP_KERNEL);
405 	if (!code)
406 		return -ENOMEM;
407 	code[FETCH_INSN_MAX - 1].op = FETCH_OP_END;
408 
409 	ret = parse_probe_arg(arg, parg->type, &code, &code[FETCH_INSN_MAX - 1],
410 			      flags);
411 	if (ret)
412 		goto fail;
413 
414 	/* Store operation */
415 	if (!strcmp(parg->type->name, "string")) {
416 		if (code->op != FETCH_OP_DEREF && code->op != FETCH_OP_IMM &&
417 		    code->op != FETCH_OP_COMM) {
418 			pr_info("string only accepts memory or address.\n");
419 			ret = -EINVAL;
420 			goto fail;
421 		}
422 		if (code->op != FETCH_OP_DEREF || parg->count) {
423 			/*
424 			 * IMM and COMM is pointing actual address, those must
425 			 * be kept, and if parg->count != 0, this is an array
426 			 * of string pointers instead of string address itself.
427 			 */
428 			code++;
429 			if (code->op != FETCH_OP_NOP) {
430 				ret = -E2BIG;
431 				goto fail;
432 			}
433 		}
434 		code->op = FETCH_OP_ST_STRING;	/* In DEREF case, replace it */
435 		code->size = parg->type->size;
436 		parg->dynamic = true;
437 	} else if (code->op == FETCH_OP_DEREF) {
438 		code->op = FETCH_OP_ST_MEM;
439 		code->size = parg->type->size;
440 	} else {
441 		code++;
442 		if (code->op != FETCH_OP_NOP) {
443 			ret = -E2BIG;
444 			goto fail;
445 		}
446 		code->op = FETCH_OP_ST_RAW;
447 		code->size = parg->type->size;
448 	}
449 	scode = code;
450 	/* Modify operation */
451 	if (t != NULL) {
452 		ret = __parse_bitfield_probe_arg(t, parg->type, &code);
453 		if (ret)
454 			goto fail;
455 	}
456 	/* Loop(Array) operation */
457 	if (parg->count) {
458 		if (scode->op != FETCH_OP_ST_MEM &&
459 		    scode->op != FETCH_OP_ST_STRING) {
460 			pr_info("array only accepts memory or address\n");
461 			ret = -EINVAL;
462 			goto fail;
463 		}
464 		code++;
465 		if (code->op != FETCH_OP_NOP) {
466 			ret = -E2BIG;
467 			goto fail;
468 		}
469 		code->op = FETCH_OP_LP_ARRAY;
470 		code->param = parg->count;
471 	}
472 	code++;
473 	code->op = FETCH_OP_END;
474 
475 	/* Shrink down the code buffer */
476 	parg->code = kzalloc(sizeof(*code) * (code - tmp + 1), GFP_KERNEL);
477 	if (!parg->code)
478 		ret = -ENOMEM;
479 	else
480 		memcpy(parg->code, tmp, sizeof(*code) * (code - tmp + 1));
481 
482 fail:
483 	if (ret) {
484 		for (code = tmp; code < tmp + FETCH_INSN_MAX; code++)
485 			if (code->op == FETCH_NOP_SYMBOL)
486 				kfree(code->data);
487 	}
488 	kfree(tmp);
489 
490 	return ret;
491 }
492 
493 /* Return 1 if name is reserved or already used by another argument */
494 int traceprobe_conflict_field_name(const char *name,
495 			       struct probe_arg *args, int narg)
496 {
497 	int i;
498 
499 	for (i = 0; i < ARRAY_SIZE(reserved_field_names); i++)
500 		if (strcmp(reserved_field_names[i], name) == 0)
501 			return 1;
502 
503 	for (i = 0; i < narg; i++)
504 		if (strcmp(args[i].name, name) == 0)
505 			return 1;
506 
507 	return 0;
508 }
509 
510 void traceprobe_free_probe_arg(struct probe_arg *arg)
511 {
512 	struct fetch_insn *code = arg->code;
513 
514 	while (code && code->op != FETCH_OP_END) {
515 		if (code->op == FETCH_NOP_SYMBOL)
516 			kfree(code->data);
517 		code++;
518 	}
519 	kfree(arg->code);
520 	kfree(arg->name);
521 	kfree(arg->comm);
522 	kfree(arg->fmt);
523 }
524 
525 int traceprobe_update_arg(struct probe_arg *arg)
526 {
527 	struct fetch_insn *code = arg->code;
528 	long offset;
529 	char *tmp;
530 	char c;
531 	int ret = 0;
532 
533 	while (code && code->op != FETCH_OP_END) {
534 		if (code->op == FETCH_NOP_SYMBOL) {
535 			if (code[1].op != FETCH_OP_IMM)
536 				return -EINVAL;
537 
538 			tmp = strpbrk("+-", code->data);
539 			if (tmp)
540 				c = *tmp;
541 			ret = traceprobe_split_symbol_offset(code->data,
542 							     &offset);
543 			if (ret)
544 				return ret;
545 
546 			code[1].immediate =
547 				(unsigned long)kallsyms_lookup_name(code->data);
548 			if (tmp)
549 				*tmp = c;
550 			if (!code[1].immediate)
551 				return -ENOENT;
552 			code[1].immediate += offset;
553 		}
554 		code++;
555 	}
556 	return 0;
557 }
558 
559 /* When len=0, we just calculate the needed length */
560 #define LEN_OR_ZERO (len ? len - pos : 0)
561 static int __set_print_fmt(struct trace_probe *tp, char *buf, int len,
562 			   bool is_return)
563 {
564 	struct probe_arg *parg;
565 	int i, j;
566 	int pos = 0;
567 	const char *fmt, *arg;
568 
569 	if (!is_return) {
570 		fmt = "(%lx)";
571 		arg = "REC->" FIELD_STRING_IP;
572 	} else {
573 		fmt = "(%lx <- %lx)";
574 		arg = "REC->" FIELD_STRING_FUNC ", REC->" FIELD_STRING_RETIP;
575 	}
576 
577 	pos += snprintf(buf + pos, LEN_OR_ZERO, "\"%s", fmt);
578 
579 	for (i = 0; i < tp->nr_args; i++) {
580 		parg = tp->args + i;
581 		pos += snprintf(buf + pos, LEN_OR_ZERO, " %s=", parg->name);
582 		if (parg->count) {
583 			pos += snprintf(buf + pos, LEN_OR_ZERO, "{%s",
584 					parg->type->fmt);
585 			for (j = 1; j < parg->count; j++)
586 				pos += snprintf(buf + pos, LEN_OR_ZERO, ",%s",
587 						parg->type->fmt);
588 			pos += snprintf(buf + pos, LEN_OR_ZERO, "}");
589 		} else
590 			pos += snprintf(buf + pos, LEN_OR_ZERO, "%s",
591 					parg->type->fmt);
592 	}
593 
594 	pos += snprintf(buf + pos, LEN_OR_ZERO, "\", %s", arg);
595 
596 	for (i = 0; i < tp->nr_args; i++) {
597 		parg = tp->args + i;
598 		if (parg->count) {
599 			if (strcmp(parg->type->name, "string") == 0)
600 				fmt = ", __get_str(%s[%d])";
601 			else
602 				fmt = ", REC->%s[%d]";
603 			for (j = 0; j < parg->count; j++)
604 				pos += snprintf(buf + pos, LEN_OR_ZERO,
605 						fmt, parg->name, j);
606 		} else {
607 			if (strcmp(parg->type->name, "string") == 0)
608 				fmt = ", __get_str(%s)";
609 			else
610 				fmt = ", REC->%s";
611 			pos += snprintf(buf + pos, LEN_OR_ZERO,
612 					fmt, parg->name);
613 		}
614 	}
615 
616 	/* return the length of print_fmt */
617 	return pos;
618 }
619 #undef LEN_OR_ZERO
620 
621 int traceprobe_set_print_fmt(struct trace_probe *tp, bool is_return)
622 {
623 	int len;
624 	char *print_fmt;
625 
626 	/* First: called with 0 length to calculate the needed length */
627 	len = __set_print_fmt(tp, NULL, 0, is_return);
628 	print_fmt = kmalloc(len + 1, GFP_KERNEL);
629 	if (!print_fmt)
630 		return -ENOMEM;
631 
632 	/* Second: actually write the @print_fmt */
633 	__set_print_fmt(tp, print_fmt, len + 1, is_return);
634 	tp->call.print_fmt = print_fmt;
635 
636 	return 0;
637 }
638 
639 int traceprobe_define_arg_fields(struct trace_event_call *event_call,
640 				 size_t offset, struct trace_probe *tp)
641 {
642 	int ret, i;
643 
644 	/* Set argument names as fields */
645 	for (i = 0; i < tp->nr_args; i++) {
646 		struct probe_arg *parg = &tp->args[i];
647 		const char *fmt = parg->type->fmttype;
648 		int size = parg->type->size;
649 
650 		if (parg->fmt)
651 			fmt = parg->fmt;
652 		if (parg->count)
653 			size *= parg->count;
654 		ret = trace_define_field(event_call, fmt, parg->name,
655 					 offset + parg->offset, size,
656 					 parg->type->is_signed,
657 					 FILTER_OTHER);
658 		if (ret)
659 			return ret;
660 	}
661 	return 0;
662 }
663