linux/kernel/trace/trace_probe.c
<<
>>
Prefs
   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}
1131