]> asedeno.scripts.mit.edu Git - linux.git/blob - kernel/trace/trace_probe.c
c59c69cb2f2e53192e7664cb132713effb51375d
[linux.git] / kernel / trace / trace_probe.c
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 /* Print type function for string type */
50 int PRINT_TYPE_FUNC_NAME(string)(struct trace_seq *s, void *data, void *ent)
51 {
52         int len = *(u32 *)data >> 16;
53
54         if (!len)
55                 trace_seq_puts(s, "(fault)");
56         else
57                 trace_seq_printf(s, "\"%s\"",
58                                  (const char *)get_loc_data(data, ent));
59         return !trace_seq_has_overflowed(s);
60 }
61
62 const char PRINT_TYPE_FMT_NAME(string)[] = "\\\"%s\\\"";
63
64 static const struct fetch_type *find_fetch_type(const char *type,
65                                                 const struct fetch_type *ftbl)
66 {
67         int i;
68
69         if (!type)
70                 type = DEFAULT_FETCH_TYPE_STR;
71
72         /* Special case: bitfield */
73         if (*type == 'b') {
74                 unsigned long bs;
75
76                 type = strchr(type, '/');
77                 if (!type)
78                         goto fail;
79
80                 type++;
81                 if (kstrtoul(type, 0, &bs))
82                         goto fail;
83
84                 switch (bs) {
85                 case 8:
86                         return find_fetch_type("u8", ftbl);
87                 case 16:
88                         return find_fetch_type("u16", ftbl);
89                 case 32:
90                         return find_fetch_type("u32", ftbl);
91                 case 64:
92                         return find_fetch_type("u64", ftbl);
93                 default:
94                         goto fail;
95                 }
96         }
97
98         for (i = 0; ftbl[i].name; i++) {
99                 if (strcmp(type, ftbl[i].name) == 0)
100                         return &ftbl[i];
101         }
102
103 fail:
104         return NULL;
105 }
106
107 /* Split symbol and offset. */
108 int traceprobe_split_symbol_offset(char *symbol, long *offset)
109 {
110         char *tmp;
111         int ret;
112
113         if (!offset)
114                 return -EINVAL;
115
116         tmp = strpbrk(symbol, "+-");
117         if (tmp) {
118                 ret = kstrtol(tmp, 0, offset);
119                 if (ret)
120                         return ret;
121                 *tmp = '\0';
122         } else
123                 *offset = 0;
124
125         return 0;
126 }
127
128 #define PARAM_MAX_STACK (THREAD_SIZE / sizeof(unsigned long))
129
130 static int parse_probe_vars(char *arg, const struct fetch_type *t,
131                             struct fetch_insn *code, bool is_return,
132                             bool is_kprobe)
133 {
134         int ret = 0;
135         unsigned long param;
136
137         if (strcmp(arg, "retval") == 0) {
138                 if (is_return)
139                         code->op = FETCH_OP_RETVAL;
140                 else
141                         ret = -EINVAL;
142         } else if (strncmp(arg, "stack", 5) == 0) {
143                 if (arg[5] == '\0') {
144                         code->op = FETCH_OP_STACKP;
145                 } else if (isdigit(arg[5])) {
146                         ret = kstrtoul(arg + 5, 10, &param);
147                         if (ret || (is_kprobe && param > PARAM_MAX_STACK))
148                                 ret = -EINVAL;
149                         else {
150                                 code->op = FETCH_OP_STACK;
151                                 code->param = (unsigned int)param;
152                         }
153                 } else
154                         ret = -EINVAL;
155         } else if (strcmp(arg, "comm") == 0) {
156                 code->op = FETCH_OP_COMM;
157         } else
158                 ret = -EINVAL;
159
160         return ret;
161 }
162
163 /* Recursive argument parser */
164 static int
165 parse_probe_arg(char *arg, const struct fetch_type *type,
166                 struct fetch_insn **pcode, struct fetch_insn *end,
167                 bool is_return, bool is_kprobe,
168                 const struct fetch_type *ftbl)
169 {
170         struct fetch_insn *code = *pcode;
171         unsigned long param;
172         long offset;
173         char *tmp;
174         int ret = 0;
175
176         switch (arg[0]) {
177         case '$':
178                 ret = parse_probe_vars(arg + 1, type, code,
179                                         is_return, is_kprobe);
180                 break;
181
182         case '%':       /* named register */
183                 ret = regs_query_register_offset(arg + 1);
184                 if (ret >= 0) {
185                         code->op = FETCH_OP_REG;
186                         code->param = (unsigned int)ret;
187                         ret = 0;
188                 }
189                 break;
190
191         case '@':       /* memory, file-offset or symbol */
192                 if (isdigit(arg[1])) {
193                         ret = kstrtoul(arg + 1, 0, &param);
194                         if (ret)
195                                 break;
196                         /* load address */
197                         code->op = FETCH_OP_IMM;
198                         code->immediate = param;
199                 } else if (arg[1] == '+') {
200                         /* kprobes don't support file offsets */
201                         if (is_kprobe)
202                                 return -EINVAL;
203
204                         ret = kstrtol(arg + 2, 0, &offset);
205                         if (ret)
206                                 break;
207
208                         code->op = FETCH_OP_FOFFS;
209                         code->immediate = (unsigned long)offset;  // imm64?
210                 } else {
211                         /* uprobes don't support symbols */
212                         if (!is_kprobe)
213                                 return -EINVAL;
214
215                         ret = traceprobe_split_symbol_offset(arg + 1, &offset);
216                         if (ret)
217                                 break;
218
219                         code->op = FETCH_OP_IMM;
220                         code->immediate =
221                                 (unsigned long)kallsyms_lookup_name(arg + 1);
222                         if (!code->immediate)
223                                 return -ENOENT;
224                         code->immediate += offset;
225                 }
226                 /* These are fetching from memory */
227                 if (++code == end)
228                         return -E2BIG;
229                 *pcode = code;
230                 code->op = FETCH_OP_DEREF;
231                 code->offset = offset;
232                 break;
233
234         case '+':       /* deref memory */
235                 arg++;  /* Skip '+', because kstrtol() rejects it. */
236         case '-':
237                 tmp = strchr(arg, '(');
238                 if (!tmp)
239                         return -EINVAL;
240
241                 *tmp = '\0';
242                 ret = kstrtol(arg, 0, &offset);
243                 if (ret)
244                         break;
245
246                 arg = tmp + 1;
247                 tmp = strrchr(arg, ')');
248
249                 if (tmp) {
250                         const struct fetch_type *t2;
251
252                         t2 = find_fetch_type(NULL, ftbl);
253                         *tmp = '\0';
254                         ret = parse_probe_arg(arg, t2, &code, end, is_return,
255                                               is_kprobe, ftbl);
256                         if (ret)
257                                 break;
258                         if (code->op == FETCH_OP_COMM)
259                                 return -EINVAL;
260                         if (++code == end)
261                                 return -E2BIG;
262                         *pcode = code;
263
264                         code->op = FETCH_OP_DEREF;
265                         code->offset = offset;
266                 }
267                 break;
268         }
269         if (!ret && code->op == FETCH_OP_NOP) {
270                 /* Parsed, but do not find fetch method */
271                 ret = -EINVAL;
272         }
273         return ret;
274 }
275
276 #define BYTES_TO_BITS(nb)       ((BITS_PER_LONG * (nb)) / sizeof(long))
277
278 /* Bitfield type needs to be parsed into a fetch function */
279 static int __parse_bitfield_probe_arg(const char *bf,
280                                       const struct fetch_type *t,
281                                       struct fetch_insn **pcode)
282 {
283         struct fetch_insn *code = *pcode;
284         unsigned long bw, bo;
285         char *tail;
286
287         if (*bf != 'b')
288                 return 0;
289
290         bw = simple_strtoul(bf + 1, &tail, 0);  /* Use simple one */
291
292         if (bw == 0 || *tail != '@')
293                 return -EINVAL;
294
295         bf = tail + 1;
296         bo = simple_strtoul(bf, &tail, 0);
297
298         if (tail == bf || *tail != '/')
299                 return -EINVAL;
300         code++;
301         if (code->op != FETCH_OP_NOP)
302                 return -E2BIG;
303         *pcode = code;
304
305         code->op = FETCH_OP_MOD_BF;
306         code->lshift = BYTES_TO_BITS(t->size) - (bw + bo);
307         code->rshift = BYTES_TO_BITS(t->size) - bw;
308         code->basesize = t->size;
309
310         return (BYTES_TO_BITS(t->size) < (bw + bo)) ? -EINVAL : 0;
311 }
312
313 /* String length checking wrapper */
314 int traceprobe_parse_probe_arg(char *arg, ssize_t *size,
315                 struct probe_arg *parg, bool is_return, bool is_kprobe,
316                 const struct fetch_type *ftbl)
317 {
318         struct fetch_insn *code, *tmp = NULL;
319         const char *t;
320         int ret;
321
322         if (strlen(arg) > MAX_ARGSTR_LEN) {
323                 pr_info("Argument is too long.: %s\n",  arg);
324                 return -ENOSPC;
325         }
326         parg->comm = kstrdup(arg, GFP_KERNEL);
327         if (!parg->comm) {
328                 pr_info("Failed to allocate memory for command '%s'.\n", arg);
329                 return -ENOMEM;
330         }
331         t = strchr(parg->comm, ':');
332         if (t) {
333                 arg[t - parg->comm] = '\0';
334                 t++;
335         }
336         /*
337          * The default type of $comm should be "string", and it can't be
338          * dereferenced.
339          */
340         if (!t && strcmp(arg, "$comm") == 0)
341                 t = "string";
342         parg->type = find_fetch_type(t, ftbl);
343         if (!parg->type) {
344                 pr_info("Unsupported type: %s\n", t);
345                 return -EINVAL;
346         }
347         parg->offset = *size;
348         *size += parg->type->size;
349
350         code = tmp = kzalloc(sizeof(*code) * FETCH_INSN_MAX, GFP_KERNEL);
351         if (!code)
352                 return -ENOMEM;
353         code[FETCH_INSN_MAX - 1].op = FETCH_OP_END;
354
355         ret = parse_probe_arg(arg, parg->type, &code, &code[FETCH_INSN_MAX - 1],
356                               is_return, is_kprobe, ftbl);
357         if (ret)
358                 goto fail;
359
360         /* Store operation */
361         if (!strcmp(parg->type->name, "string")) {
362                 if (code->op != FETCH_OP_DEREF && code->op != FETCH_OP_IMM &&
363                     code->op != FETCH_OP_COMM) {
364                         pr_info("string only accepts memory or address.\n");
365                         ret = -EINVAL;
366                         goto fail;
367                 }
368                 /* Since IMM or COMM must be the 1st insn, this is safe */
369                 if (code->op == FETCH_OP_IMM || code->op == FETCH_OP_COMM)
370                         code++;
371                 code->op = FETCH_OP_ST_STRING;  /* In DEREF case, replace it */
372                 parg->dynamic = true;
373         } else if (code->op == FETCH_OP_DEREF) {
374                 code->op = FETCH_OP_ST_MEM;
375                 code->size = parg->type->size;
376         } else {
377                 code++;
378                 if (code->op != FETCH_OP_NOP) {
379                         ret = -E2BIG;
380                         goto fail;
381                 }
382                 code->op = FETCH_OP_ST_RAW;
383                 code->size = parg->type->size;
384         }
385         /* Modify operation */
386         if (t != NULL) {
387                 ret = __parse_bitfield_probe_arg(t, parg->type, &code);
388                 if (ret)
389                         goto fail;
390         }
391         code++;
392         code->op = FETCH_OP_END;
393
394         /* Shrink down the code buffer */
395         parg->code = kzalloc(sizeof(*code) * (code - tmp + 1), GFP_KERNEL);
396         if (!parg->code)
397                 ret = -ENOMEM;
398         else
399                 memcpy(parg->code, tmp, sizeof(*code) * (code - tmp + 1));
400
401 fail:
402         kfree(tmp);
403
404         return ret;
405 }
406
407 /* Return 1 if name is reserved or already used by another argument */
408 int traceprobe_conflict_field_name(const char *name,
409                                struct probe_arg *args, int narg)
410 {
411         int i;
412
413         for (i = 0; i < ARRAY_SIZE(reserved_field_names); i++)
414                 if (strcmp(reserved_field_names[i], name) == 0)
415                         return 1;
416
417         for (i = 0; i < narg; i++)
418                 if (strcmp(args[i].name, name) == 0)
419                         return 1;
420
421         return 0;
422 }
423
424 void traceprobe_free_probe_arg(struct probe_arg *arg)
425 {
426         kfree(arg->code);
427         kfree(arg->name);
428         kfree(arg->comm);
429 }
430
431 static int __set_print_fmt(struct trace_probe *tp, char *buf, int len,
432                            bool is_return)
433 {
434         int i;
435         int pos = 0;
436
437         const char *fmt, *arg;
438
439         if (!is_return) {
440                 fmt = "(%lx)";
441                 arg = "REC->" FIELD_STRING_IP;
442         } else {
443                 fmt = "(%lx <- %lx)";
444                 arg = "REC->" FIELD_STRING_FUNC ", REC->" FIELD_STRING_RETIP;
445         }
446
447         /* When len=0, we just calculate the needed length */
448 #define LEN_OR_ZERO (len ? len - pos : 0)
449
450         pos += snprintf(buf + pos, LEN_OR_ZERO, "\"%s", fmt);
451
452         for (i = 0; i < tp->nr_args; i++) {
453                 pos += snprintf(buf + pos, LEN_OR_ZERO, " %s=%s",
454                                 tp->args[i].name, tp->args[i].type->fmt);
455         }
456
457         pos += snprintf(buf + pos, LEN_OR_ZERO, "\", %s", arg);
458
459         for (i = 0; i < tp->nr_args; i++) {
460                 if (strcmp(tp->args[i].type->name, "string") == 0)
461                         pos += snprintf(buf + pos, LEN_OR_ZERO,
462                                         ", __get_str(%s)",
463                                         tp->args[i].name);
464                 else
465                         pos += snprintf(buf + pos, LEN_OR_ZERO, ", REC->%s",
466                                         tp->args[i].name);
467         }
468
469 #undef LEN_OR_ZERO
470
471         /* return the length of print_fmt */
472         return pos;
473 }
474
475 int set_print_fmt(struct trace_probe *tp, bool is_return)
476 {
477         int len;
478         char *print_fmt;
479
480         /* First: called with 0 length to calculate the needed length */
481         len = __set_print_fmt(tp, NULL, 0, is_return);
482         print_fmt = kmalloc(len + 1, GFP_KERNEL);
483         if (!print_fmt)
484                 return -ENOMEM;
485
486         /* Second: actually write the @print_fmt */
487         __set_print_fmt(tp, print_fmt, len + 1, is_return);
488         tp->call.print_fmt = print_fmt;
489
490         return 0;
491 }
492
493 int traceprobe_define_arg_fields(struct trace_event_call *event_call,
494                                  size_t offset, struct trace_probe *tp)
495 {
496         int ret, i;
497
498         /* Set argument names as fields */
499         for (i = 0; i < tp->nr_args; i++) {
500                 struct probe_arg *parg = &tp->args[i];
501
502                 ret = trace_define_field(event_call, parg->type->fmttype,
503                                          parg->name,
504                                          offset + parg->offset,
505                                          parg->type->size,
506                                          parg->type->is_signed,
507                                          FILTER_OTHER);
508                 if (ret)
509                         return ret;
510         }
511         return 0;
512 }