trace_probe.c 15 KB

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