diff options
Diffstat (limited to 'tools/perf/util')
| -rw-r--r-- | tools/perf/util/perf_regs.c | 6 | ||||
| -rw-r--r-- | tools/perf/util/perf_regs.h | 11 | ||||
| -rw-r--r-- | tools/perf/util/probe-file.c | 132 |
3 files changed, 47 insertions, 102 deletions
diff --git a/tools/perf/util/perf_regs.c b/tools/perf/util/perf_regs.c index a37e5934aa2a..b2ae039eff85 100644 --- a/tools/perf/util/perf_regs.c +++ b/tools/perf/util/perf_regs.c | |||
| @@ -6,10 +6,10 @@ const struct sample_reg __weak sample_reg_masks[] = { | |||
| 6 | SMPL_REG_END | 6 | SMPL_REG_END |
| 7 | }; | 7 | }; |
| 8 | 8 | ||
| 9 | int __weak sdt_rename_register(char **pdesc __maybe_unused, | 9 | int __weak arch_sdt_arg_parse_op(char *old_op __maybe_unused, |
| 10 | char *old_name __maybe_unused) | 10 | char **new_op __maybe_unused) |
| 11 | { | 11 | { |
| 12 | return 0; | 12 | return SDT_ARG_SKIP; |
| 13 | } | 13 | } |
| 14 | 14 | ||
| 15 | #ifdef HAVE_PERF_REGS_SUPPORT | 15 | #ifdef HAVE_PERF_REGS_SUPPORT |
diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h index 7544a157e159..32b37d19dcc3 100644 --- a/tools/perf/util/perf_regs.h +++ b/tools/perf/util/perf_regs.h | |||
| @@ -15,11 +15,12 @@ struct sample_reg { | |||
| 15 | 15 | ||
| 16 | extern const struct sample_reg sample_reg_masks[]; | 16 | extern const struct sample_reg sample_reg_masks[]; |
| 17 | 17 | ||
| 18 | /* | 18 | enum { |
| 19 | * The table sdt_reg_renamings is used for adjusting gcc/gas-generated | 19 | SDT_ARG_VALID = 0, |
| 20 | * registers before filling the uprobe tracer interface. | 20 | SDT_ARG_SKIP, |
| 21 | */ | 21 | }; |
| 22 | int sdt_rename_register(char **pdesc, char *old_name); | 22 | |
| 23 | int arch_sdt_arg_parse_op(char *old_op, char **new_op); | ||
| 23 | 24 | ||
| 24 | #ifdef HAVE_PERF_REGS_SUPPORT | 25 | #ifdef HAVE_PERF_REGS_SUPPORT |
| 25 | #include <perf_regs.h> | 26 | #include <perf_regs.h> |
diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c index d741634cbfc0..88714dec8912 100644 --- a/tools/perf/util/probe-file.c +++ b/tools/perf/util/probe-file.c | |||
| @@ -694,10 +694,29 @@ static const char * const type_to_suffix[] = { | |||
| 694 | "", ":u8", ":u16", "", ":u32", "", "", "", ":u64" | 694 | "", ":u8", ":u16", "", ":u32", "", "", "", ":u64" |
| 695 | }; | 695 | }; |
| 696 | 696 | ||
| 697 | /* | ||
| 698 | * Isolate the string number and convert it into a decimal value; | ||
| 699 | * this will be an index to get suffix of the uprobe name (defining | ||
| 700 | * the type) | ||
| 701 | */ | ||
| 702 | static int sdt_arg_parse_size(char *n_ptr, const char **suffix) | ||
| 703 | { | ||
| 704 | long type_idx; | ||
| 705 | |||
| 706 | type_idx = strtol(n_ptr, NULL, 10); | ||
| 707 | if (type_idx < -8 || type_idx > 8) { | ||
| 708 | pr_debug4("Failed to get a valid sdt type\n"); | ||
| 709 | return -1; | ||
| 710 | } | ||
| 711 | |||
| 712 | *suffix = type_to_suffix[type_idx + 8]; | ||
| 713 | return 0; | ||
| 714 | } | ||
| 715 | |||
| 697 | static int synthesize_sdt_probe_arg(struct strbuf *buf, int i, const char *arg) | 716 | static int synthesize_sdt_probe_arg(struct strbuf *buf, int i, const char *arg) |
| 698 | { | 717 | { |
| 699 | char *tmp, *desc = strdup(arg); | 718 | char *op, *desc = strdup(arg), *new_op = NULL; |
| 700 | const char *prefix = "", *suffix = ""; | 719 | const char *suffix = ""; |
| 701 | int ret = -1; | 720 | int ret = -1; |
| 702 | 721 | ||
| 703 | if (desc == NULL) { | 722 | if (desc == NULL) { |
| @@ -705,112 +724,37 @@ static int synthesize_sdt_probe_arg(struct strbuf *buf, int i, const char *arg) | |||
| 705 | return ret; | 724 | return ret; |
| 706 | } | 725 | } |
| 707 | 726 | ||
| 708 | tmp = strchr(desc, '@'); | ||
| 709 | if (tmp) { | ||
| 710 | long type_idx; | ||
| 711 | /* | ||
| 712 | * Isolate the string number and convert it into a | ||
| 713 | * binary value; this will be an index to get suffix | ||
| 714 | * of the uprobe name (defining the type) | ||
| 715 | */ | ||
| 716 | tmp[0] = '\0'; | ||
| 717 | type_idx = strtol(desc, NULL, 10); | ||
| 718 | /* Check that the conversion went OK */ | ||
| 719 | if (type_idx == LONG_MIN || type_idx == LONG_MAX) { | ||
| 720 | pr_debug4("Failed to parse sdt type\n"); | ||
| 721 | goto error; | ||
| 722 | } | ||
| 723 | /* Check that the converted value is OK */ | ||
| 724 | if (type_idx < -8 || type_idx > 8) { | ||
| 725 | pr_debug4("Failed to get a valid sdt type\n"); | ||
| 726 | goto error; | ||
| 727 | } | ||
| 728 | suffix = type_to_suffix[type_idx + 8]; | ||
| 729 | /* Get rid of the sdt prefix which is now useless */ | ||
| 730 | tmp++; | ||
| 731 | memmove(desc, tmp, strlen(tmp) + 1); | ||
| 732 | } | ||
| 733 | |||
| 734 | /* | 727 | /* |
| 735 | * The uprobe tracer format does not support all the | 728 | * Argument is in N@OP format. N is size of the argument and OP is |
| 736 | * addressing modes (notably: in x86 the scaled mode); so, we | 729 | * the actual assembly operand. N can be omitted; in that case |
| 737 | * detect ',' characters, if there is just one, there is no | 730 | * argument is just OP(without @). |
| 738 | * use converting the sdt arg into a uprobe one. | ||
| 739 | */ | 731 | */ |
| 740 | if (strchr(desc, ',')) { | 732 | op = strchr(desc, '@'); |
| 741 | pr_debug4("Skipping unsupported SDT argument; %s\n", desc); | 733 | if (op) { |
| 742 | goto out; | 734 | op[0] = '\0'; |
| 743 | } | 735 | op++; |
| 744 | 736 | ||
| 745 | /* | 737 | if (sdt_arg_parse_size(desc, &suffix)) |
| 746 | * If the argument addressing mode is indirect, we must check | 738 | goto error; |
| 747 | * a few things... | 739 | } else { |
| 748 | */ | 740 | op = desc; |
| 749 | tmp = strchr(desc, '('); | ||
| 750 | if (tmp) { | ||
| 751 | int j; | ||
| 752 | |||
| 753 | /* | ||
| 754 | * ...if the addressing mode is indirect with a | ||
| 755 | * positive offset (ex.: "1608(%ax)"), we need to add | ||
| 756 | * a '+' prefix so as to be compliant with uprobe | ||
| 757 | * format. | ||
| 758 | */ | ||
| 759 | if (desc[0] != '+' && desc[0] != '-') | ||
| 760 | prefix = "+"; | ||
| 761 | |||
| 762 | /* | ||
| 763 | * ...or if the addressing mode is indirect with a symbol | ||
| 764 | * as offset, the argument will not be supported by | ||
| 765 | * the uprobe tracer format; so, let's skip this one. | ||
| 766 | */ | ||
| 767 | for (j = 0; j < tmp - desc; j++) { | ||
| 768 | if (desc[j] != '+' && desc[j] != '-' && | ||
| 769 | !isdigit(desc[j])) { | ||
| 770 | pr_debug4("Skipping unsupported SDT argument; " | ||
| 771 | "%s\n", desc); | ||
| 772 | goto out; | ||
| 773 | } | ||
| 774 | } | ||
| 775 | } | 741 | } |
| 776 | 742 | ||
| 777 | /* | 743 | ret = arch_sdt_arg_parse_op(op, &new_op); |
| 778 | * The uprobe tracer format does not support constants; if we | ||
| 779 | * find one in the current argument, let's skip the argument. | ||
| 780 | */ | ||
| 781 | if (strchr(desc, '$')) { | ||
| 782 | pr_debug4("Skipping unsupported SDT argument; %s\n", desc); | ||
| 783 | goto out; | ||
| 784 | } | ||
| 785 | 744 | ||
| 786 | /* | 745 | if (ret < 0) |
| 787 | * The uprobe parser does not support all gas register names; | 746 | goto error; |
| 788 | * so, we have to replace them (ex. for x86_64: %rax -> %ax); | ||
| 789 | * the loop below looks for the register names (starting with | ||
| 790 | * a '%' and tries to perform the needed renamings. | ||
| 791 | */ | ||
| 792 | tmp = strchr(desc, '%'); | ||
| 793 | while (tmp) { | ||
| 794 | size_t offset = tmp - desc; | ||
| 795 | 747 | ||
| 796 | ret = sdt_rename_register(&desc, desc + offset); | 748 | if (ret == SDT_ARG_VALID) { |
| 749 | ret = strbuf_addf(buf, " arg%d=%s%s", i + 1, new_op, suffix); | ||
| 797 | if (ret < 0) | 750 | if (ret < 0) |
| 798 | goto error; | 751 | goto error; |
| 799 | |||
| 800 | /* | ||
| 801 | * The desc pointer might have changed; so, let's not | ||
| 802 | * try to reuse tmp for next lookup | ||
| 803 | */ | ||
| 804 | tmp = strchr(desc + offset + 1, '%'); | ||
| 805 | } | 752 | } |
| 806 | 753 | ||
| 807 | if (strbuf_addf(buf, " arg%d=%s%s%s", i + 1, prefix, desc, suffix) < 0) | ||
| 808 | goto error; | ||
| 809 | |||
| 810 | out: | ||
| 811 | ret = 0; | 754 | ret = 0; |
| 812 | error: | 755 | error: |
| 813 | free(desc); | 756 | free(desc); |
| 757 | free(new_op); | ||
| 814 | return ret; | 758 | return ret; |
| 815 | } | 759 | } |
| 816 | 760 | ||
