1 /* 2 * Common code for probe-based Dynamic events. 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program; if not, write to the Free Software 15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 * 17 * This code was copied from kernel/trace/trace_kprobe.c written by 18 * Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> 19 * 20 * Updates to make this generic: 21 * Copyright (C) IBM Corporation, 2010-2011 22 * Author: Srikar Dronamraju 23 */ 24 25 #include "trace_probe.h" 26 27 const char *reserved_field_names[] = { 28 "common_type", 29 "common_flags", 30 "common_preempt_count", 31 "common_pid", 32 "common_tgid", 33 FIELD_STRING_IP, 34 FIELD_STRING_RETIP, 35 FIELD_STRING_FUNC, 36 }; 37 38 /* Printing in basic type function template */ 39 #define DEFINE_BASIC_PRINT_TYPE_FUNC(type, fmt) \ 40 int PRINT_TYPE_FUNC_NAME(type)(struct trace_seq *s, const char *name, \ 41 void *data, void *ent) \ 42 { \ 43 return trace_seq_printf(s, " %s=" fmt, name, *(type *)data); \ 44 } \ 45 const char PRINT_TYPE_FMT_NAME(type)[] = fmt; \ 46 NOKPROBE_SYMBOL(PRINT_TYPE_FUNC_NAME(type)); 47 48 DEFINE_BASIC_PRINT_TYPE_FUNC(u8 , "0x%x") 49 DEFINE_BASIC_PRINT_TYPE_FUNC(u16, "0x%x") 50 DEFINE_BASIC_PRINT_TYPE_FUNC(u32, "0x%x") 51 DEFINE_BASIC_PRINT_TYPE_FUNC(u64, "0x%Lx") 52 DEFINE_BASIC_PRINT_TYPE_FUNC(s8, "%d") 53 DEFINE_BASIC_PRINT_TYPE_FUNC(s16, "%d") 54 DEFINE_BASIC_PRINT_TYPE_FUNC(s32, "%d") 55 DEFINE_BASIC_PRINT_TYPE_FUNC(s64, "%Ld") 56 57 /* Print type function for string type */ 58 int PRINT_TYPE_FUNC_NAME(string)(struct trace_seq *s, const char *name, 59 void *data, void *ent) 60 { 61 int len = *(u32 *)data >> 16; 62 63 if (!len) 64 return trace_seq_printf(s, " %s=(fault)", name); 65 else 66 return trace_seq_printf(s, " %s=\"%s\"", name, 67 (const char *)get_loc_data(data, ent)); 68 } 69 NOKPROBE_SYMBOL(PRINT_TYPE_FUNC_NAME(string)); 70 71 const char PRINT_TYPE_FMT_NAME(string)[] = "\\\"%s\\\""; 72 73 #define CHECK_FETCH_FUNCS(method, fn) \ 74 (((FETCH_FUNC_NAME(method, u8) == fn) || \ 75 (FETCH_FUNC_NAME(method, u16) == fn) || \ 76 (FETCH_FUNC_NAME(method, u32) == fn) || \ 77 (FETCH_FUNC_NAME(method, u64) == fn) || \ 78 (FETCH_FUNC_NAME(method, string) == fn) || \ 79 (FETCH_FUNC_NAME(method, string_size) == fn)) \ 80 && (fn != NULL)) 81 82 /* Data fetch function templates */ 83 #define DEFINE_FETCH_reg(type) \ 84 void FETCH_FUNC_NAME(reg, type)(struct pt_regs *regs, void *offset, void *dest) \ 85 { \ 86 *(type *)dest = (type)regs_get_register(regs, \ 87 (unsigned int)((unsigned long)offset)); \ 88 } \ 89 NOKPROBE_SYMBOL(FETCH_FUNC_NAME(reg, type)); 90 DEFINE_BASIC_FETCH_FUNCS(reg) 91 /* No string on the register */ 92 #define fetch_reg_string NULL 93 #define fetch_reg_string_size NULL 94 95 #define DEFINE_FETCH_retval(type) \ 96 void FETCH_FUNC_NAME(retval, type)(struct pt_regs *regs, \ 97 void *dummy, void *dest) \ 98 { \ 99 *(type *)dest = (type)regs_return_value(regs); \ 100 } \ 101 NOKPROBE_SYMBOL(FETCH_FUNC_NAME(retval, type)); 102 DEFINE_BASIC_FETCH_FUNCS(retval) 103 /* No string on the retval */ 104 #define fetch_retval_string NULL 105 #define fetch_retval_string_size NULL 106 107 /* Dereference memory access function */ 108 struct deref_fetch_param { 109 struct fetch_param orig; 110 long offset; 111 fetch_func_t fetch; 112 fetch_func_t fetch_size; 113 }; 114 115 #define DEFINE_FETCH_deref(type) \ 116 void FETCH_FUNC_NAME(deref, type)(struct pt_regs *regs, \ 117 void *data, void *dest) \ 118 { \ 119 struct deref_fetch_param *dprm = data; \ 120 unsigned long addr; \ 121 call_fetch(&dprm->orig, regs, &addr); \ 122 if (addr) { \ 123 addr += dprm->offset; \ 124 dprm->fetch(regs, (void *)addr, dest); \ 125 } else \ 126 *(type *)dest = 0; \ 127 } \ 128 NOKPROBE_SYMBOL(FETCH_FUNC_NAME(deref, type)); 129 DEFINE_BASIC_FETCH_FUNCS(deref) 130 DEFINE_FETCH_deref(string) 131 132 void FETCH_FUNC_NAME(deref, string_size)(struct pt_regs *regs, 133 void *data, void *dest) 134 { 135 struct deref_fetch_param *dprm = data; 136 unsigned long addr; 137 138 call_fetch(&dprm->orig, regs, &addr); 139 if (addr && dprm->fetch_size) { 140 addr += dprm->offset; 141 dprm->fetch_size(regs, (void *)addr, dest); 142 } else 143 *(string_size *)dest = 0; 144 } 145 NOKPROBE_SYMBOL(FETCH_FUNC_NAME(deref, string_size)); 146 147 static void update_deref_fetch_param(struct deref_fetch_param *data) 148 { 149 if (CHECK_FETCH_FUNCS(deref, data->orig.fn)) 150 update_deref_fetch_param(data->orig.data); 151 else if (CHECK_FETCH_FUNCS(symbol, data->orig.fn)) 152 update_symbol_cache(data->orig.data); 153 } 154 NOKPROBE_SYMBOL(update_deref_fetch_param); 155 156 static void free_deref_fetch_param(struct deref_fetch_param *data) 157 { 158 if (CHECK_FETCH_FUNCS(deref, data->orig.fn)) 159 free_deref_fetch_param(data->orig.data); 160 else if (CHECK_FETCH_FUNCS(symbol, data->orig.fn)) 161 free_symbol_cache(data->orig.data); 162 kfree(data); 163 } 164 NOKPROBE_SYMBOL(free_deref_fetch_param); 165 166 /* Bitfield fetch function */ 167 struct bitfield_fetch_param { 168 struct fetch_param orig; 169 unsigned char hi_shift; 170 unsigned char low_shift; 171 }; 172 173 #define DEFINE_FETCH_bitfield(type) \ 174 void FETCH_FUNC_NAME(bitfield, type)(struct pt_regs *regs, \ 175 void *data, void *dest) \ 176 { \ 177 struct bitfield_fetch_param *bprm = data; \ 178 type buf = 0; \ 179 call_fetch(&bprm->orig, regs, &buf); \ 180 if (buf) { \ 181 buf <<= bprm->hi_shift; \ 182 buf >>= bprm->low_shift; \ 183 } \ 184 *(type *)dest = buf; \ 185 } \ 186 NOKPROBE_SYMBOL(FETCH_FUNC_NAME(bitfield, type)); 187 DEFINE_BASIC_FETCH_FUNCS(bitfield) 188 #define fetch_bitfield_string NULL 189 #define fetch_bitfield_string_size NULL 190 191 static void 192 update_bitfield_fetch_param(struct bitfield_fetch_param *data) 193 { 194 /* 195 * Don't check the bitfield itself, because this must be the 196 * last fetch function. 197 */ 198 if (CHECK_FETCH_FUNCS(deref, data->orig.fn)) 199 update_deref_fetch_param(data->orig.data); 200 else if (CHECK_FETCH_FUNCS(symbol, data->orig.fn)) 201 update_symbol_cache(data->orig.data); 202 } 203 204 static void 205 free_bitfield_fetch_param(struct bitfield_fetch_param *data) 206 { 207 /* 208 * Don't check the bitfield itself, because this must be the 209 * last fetch function. 210 */ 211 if (CHECK_FETCH_FUNCS(deref, data->orig.fn)) 212 free_deref_fetch_param(data->orig.data); 213 else if (CHECK_FETCH_FUNCS(symbol, data->orig.fn)) 214 free_symbol_cache(data->orig.data); 215 216 kfree(data); 217 } 218 219 static const struct fetch_type *find_fetch_type(const char *type, 220 const struct fetch_type *ftbl) 221 { 222 int i; 223 224 if (!type) 225 type = DEFAULT_FETCH_TYPE_STR; 226 227 /* Special case: bitfield */ 228 if (*type == 'b') { 229 unsigned long bs; 230 231 type = strchr(type, '/'); 232 if (!type) 233 goto fail; 234 235 type++; 236 if (kstrtoul(type, 0, &bs)) 237 goto fail; 238 239 switch (bs) { 240 case 8: 241 return find_fetch_type("u8", ftbl); 242 case 16: 243 return find_fetch_type("u16", ftbl); 244 case 32: 245 return find_fetch_type("u32", ftbl); 246 case 64: 247 return find_fetch_type("u64", ftbl); 248 default: 249 goto fail; 250 } 251 } 252 253 for (i = 0; ftbl[i].name; i++) { 254 if (strcmp(type, ftbl[i].name) == 0) 255 return &ftbl[i]; 256 } 257 258 fail: 259 return NULL; 260 } 261 262 /* Special function : only accept unsigned long */ 263 static void fetch_kernel_stack_address(struct pt_regs *regs, void *dummy, void *dest) 264 { 265 *(unsigned long *)dest = kernel_stack_pointer(regs); 266 } 267 NOKPROBE_SYMBOL(fetch_kernel_stack_address); 268 269 static void fetch_user_stack_address(struct pt_regs *regs, void *dummy, void *dest) 270 { 271 *(unsigned long *)dest = user_stack_pointer(regs); 272 } 273 NOKPROBE_SYMBOL(fetch_user_stack_address); 274 275 static fetch_func_t get_fetch_size_function(const struct fetch_type *type, 276 fetch_func_t orig_fn, 277 const struct fetch_type *ftbl) 278 { 279 int i; 280 281 if (type != &ftbl[FETCH_TYPE_STRING]) 282 return NULL; /* Only string type needs size function */ 283 284 for (i = 0; i < FETCH_MTD_END; i++) 285 if (type->fetch[i] == orig_fn) 286 return ftbl[FETCH_TYPE_STRSIZE].fetch[i]; 287 288 WARN_ON(1); /* This should not happen */ 289 290 return NULL; 291 } 292 293 /* Split symbol and offset. */ 294 int traceprobe_split_symbol_offset(char *symbol, unsigned long *offset) 295 { 296 char *tmp; 297 int ret; 298 299 if (!offset) 300 return -EINVAL; 301 302 tmp = strchr(symbol, '+'); 303 if (tmp) { 304 /* skip sign because kstrtoul doesn't accept '+' */ 305 ret = kstrtoul(tmp + 1, 0, offset); 306 if (ret) 307 return ret; 308 309 *tmp = '\0'; 310 } else 311 *offset = 0; 312 313 return 0; 314 } 315 316 #define PARAM_MAX_STACK (THREAD_SIZE / sizeof(unsigned long)) 317 318 static int parse_probe_vars(char *arg, const struct fetch_type *t, 319 struct fetch_param *f, bool is_return, 320 bool is_kprobe) 321 { 322 int ret = 0; 323 unsigned long param; 324 325 if (strcmp(arg, "retval") == 0) { 326 if (is_return) 327 f->fn = t->fetch[FETCH_MTD_retval]; 328 else 329 ret = -EINVAL; 330 } else if (strncmp(arg, "stack", 5) == 0) { 331 if (arg[5] == '\0') { 332 if (strcmp(t->name, DEFAULT_FETCH_TYPE_STR)) 333 return -EINVAL; 334 335 if (is_kprobe) 336 f->fn = fetch_kernel_stack_address; 337 else 338 f->fn = fetch_user_stack_address; 339 } else if (isdigit(arg[5])) { 340 ret = kstrtoul(arg + 5, 10, ¶m); 341 if (ret || (is_kprobe && param > PARAM_MAX_STACK)) 342 ret = -EINVAL; 343 else { 344 f->fn = t->fetch[FETCH_MTD_stack]; 345 f->data = (void *)param; 346 } 347 } else 348 ret = -EINVAL; 349 } else 350 ret = -EINVAL; 351 352 return ret; 353 } 354 355 /* Recursive argument parser */ 356 static int parse_probe_arg(char *arg, const struct fetch_type *t, 357 struct fetch_param *f, bool is_return, bool is_kprobe) 358 { 359 const struct fetch_type *ftbl; 360 unsigned long param; 361 long offset; 362 char *tmp; 363 int ret = 0; 364 365 ftbl = is_kprobe ? kprobes_fetch_type_table : uprobes_fetch_type_table; 366 BUG_ON(ftbl == NULL); 367 368 switch (arg[0]) { 369 case '$': 370 ret = parse_probe_vars(arg + 1, t, f, is_return, is_kprobe); 371 break; 372 373 case '%': /* named register */ 374 ret = regs_query_register_offset(arg + 1); 375 if (ret >= 0) { 376 f->fn = t->fetch[FETCH_MTD_reg]; 377 f->data = (void *)(unsigned long)ret; 378 ret = 0; 379 } 380 break; 381 382 case '@': /* memory, file-offset or symbol */ 383 if (isdigit(arg[1])) { 384 ret = kstrtoul(arg + 1, 0, ¶m); 385 if (ret) 386 break; 387 388 f->fn = t->fetch[FETCH_MTD_memory]; 389 f->data = (void *)param; 390 } else if (arg[1] == '+') { 391 /* kprobes don't support file offsets */ 392 if (is_kprobe) 393 return -EINVAL; 394 395 ret = kstrtol(arg + 2, 0, &offset); 396 if (ret) 397 break; 398 399 f->fn = t->fetch[FETCH_MTD_file_offset]; 400 f->data = (void *)offset; 401 } else { 402 /* uprobes don't support symbols */ 403 if (!is_kprobe) 404 return -EINVAL; 405 406 ret = traceprobe_split_symbol_offset(arg + 1, &offset); 407 if (ret) 408 break; 409 410 f->data = alloc_symbol_cache(arg + 1, offset); 411 if (f->data) 412 f->fn = t->fetch[FETCH_MTD_symbol]; 413 } 414 break; 415 416 case '+': /* deref memory */ 417 arg++; /* Skip '+', because kstrtol() rejects it. */ 418 case '-': 419 tmp = strchr(arg, '('); 420 if (!tmp) 421 break; 422 423 *tmp = '\0'; 424 ret = kstrtol(arg, 0, &offset); 425 426 if (ret) 427 break; 428 429 arg = tmp + 1; 430 tmp = strrchr(arg, ')'); 431 432 if (tmp) { 433 struct deref_fetch_param *dprm; 434 const struct fetch_type *t2; 435 436 t2 = find_fetch_type(NULL, ftbl); 437 *tmp = '\0'; 438 dprm = kzalloc(sizeof(struct deref_fetch_param), GFP_KERNEL); 439 440 if (!dprm) 441 return -ENOMEM; 442 443 dprm->offset = offset; 444 dprm->fetch = t->fetch[FETCH_MTD_memory]; 445 dprm->fetch_size = get_fetch_size_function(t, 446 dprm->fetch, ftbl); 447 ret = parse_probe_arg(arg, t2, &dprm->orig, is_return, 448 is_kprobe); 449 if (ret) 450 kfree(dprm); 451 else { 452 f->fn = t->fetch[FETCH_MTD_deref]; 453 f->data = (void *)dprm; 454 } 455 } 456 break; 457 } 458 if (!ret && !f->fn) { /* Parsed, but do not find fetch method */ 459 pr_info("%s type has no corresponding fetch method.\n", t->name); 460 ret = -EINVAL; 461 } 462 463 return ret; 464 } 465 466 #define BYTES_TO_BITS(nb) ((BITS_PER_LONG * (nb)) / sizeof(long)) 467 468 /* Bitfield type needs to be parsed into a fetch function */ 469 static int __parse_bitfield_probe_arg(const char *bf, 470 const struct fetch_type *t, 471 struct fetch_param *f) 472 { 473 struct bitfield_fetch_param *bprm; 474 unsigned long bw, bo; 475 char *tail; 476 477 if (*bf != 'b') 478 return 0; 479 480 bprm = kzalloc(sizeof(*bprm), GFP_KERNEL); 481 if (!bprm) 482 return -ENOMEM; 483 484 bprm->orig = *f; 485 f->fn = t->fetch[FETCH_MTD_bitfield]; 486 f->data = (void *)bprm; 487 bw = simple_strtoul(bf + 1, &tail, 0); /* Use simple one */ 488 489 if (bw == 0 || *tail != '@') 490 return -EINVAL; 491 492 bf = tail + 1; 493 bo = simple_strtoul(bf, &tail, 0); 494 495 if (tail == bf || *tail != '/') 496 return -EINVAL; 497 498 bprm->hi_shift = BYTES_TO_BITS(t->size) - (bw + bo); 499 bprm->low_shift = bprm->hi_shift + bo; 500 501 return (BYTES_TO_BITS(t->size) < (bw + bo)) ? -EINVAL : 0; 502 } 503 504 /* String length checking wrapper */ 505 int traceprobe_parse_probe_arg(char *arg, ssize_t *size, 506 struct probe_arg *parg, bool is_return, bool is_kprobe) 507 { 508 const struct fetch_type *ftbl; 509 const char *t; 510 int ret; 511 512 ftbl = is_kprobe ? kprobes_fetch_type_table : uprobes_fetch_type_table; 513 BUG_ON(ftbl == NULL); 514 515 if (strlen(arg) > MAX_ARGSTR_LEN) { 516 pr_info("Argument is too long.: %s\n", arg); 517 return -ENOSPC; 518 } 519 parg->comm = kstrdup(arg, GFP_KERNEL); 520 if (!parg->comm) { 521 pr_info("Failed to allocate memory for command '%s'.\n", arg); 522 return -ENOMEM; 523 } 524 t = strchr(parg->comm, ':'); 525 if (t) { 526 arg[t - parg->comm] = '\0'; 527 t++; 528 } 529 parg->type = find_fetch_type(t, ftbl); 530 if (!parg->type) { 531 pr_info("Unsupported type: %s\n", t); 532 return -EINVAL; 533 } 534 parg->offset = *size; 535 *size += parg->type->size; 536 ret = parse_probe_arg(arg, parg->type, &parg->fetch, is_return, is_kprobe); 537 538 if (ret >= 0 && t != NULL) 539 ret = __parse_bitfield_probe_arg(t, parg->type, &parg->fetch); 540 541 if (ret >= 0) { 542 parg->fetch_size.fn = get_fetch_size_function(parg->type, 543 parg->fetch.fn, 544 ftbl); 545 parg->fetch_size.data = parg->fetch.data; 546 } 547 548 return ret; 549 } 550 551 /* Return 1 if name is reserved or already used by another argument */ 552 int traceprobe_conflict_field_name(const char *name, 553 struct probe_arg *args, int narg) 554 { 555 int i; 556 557 for (i = 0; i < ARRAY_SIZE(reserved_field_names); i++) 558 if (strcmp(reserved_field_names[i], name) == 0) 559 return 1; 560 561 for (i = 0; i < narg; i++) 562 if (strcmp(args[i].name, name) == 0) 563 return 1; 564 565 return 0; 566 } 567 568 void traceprobe_update_arg(struct probe_arg *arg) 569 { 570 if (CHECK_FETCH_FUNCS(bitfield, arg->fetch.fn)) 571 update_bitfield_fetch_param(arg->fetch.data); 572 else if (CHECK_FETCH_FUNCS(deref, arg->fetch.fn)) 573 update_deref_fetch_param(arg->fetch.data); 574 else if (CHECK_FETCH_FUNCS(symbol, arg->fetch.fn)) 575 update_symbol_cache(arg->fetch.data); 576 } 577 578 void traceprobe_free_probe_arg(struct probe_arg *arg) 579 { 580 if (CHECK_FETCH_FUNCS(bitfield, arg->fetch.fn)) 581 free_bitfield_fetch_param(arg->fetch.data); 582 else if (CHECK_FETCH_FUNCS(deref, arg->fetch.fn)) 583 free_deref_fetch_param(arg->fetch.data); 584 else if (CHECK_FETCH_FUNCS(symbol, arg->fetch.fn)) 585 free_symbol_cache(arg->fetch.data); 586 587 kfree(arg->name); 588 kfree(arg->comm); 589 } 590 591 int traceprobe_command(const char *buf, int (*createfn)(int, char **)) 592 { 593 char **argv; 594 int argc, ret; 595 596 argc = 0; 597 ret = 0; 598 argv = argv_split(GFP_KERNEL, buf, &argc); 599 if (!argv) 600 return -ENOMEM; 601 602 if (argc) 603 ret = createfn(argc, argv); 604 605 argv_free(argv); 606 607 return ret; 608 } 609 610 #define WRITE_BUFSIZE 4096 611 612 ssize_t traceprobe_probes_write(struct file *file, const char __user *buffer, 613 size_t count, loff_t *ppos, 614 int (*createfn)(int, char **)) 615 { 616 char *kbuf, *tmp; 617 int ret = 0; 618 size_t done = 0; 619 size_t size; 620 621 kbuf = kmalloc(WRITE_BUFSIZE, GFP_KERNEL); 622 if (!kbuf) 623 return -ENOMEM; 624 625 while (done < count) { 626 size = count - done; 627 628 if (size >= WRITE_BUFSIZE) 629 size = WRITE_BUFSIZE - 1; 630 631 if (copy_from_user(kbuf, buffer + done, size)) { 632 ret = -EFAULT; 633 goto out; 634 } 635 kbuf[size] = '\0'; 636 tmp = strchr(kbuf, '\n'); 637 638 if (tmp) { 639 *tmp = '\0'; 640 size = tmp - kbuf + 1; 641 } else if (done + size < count) { 642 pr_warning("Line length is too long: " 643 "Should be less than %d.", WRITE_BUFSIZE); 644 ret = -EINVAL; 645 goto out; 646 } 647 done += size; 648 /* Remove comments */ 649 tmp = strchr(kbuf, '#'); 650 651 if (tmp) 652 *tmp = '\0'; 653 654 ret = traceprobe_command(kbuf, createfn); 655 if (ret) 656 goto out; 657 } 658 ret = done; 659 660 out: 661 kfree(kbuf); 662 663 return ret; 664 } 665 666 static int __set_print_fmt(struct trace_probe *tp, char *buf, int len, 667 bool is_return) 668 { 669 int i; 670 int pos = 0; 671 672 const char *fmt, *arg; 673 674 if (!is_return) { 675 fmt = "(%lx)"; 676 arg = "REC->" FIELD_STRING_IP; 677 } else { 678 fmt = "(%lx <- %lx)"; 679 arg = "REC->" FIELD_STRING_FUNC ", REC->" FIELD_STRING_RETIP; 680 } 681 682 /* When len=0, we just calculate the needed length */ 683 #define LEN_OR_ZERO (len ? len - pos : 0) 684 685 pos += snprintf(buf + pos, LEN_OR_ZERO, "\"%s", fmt); 686 687 for (i = 0; i < tp->nr_args; i++) { 688 pos += snprintf(buf + pos, LEN_OR_ZERO, " %s=%s", 689 tp->args[i].name, tp->args[i].type->fmt); 690 } 691 692 pos += snprintf(buf + pos, LEN_OR_ZERO, "\", %s", arg); 693 694 for (i = 0; i < tp->nr_args; i++) { 695 if (strcmp(tp->args[i].type->name, "string") == 0) 696 pos += snprintf(buf + pos, LEN_OR_ZERO, 697 ", __get_str(%s)", 698 tp->args[i].name); 699 else 700 pos += snprintf(buf + pos, LEN_OR_ZERO, ", REC->%s", 701 tp->args[i].name); 702 } 703 704 #undef LEN_OR_ZERO 705 706 /* return the length of print_fmt */ 707 return pos; 708 } 709 710 int set_print_fmt(struct trace_probe *tp, bool is_return) 711 { 712 int len; 713 char *print_fmt; 714 715 /* First: called with 0 length to calculate the needed length */ 716 len = __set_print_fmt(tp, NULL, 0, is_return); 717 print_fmt = kmalloc(len + 1, GFP_KERNEL); 718 if (!print_fmt) 719 return -ENOMEM; 720 721 /* Second: actually write the @print_fmt */ 722 __set_print_fmt(tp, print_fmt, len + 1, is_return); 723 tp->call.print_fmt = print_fmt; 724 725 return 0; 726 } 727