]>
Commit | Line | Data |
---|---|---|
3b1f8311 AB |
1 | #include <string.h> |
2 | ||
c5e991ee | 3 | #include "../../perf.h" |
3b1f8311 | 4 | #include "../../util/util.h" |
c5e991ee SE |
5 | #include "../../util/perf_regs.h" |
6 | ||
c5e991ee | 7 | const struct sample_reg sample_reg_masks[] = { |
af4aeadd SE |
8 | SMPL_REG(AX, PERF_REG_X86_AX), |
9 | SMPL_REG(BX, PERF_REG_X86_BX), | |
10 | SMPL_REG(CX, PERF_REG_X86_CX), | |
11 | SMPL_REG(DX, PERF_REG_X86_DX), | |
12 | SMPL_REG(SI, PERF_REG_X86_SI), | |
13 | SMPL_REG(DI, PERF_REG_X86_DI), | |
14 | SMPL_REG(BP, PERF_REG_X86_BP), | |
15 | SMPL_REG(SP, PERF_REG_X86_SP), | |
16 | SMPL_REG(IP, PERF_REG_X86_IP), | |
17 | SMPL_REG(FLAGS, PERF_REG_X86_FLAGS), | |
18 | SMPL_REG(CS, PERF_REG_X86_CS), | |
19 | SMPL_REG(SS, PERF_REG_X86_SS), | |
c5e991ee | 20 | #ifdef HAVE_ARCH_X86_64_SUPPORT |
af4aeadd SE |
21 | SMPL_REG(R8, PERF_REG_X86_R8), |
22 | SMPL_REG(R9, PERF_REG_X86_R9), | |
23 | SMPL_REG(R10, PERF_REG_X86_R10), | |
24 | SMPL_REG(R11, PERF_REG_X86_R11), | |
25 | SMPL_REG(R12, PERF_REG_X86_R12), | |
26 | SMPL_REG(R13, PERF_REG_X86_R13), | |
27 | SMPL_REG(R14, PERF_REG_X86_R14), | |
28 | SMPL_REG(R15, PERF_REG_X86_R15), | |
c5e991ee | 29 | #endif |
af4aeadd | 30 | SMPL_REG_END |
c5e991ee | 31 | }; |
3b1f8311 AB |
32 | |
33 | struct sdt_name_reg { | |
34 | const char *sdt_name; | |
35 | const char *uprobe_name; | |
36 | }; | |
37 | #define SDT_NAME_REG(n, m) {.sdt_name = "%" #n, .uprobe_name = "%" #m} | |
38 | #define SDT_NAME_REG_END {.sdt_name = NULL, .uprobe_name = NULL} | |
39 | ||
40 | static const struct sdt_name_reg sdt_reg_renamings[] = { | |
41 | SDT_NAME_REG(eax, ax), | |
42 | SDT_NAME_REG(rax, ax), | |
43 | SDT_NAME_REG(ebx, bx), | |
44 | SDT_NAME_REG(rbx, bx), | |
45 | SDT_NAME_REG(ecx, cx), | |
46 | SDT_NAME_REG(rcx, cx), | |
47 | SDT_NAME_REG(edx, dx), | |
48 | SDT_NAME_REG(rdx, dx), | |
49 | SDT_NAME_REG(esi, si), | |
50 | SDT_NAME_REG(rsi, si), | |
51 | SDT_NAME_REG(edi, di), | |
52 | SDT_NAME_REG(rdi, di), | |
53 | SDT_NAME_REG(ebp, bp), | |
54 | SDT_NAME_REG(rbp, bp), | |
55 | SDT_NAME_REG_END, | |
56 | }; | |
57 | ||
58 | int sdt_rename_register(char **pdesc, char *old_name) | |
59 | { | |
60 | const struct sdt_name_reg *rnames = sdt_reg_renamings; | |
61 | char *new_desc, *old_desc = *pdesc; | |
62 | size_t prefix_len, sdt_len, uprobe_len, old_desc_len, offset; | |
63 | int ret = -1; | |
64 | ||
65 | while (ret != 0 && rnames->sdt_name != NULL) { | |
66 | sdt_len = strlen(rnames->sdt_name); | |
67 | ret = strncmp(old_name, rnames->sdt_name, sdt_len); | |
68 | rnames += !!ret; | |
69 | } | |
70 | ||
71 | if (rnames->sdt_name == NULL) | |
72 | return 0; | |
73 | ||
74 | sdt_len = strlen(rnames->sdt_name); | |
75 | uprobe_len = strlen(rnames->uprobe_name); | |
76 | old_desc_len = strlen(old_desc) + 1; | |
77 | ||
78 | new_desc = zalloc(old_desc_len + uprobe_len - sdt_len); | |
79 | if (new_desc == NULL) | |
80 | return -1; | |
81 | ||
82 | /* Copy the chars before the register name (at least '%') */ | |
83 | prefix_len = old_name - old_desc; | |
84 | memcpy(new_desc, old_desc, prefix_len); | |
85 | ||
86 | /* Copy the new register name */ | |
87 | memcpy(new_desc + prefix_len, rnames->uprobe_name, uprobe_len); | |
88 | ||
89 | /* Copy the chars after the register name (if need be) */ | |
90 | offset = prefix_len + sdt_len; | |
91 | if (offset < old_desc_len) { | |
92 | /* | |
93 | * The orginal register name can be suffixed by 'b', | |
94 | * 'w' or 'd' to indicate its size; so, we need to | |
95 | * skip this char if we met one. | |
96 | */ | |
97 | char sfx = old_desc[offset]; | |
98 | ||
99 | if (sfx == 'b' || sfx == 'w' || sfx == 'd') | |
100 | offset++; | |
101 | } | |
102 | ||
103 | if (offset < old_desc_len) | |
104 | memcpy(new_desc + prefix_len + uprobe_len, | |
105 | old_desc + offset, old_desc_len - offset); | |
106 | ||
107 | free(old_desc); | |
108 | *pdesc = new_desc; | |
109 | ||
110 | return 0; | |
111 | } |