root/kernel/trace/trace_probe.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. DEFINE_BASIC_PRINT_TYPE_FUNC
  2. find_fetch_type
  3. trace_probe_log_init
  4. trace_probe_log_clear
  5. trace_probe_log_set_index
  6. __trace_probe_log_err
  7. traceprobe_split_symbol_offset
  8. traceprobe_parse_event_name
  9. parse_probe_vars
  10. str_to_immediate
  11. __parse_imm_string
  12. parse_probe_arg
  13. __parse_bitfield_probe_arg
  14. traceprobe_parse_probe_arg_body
  15. traceprobe_conflict_field_name
  16. traceprobe_parse_probe_arg
  17. traceprobe_free_probe_arg
  18. traceprobe_update_arg
  19. __set_print_fmt
  20. traceprobe_set_print_fmt
  21. traceprobe_define_arg_fields
  22. trace_probe_event_free
  23. trace_probe_append
  24. trace_probe_unlink
  25. trace_probe_cleanup
  26. trace_probe_init
  27. trace_probe_register_event_call
  28. trace_probe_add_file
  29. trace_probe_get_file_link
  30. trace_probe_remove_file
  31. trace_probe_compare_arg_type
  32. trace_probe_match_command_args

   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 
  19 static const char *trace_probe_err_text[] = { ERRORS };
  20 
  21 static 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)                  \
  34 int 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 }                                                                       \
  39 const char PRINT_TYPE_FMT_NAME(tname)[] = fmt;
  40 
  41 DEFINE_BASIC_PRINT_TYPE_FUNC(u8,  u8,  "%u")
  42 DEFINE_BASIC_PRINT_TYPE_FUNC(u16, u16, "%u")
  43 DEFINE_BASIC_PRINT_TYPE_FUNC(u32, u32, "%u")
  44 DEFINE_BASIC_PRINT_TYPE_FUNC(u64, u64, "%Lu")
  45 DEFINE_BASIC_PRINT_TYPE_FUNC(s8,  s8,  "%d")
  46 DEFINE_BASIC_PRINT_TYPE_FUNC(s16, s16, "%d")
  47 DEFINE_BASIC_PRINT_TYPE_FUNC(s32, s32, "%d")
  48 DEFINE_BASIC_PRINT_TYPE_FUNC(s64, s64, "%Ld")
  49 DEFINE_BASIC_PRINT_TYPE_FUNC(x8,  u8,  "0x%x")
  50 DEFINE_BASIC_PRINT_TYPE_FUNC(x16, u16, "0x%x")
  51 DEFINE_BASIC_PRINT_TYPE_FUNC(x32, u32, "0x%x")
  52 DEFINE_BASIC_PRINT_TYPE_FUNC(x64, u64, "0x%Lx")
  53 
  54 int 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 }
  59 const char PRINT_TYPE_FMT_NAME(symbol)[] = "%pS";
  60 
  61 /* Print type function for string type */
  62 int 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 
  74 const char PRINT_TYPE_FMT_NAME(string)[] = "\\\"%s\\\"";
  75 
  76 /* Fetch type information table */
  77 static 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 
 101 static 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 
 139 fail:
 140         return NULL;
 141 }
 142 
 143 static struct trace_probe_log trace_probe_log;
 144 
 145 void 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 
 153 void trace_probe_log_clear(void)
 154 {
 155         memset(&trace_probe_log, 0, sizeof(trace_probe_log));
 156 }
 157 
 158 void trace_probe_log_set_index(int index)
 159 {
 160         trace_probe_log.index = index;
 161 }
 162 
 163 void __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. */
 208 int 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 */
 229 int 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 
 272 static 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 
 324 inval_var:
 325         trace_probe_log_err(offs, BAD_VAR);
 326         return -EINVAL;
 327 }
 328 
 329 static 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 
 340 static 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 */
 353 static int
 354 parse_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 */
 508 static 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 */
 543 static 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 
 719 fail:
 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 */
 732 static 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 
 748 int 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 
 789 void 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 
 805 int 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)
 841 static 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                             (strcmp(parg->type->name, "ustring") == 0))
 881                                 fmt = ", __get_str(%s[%d])";
 882                         else
 883                                 fmt = ", REC->%s[%d]";
 884                         for (j = 0; j < parg->count; j++)
 885                                 pos += snprintf(buf + pos, LEN_OR_ZERO,
 886                                                 fmt, parg->name, j);
 887                 } else {
 888                         if ((strcmp(parg->type->name, "string") == 0) ||
 889                             (strcmp(parg->type->name, "ustring") == 0))
 890                                 fmt = ", __get_str(%s)";
 891                         else
 892                                 fmt = ", REC->%s";
 893                         pos += snprintf(buf + pos, LEN_OR_ZERO,
 894                                         fmt, parg->name);
 895                 }
 896         }
 897 
 898         /* return the length of print_fmt */
 899         return pos;
 900 }
 901 #undef LEN_OR_ZERO
 902 
 903 int traceprobe_set_print_fmt(struct trace_probe *tp, bool is_return)
 904 {
 905         struct trace_event_call *call = trace_probe_event_call(tp);
 906         int len;
 907         char *print_fmt;
 908 
 909         /* First: called with 0 length to calculate the needed length */
 910         len = __set_print_fmt(tp, NULL, 0, is_return);
 911         print_fmt = kmalloc(len + 1, GFP_KERNEL);
 912         if (!print_fmt)
 913                 return -ENOMEM;
 914 
 915         /* Second: actually write the @print_fmt */
 916         __set_print_fmt(tp, print_fmt, len + 1, is_return);
 917         call->print_fmt = print_fmt;
 918 
 919         return 0;
 920 }
 921 
 922 int traceprobe_define_arg_fields(struct trace_event_call *event_call,
 923                                  size_t offset, struct trace_probe *tp)
 924 {
 925         int ret, i;
 926 
 927         /* Set argument names as fields */
 928         for (i = 0; i < tp->nr_args; i++) {
 929                 struct probe_arg *parg = &tp->args[i];
 930                 const char *fmt = parg->type->fmttype;
 931                 int size = parg->type->size;
 932 
 933                 if (parg->fmt)
 934                         fmt = parg->fmt;
 935                 if (parg->count)
 936                         size *= parg->count;
 937                 ret = trace_define_field(event_call, fmt, parg->name,
 938                                          offset + parg->offset, size,
 939                                          parg->type->is_signed,
 940                                          FILTER_OTHER);
 941                 if (ret)
 942                         return ret;
 943         }
 944         return 0;
 945 }
 946 
 947 static void trace_probe_event_free(struct trace_probe_event *tpe)
 948 {
 949         kfree(tpe->class.system);
 950         kfree(tpe->call.name);
 951         kfree(tpe->call.print_fmt);
 952         kfree(tpe);
 953 }
 954 
 955 int trace_probe_append(struct trace_probe *tp, struct trace_probe *to)
 956 {
 957         if (trace_probe_has_sibling(tp))
 958                 return -EBUSY;
 959 
 960         list_del_init(&tp->list);
 961         trace_probe_event_free(tp->event);
 962 
 963         tp->event = to->event;
 964         list_add_tail(&tp->list, trace_probe_probe_list(to));
 965 
 966         return 0;
 967 }
 968 
 969 void trace_probe_unlink(struct trace_probe *tp)
 970 {
 971         list_del_init(&tp->list);
 972         if (list_empty(trace_probe_probe_list(tp)))
 973                 trace_probe_event_free(tp->event);
 974         tp->event = NULL;
 975 }
 976 
 977 void trace_probe_cleanup(struct trace_probe *tp)
 978 {
 979         int i;
 980 
 981         for (i = 0; i < tp->nr_args; i++)
 982                 traceprobe_free_probe_arg(&tp->args[i]);
 983 
 984         if (tp->event)
 985                 trace_probe_unlink(tp);
 986 }
 987 
 988 int trace_probe_init(struct trace_probe *tp, const char *event,
 989                      const char *group, bool alloc_filter)
 990 {
 991         struct trace_event_call *call;
 992         size_t size = sizeof(struct trace_probe_event);
 993         int ret = 0;
 994 
 995         if (!event || !group)
 996                 return -EINVAL;
 997 
 998         if (alloc_filter)
 999                 size += sizeof(struct trace_uprobe_filter);
1000 
1001         tp->event = kzalloc(size, GFP_KERNEL);
1002         if (!tp->event)
1003                 return -ENOMEM;
1004 
1005         INIT_LIST_HEAD(&tp->event->files);
1006         INIT_LIST_HEAD(&tp->event->class.fields);
1007         INIT_LIST_HEAD(&tp->event->probes);
1008         INIT_LIST_HEAD(&tp->list);
1009         list_add(&tp->event->probes, &tp->list);
1010 
1011         call = trace_probe_event_call(tp);
1012         call->class = &tp->event->class;
1013         call->name = kstrdup(event, GFP_KERNEL);
1014         if (!call->name) {
1015                 ret = -ENOMEM;
1016                 goto error;
1017         }
1018 
1019         tp->event->class.system = kstrdup(group, GFP_KERNEL);
1020         if (!tp->event->class.system) {
1021                 ret = -ENOMEM;
1022                 goto error;
1023         }
1024 
1025         return 0;
1026 
1027 error:
1028         trace_probe_cleanup(tp);
1029         return ret;
1030 }
1031 
1032 int trace_probe_register_event_call(struct trace_probe *tp)
1033 {
1034         struct trace_event_call *call = trace_probe_event_call(tp);
1035         int ret;
1036 
1037         ret = register_trace_event(&call->event);
1038         if (!ret)
1039                 return -ENODEV;
1040 
1041         ret = trace_add_event_call(call);
1042         if (ret)
1043                 unregister_trace_event(&call->event);
1044 
1045         return ret;
1046 }
1047 
1048 int trace_probe_add_file(struct trace_probe *tp, struct trace_event_file *file)
1049 {
1050         struct event_file_link *link;
1051 
1052         link = kmalloc(sizeof(*link), GFP_KERNEL);
1053         if (!link)
1054                 return -ENOMEM;
1055 
1056         link->file = file;
1057         INIT_LIST_HEAD(&link->list);
1058         list_add_tail_rcu(&link->list, &tp->event->files);
1059         trace_probe_set_flag(tp, TP_FLAG_TRACE);
1060         return 0;
1061 }
1062 
1063 struct event_file_link *trace_probe_get_file_link(struct trace_probe *tp,
1064                                                   struct trace_event_file *file)
1065 {
1066         struct event_file_link *link;
1067 
1068         trace_probe_for_each_link(link, tp) {
1069                 if (link->file == file)
1070                         return link;
1071         }
1072 
1073         return NULL;
1074 }
1075 
1076 int trace_probe_remove_file(struct trace_probe *tp,
1077                             struct trace_event_file *file)
1078 {
1079         struct event_file_link *link;
1080 
1081         link = trace_probe_get_file_link(tp, file);
1082         if (!link)
1083                 return -ENOENT;
1084 
1085         list_del_rcu(&link->list);
1086         synchronize_rcu();
1087         kfree(link);
1088 
1089         if (list_empty(&tp->event->files))
1090                 trace_probe_clear_flag(tp, TP_FLAG_TRACE);
1091 
1092         return 0;
1093 }
1094 
1095 /*
1096  * Return the smallest index of different type argument (start from 1).
1097  * If all argument types and name are same, return 0.
1098  */
1099 int trace_probe_compare_arg_type(struct trace_probe *a, struct trace_probe *b)
1100 {
1101         int i;
1102 
1103         /* In case of more arguments */
1104         if (a->nr_args < b->nr_args)
1105                 return a->nr_args + 1;
1106         if (a->nr_args > b->nr_args)
1107                 return b->nr_args + 1;
1108 
1109         for (i = 0; i < a->nr_args; i++) {
1110                 if ((b->nr_args <= i) ||
1111                     ((a->args[i].type != b->args[i].type) ||
1112                      (a->args[i].count != b->args[i].count) ||
1113                      strcmp(a->args[i].name, b->args[i].name)))
1114                         return i + 1;
1115         }
1116 
1117         return 0;
1118 }
1119 
1120 bool trace_probe_match_command_args(struct trace_probe *tp,
1121                                     int argc, const char **argv)
1122 {
1123         char buf[MAX_ARGSTR_LEN + 1];
1124         int i;
1125 
1126         if (tp->nr_args < argc)
1127                 return false;
1128 
1129         for (i = 0; i < argc; i++) {
1130                 snprintf(buf, sizeof(buf), "%s=%s",
1131                          tp->args[i].name, tp->args[i].comm);
1132                 if (strcmp(buf, argv[i]))
1133                         return false;
1134         }
1135         return true;
1136 }

/* [<][>][^][v][top][bottom][index][help] */