Commit e742f3dc0886a92403d578e8ac771e5e33d06d08

Authored by Ingo Molnar

Merge tag 'perf-urgent-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/g…

…it/acme/linux into perf/urgent

Pull perf/urgent fixes from Arnaldo Carvalho de Melo:

" User visible fixes:

  - Fix probing at function return (Namhyumg Kim)

  Developer visible fixes:

  - Symbol processing changes necessary for fixing support for
    kretprobes in 'perf probe' (Namhyung Kim, Arnaldo Carvalho de Melo)

  - Annotation memory leaks and instruction parsing fixes (Rabin Vincent)

  - Fix perl build on ARM64 (Wang Nam)
"

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>

Showing 7 changed files Inline Diff

tools/perf/scripts/perl/Perf-Trace-Util/Context.c
1 /* 1 /*
2 * This file was generated automatically by ExtUtils::ParseXS version 2.18_02 from the 2 * This file was generated automatically by ExtUtils::ParseXS version 2.18_02 from the
3 * contents of Context.xs. Do not edit this file, edit Context.xs instead. 3 * contents of Context.xs. Do not edit this file, edit Context.xs instead.
4 * 4 *
5 * ANY CHANGES MADE HERE WILL BE LOST! 5 * ANY CHANGES MADE HERE WILL BE LOST!
6 * 6 *
7 */ 7 */
8 8 #include <stdbool.h>
9 #ifndef HAS_BOOL
10 # define HAS_BOOL 1
11 #endif
9 #line 1 "Context.xs" 12 #line 1 "Context.xs"
10 /* 13 /*
11 * Context.xs. XS interfaces for perf script. 14 * Context.xs. XS interfaces for perf script.
12 * 15 *
13 * Copyright (C) 2009 Tom Zanussi <tzanussi@gmail.com> 16 * Copyright (C) 2009 Tom Zanussi <tzanussi@gmail.com>
14 * 17 *
15 * This program is free software; you can redistribute it and/or modify 18 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by 19 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or 20 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version. 21 * (at your option) any later version.
19 * 22 *
20 * This program is distributed in the hope that it will be useful, 23 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of 24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details. 26 * GNU General Public License for more details.
24 * 27 *
25 * You should have received a copy of the GNU General Public License 28 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software 29 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 30 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 * 31 *
29 */ 32 */
30 33
31 #include "EXTERN.h" 34 #include "EXTERN.h"
32 #include "perl.h" 35 #include "perl.h"
33 #include "XSUB.h" 36 #include "XSUB.h"
34 #include "../../../perf.h" 37 #include "../../../perf.h"
35 #include "../../../util/trace-event.h" 38 #include "../../../util/trace-event.h"
36 39
37 #ifndef PERL_UNUSED_VAR 40 #ifndef PERL_UNUSED_VAR
38 # define PERL_UNUSED_VAR(var) if (0) var = var 41 # define PERL_UNUSED_VAR(var) if (0) var = var
39 #endif 42 #endif
40 43
41 #line 42 "Context.c" 44 #line 42 "Context.c"
42 45
43 XS(XS_Perf__Trace__Context_common_pc); /* prototype to pass -Wmissing-prototypes */ 46 XS(XS_Perf__Trace__Context_common_pc); /* prototype to pass -Wmissing-prototypes */
44 XS(XS_Perf__Trace__Context_common_pc) 47 XS(XS_Perf__Trace__Context_common_pc)
45 { 48 {
46 #ifdef dVAR 49 #ifdef dVAR
47 dVAR; dXSARGS; 50 dVAR; dXSARGS;
48 #else 51 #else
49 dXSARGS; 52 dXSARGS;
50 #endif 53 #endif
51 if (items != 1) 54 if (items != 1)
52 Perl_croak(aTHX_ "Usage: %s(%s)", "Perf::Trace::Context::common_pc", "context"); 55 Perl_croak(aTHX_ "Usage: %s(%s)", "Perf::Trace::Context::common_pc", "context");
53 PERL_UNUSED_VAR(cv); /* -W */ 56 PERL_UNUSED_VAR(cv); /* -W */
54 { 57 {
55 struct scripting_context * context = INT2PTR(struct scripting_context *,SvIV(ST(0))); 58 struct scripting_context * context = INT2PTR(struct scripting_context *,SvIV(ST(0)));
56 int RETVAL; 59 int RETVAL;
57 dXSTARG; 60 dXSTARG;
58 61
59 RETVAL = common_pc(context); 62 RETVAL = common_pc(context);
60 XSprePUSH; PUSHi((IV)RETVAL); 63 XSprePUSH; PUSHi((IV)RETVAL);
61 } 64 }
62 XSRETURN(1); 65 XSRETURN(1);
63 } 66 }
64 67
65 68
66 XS(XS_Perf__Trace__Context_common_flags); /* prototype to pass -Wmissing-prototypes */ 69 XS(XS_Perf__Trace__Context_common_flags); /* prototype to pass -Wmissing-prototypes */
67 XS(XS_Perf__Trace__Context_common_flags) 70 XS(XS_Perf__Trace__Context_common_flags)
68 { 71 {
69 #ifdef dVAR 72 #ifdef dVAR
70 dVAR; dXSARGS; 73 dVAR; dXSARGS;
71 #else 74 #else
72 dXSARGS; 75 dXSARGS;
73 #endif 76 #endif
74 if (items != 1) 77 if (items != 1)
75 Perl_croak(aTHX_ "Usage: %s(%s)", "Perf::Trace::Context::common_flags", "context"); 78 Perl_croak(aTHX_ "Usage: %s(%s)", "Perf::Trace::Context::common_flags", "context");
76 PERL_UNUSED_VAR(cv); /* -W */ 79 PERL_UNUSED_VAR(cv); /* -W */
77 { 80 {
78 struct scripting_context * context = INT2PTR(struct scripting_context *,SvIV(ST(0))); 81 struct scripting_context * context = INT2PTR(struct scripting_context *,SvIV(ST(0)));
79 int RETVAL; 82 int RETVAL;
80 dXSTARG; 83 dXSTARG;
81 84
82 RETVAL = common_flags(context); 85 RETVAL = common_flags(context);
83 XSprePUSH; PUSHi((IV)RETVAL); 86 XSprePUSH; PUSHi((IV)RETVAL);
84 } 87 }
85 XSRETURN(1); 88 XSRETURN(1);
86 } 89 }
87 90
88 91
89 XS(XS_Perf__Trace__Context_common_lock_depth); /* prototype to pass -Wmissing-prototypes */ 92 XS(XS_Perf__Trace__Context_common_lock_depth); /* prototype to pass -Wmissing-prototypes */
90 XS(XS_Perf__Trace__Context_common_lock_depth) 93 XS(XS_Perf__Trace__Context_common_lock_depth)
91 { 94 {
92 #ifdef dVAR 95 #ifdef dVAR
93 dVAR; dXSARGS; 96 dVAR; dXSARGS;
94 #else 97 #else
95 dXSARGS; 98 dXSARGS;
96 #endif 99 #endif
97 if (items != 1) 100 if (items != 1)
98 Perl_croak(aTHX_ "Usage: %s(%s)", "Perf::Trace::Context::common_lock_depth", "context"); 101 Perl_croak(aTHX_ "Usage: %s(%s)", "Perf::Trace::Context::common_lock_depth", "context");
99 PERL_UNUSED_VAR(cv); /* -W */ 102 PERL_UNUSED_VAR(cv); /* -W */
100 { 103 {
101 struct scripting_context * context = INT2PTR(struct scripting_context *,SvIV(ST(0))); 104 struct scripting_context * context = INT2PTR(struct scripting_context *,SvIV(ST(0)));
102 int RETVAL; 105 int RETVAL;
103 dXSTARG; 106 dXSTARG;
104 107
105 RETVAL = common_lock_depth(context); 108 RETVAL = common_lock_depth(context);
106 XSprePUSH; PUSHi((IV)RETVAL); 109 XSprePUSH; PUSHi((IV)RETVAL);
107 } 110 }
108 XSRETURN(1); 111 XSRETURN(1);
109 } 112 }
110 113
111 #ifdef __cplusplus 114 #ifdef __cplusplus
112 extern "C" 115 extern "C"
113 #endif 116 #endif
114 XS(boot_Perf__Trace__Context); /* prototype to pass -Wmissing-prototypes */ 117 XS(boot_Perf__Trace__Context); /* prototype to pass -Wmissing-prototypes */
115 XS(boot_Perf__Trace__Context) 118 XS(boot_Perf__Trace__Context)
116 { 119 {
117 #ifdef dVAR 120 #ifdef dVAR
118 dVAR; dXSARGS; 121 dVAR; dXSARGS;
119 #else 122 #else
120 dXSARGS; 123 dXSARGS;
121 #endif 124 #endif
122 const char* file = __FILE__; 125 const char* file = __FILE__;
123 126
124 PERL_UNUSED_VAR(cv); /* -W */ 127 PERL_UNUSED_VAR(cv); /* -W */
125 PERL_UNUSED_VAR(items); /* -W */ 128 PERL_UNUSED_VAR(items); /* -W */
126 XS_VERSION_BOOTCHECK ; 129 XS_VERSION_BOOTCHECK ;
127 130
128 newXSproto("Perf::Trace::Context::common_pc", XS_Perf__Trace__Context_common_pc, file, "$"); 131 newXSproto("Perf::Trace::Context::common_pc", XS_Perf__Trace__Context_common_pc, file, "$");
129 newXSproto("Perf::Trace::Context::common_flags", XS_Perf__Trace__Context_common_flags, file, "$"); 132 newXSproto("Perf::Trace::Context::common_flags", XS_Perf__Trace__Context_common_flags, file, "$");
130 newXSproto("Perf::Trace::Context::common_lock_depth", XS_Perf__Trace__Context_common_lock_depth, file, "$"); 133 newXSproto("Perf::Trace::Context::common_lock_depth", XS_Perf__Trace__Context_common_lock_depth, file, "$");
131 if (PL_unitcheckav) 134 if (PL_unitcheckav)
132 call_list(PL_scopestack_ix, PL_unitcheckav); 135 call_list(PL_scopestack_ix, PL_unitcheckav);
133 XSRETURN_YES; 136 XSRETURN_YES;
134 } 137 }
135 138
136 139
tools/perf/util/annotate.c
1 /* 1 /*
2 * Copyright (C) 2011, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com> 2 * Copyright (C) 2011, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
3 * 3 *
4 * Parts came from builtin-annotate.c, see those files for further 4 * Parts came from builtin-annotate.c, see those files for further
5 * copyright notes. 5 * copyright notes.
6 * 6 *
7 * Released under the GPL v2. (and only v2, not any later version) 7 * Released under the GPL v2. (and only v2, not any later version)
8 */ 8 */
9 9
10 #include "util.h" 10 #include "util.h"
11 #include "ui/ui.h" 11 #include "ui/ui.h"
12 #include "sort.h" 12 #include "sort.h"
13 #include "build-id.h" 13 #include "build-id.h"
14 #include "color.h" 14 #include "color.h"
15 #include "cache.h" 15 #include "cache.h"
16 #include "symbol.h" 16 #include "symbol.h"
17 #include "debug.h" 17 #include "debug.h"
18 #include "annotate.h" 18 #include "annotate.h"
19 #include "evsel.h" 19 #include "evsel.h"
20 #include <regex.h> 20 #include <regex.h>
21 #include <pthread.h> 21 #include <pthread.h>
22 #include <linux/bitops.h> 22 #include <linux/bitops.h>
23 23
24 const char *disassembler_style; 24 const char *disassembler_style;
25 const char *objdump_path; 25 const char *objdump_path;
26 static regex_t file_lineno; 26 static regex_t file_lineno;
27 27
28 static struct ins *ins__find(const char *name); 28 static struct ins *ins__find(const char *name);
29 static int disasm_line__parse(char *line, char **namep, char **rawp); 29 static int disasm_line__parse(char *line, char **namep, char **rawp);
30 30
31 static void ins__delete(struct ins_operands *ops) 31 static void ins__delete(struct ins_operands *ops)
32 { 32 {
33 zfree(&ops->source.raw); 33 zfree(&ops->source.raw);
34 zfree(&ops->source.name); 34 zfree(&ops->source.name);
35 zfree(&ops->target.raw); 35 zfree(&ops->target.raw);
36 zfree(&ops->target.name); 36 zfree(&ops->target.name);
37 } 37 }
38 38
39 static int ins__raw_scnprintf(struct ins *ins, char *bf, size_t size, 39 static int ins__raw_scnprintf(struct ins *ins, char *bf, size_t size,
40 struct ins_operands *ops) 40 struct ins_operands *ops)
41 { 41 {
42 return scnprintf(bf, size, "%-6.6s %s", ins->name, ops->raw); 42 return scnprintf(bf, size, "%-6.6s %s", ins->name, ops->raw);
43 } 43 }
44 44
45 int ins__scnprintf(struct ins *ins, char *bf, size_t size, 45 int ins__scnprintf(struct ins *ins, char *bf, size_t size,
46 struct ins_operands *ops) 46 struct ins_operands *ops)
47 { 47 {
48 if (ins->ops->scnprintf) 48 if (ins->ops->scnprintf)
49 return ins->ops->scnprintf(ins, bf, size, ops); 49 return ins->ops->scnprintf(ins, bf, size, ops);
50 50
51 return ins__raw_scnprintf(ins, bf, size, ops); 51 return ins__raw_scnprintf(ins, bf, size, ops);
52 } 52 }
53 53
54 static int call__parse(struct ins_operands *ops) 54 static int call__parse(struct ins_operands *ops)
55 { 55 {
56 char *endptr, *tok, *name; 56 char *endptr, *tok, *name;
57 57
58 ops->target.addr = strtoull(ops->raw, &endptr, 16); 58 ops->target.addr = strtoull(ops->raw, &endptr, 16);
59 59
60 name = strchr(endptr, '<'); 60 name = strchr(endptr, '<');
61 if (name == NULL) 61 if (name == NULL)
62 goto indirect_call; 62 goto indirect_call;
63 63
64 name++; 64 name++;
65 65
66 tok = strchr(name, '>'); 66 tok = strchr(name, '>');
67 if (tok == NULL) 67 if (tok == NULL)
68 return -1; 68 return -1;
69 69
70 *tok = '\0'; 70 *tok = '\0';
71 ops->target.name = strdup(name); 71 ops->target.name = strdup(name);
72 *tok = '>'; 72 *tok = '>';
73 73
74 return ops->target.name == NULL ? -1 : 0; 74 return ops->target.name == NULL ? -1 : 0;
75 75
76 indirect_call: 76 indirect_call:
77 tok = strchr(endptr, '('); 77 tok = strchr(endptr, '(');
78 if (tok != NULL) { 78 if (tok != NULL) {
79 ops->target.addr = 0; 79 ops->target.addr = 0;
80 return 0; 80 return 0;
81 } 81 }
82 82
83 tok = strchr(endptr, '*'); 83 tok = strchr(endptr, '*');
84 if (tok == NULL) 84 if (tok == NULL)
85 return -1; 85 return -1;
86 86
87 ops->target.addr = strtoull(tok + 1, NULL, 16); 87 ops->target.addr = strtoull(tok + 1, NULL, 16);
88 return 0; 88 return 0;
89 } 89 }
90 90
91 static int call__scnprintf(struct ins *ins, char *bf, size_t size, 91 static int call__scnprintf(struct ins *ins, char *bf, size_t size,
92 struct ins_operands *ops) 92 struct ins_operands *ops)
93 { 93 {
94 if (ops->target.name) 94 if (ops->target.name)
95 return scnprintf(bf, size, "%-6.6s %s", ins->name, ops->target.name); 95 return scnprintf(bf, size, "%-6.6s %s", ins->name, ops->target.name);
96 96
97 if (ops->target.addr == 0) 97 if (ops->target.addr == 0)
98 return ins__raw_scnprintf(ins, bf, size, ops); 98 return ins__raw_scnprintf(ins, bf, size, ops);
99 99
100 return scnprintf(bf, size, "%-6.6s *%" PRIx64, ins->name, ops->target.addr); 100 return scnprintf(bf, size, "%-6.6s *%" PRIx64, ins->name, ops->target.addr);
101 } 101 }
102 102
103 static struct ins_ops call_ops = { 103 static struct ins_ops call_ops = {
104 .parse = call__parse, 104 .parse = call__parse,
105 .scnprintf = call__scnprintf, 105 .scnprintf = call__scnprintf,
106 }; 106 };
107 107
108 bool ins__is_call(const struct ins *ins) 108 bool ins__is_call(const struct ins *ins)
109 { 109 {
110 return ins->ops == &call_ops; 110 return ins->ops == &call_ops;
111 } 111 }
112 112
113 static int jump__parse(struct ins_operands *ops) 113 static int jump__parse(struct ins_operands *ops)
114 { 114 {
115 const char *s = strchr(ops->raw, '+'); 115 const char *s = strchr(ops->raw, '+');
116 116
117 ops->target.addr = strtoull(ops->raw, NULL, 16); 117 ops->target.addr = strtoull(ops->raw, NULL, 16);
118 118
119 if (s++ != NULL) 119 if (s++ != NULL)
120 ops->target.offset = strtoull(s, NULL, 16); 120 ops->target.offset = strtoull(s, NULL, 16);
121 else 121 else
122 ops->target.offset = UINT64_MAX; 122 ops->target.offset = UINT64_MAX;
123 123
124 return 0; 124 return 0;
125 } 125 }
126 126
127 static int jump__scnprintf(struct ins *ins, char *bf, size_t size, 127 static int jump__scnprintf(struct ins *ins, char *bf, size_t size,
128 struct ins_operands *ops) 128 struct ins_operands *ops)
129 { 129 {
130 return scnprintf(bf, size, "%-6.6s %" PRIx64, ins->name, ops->target.offset); 130 return scnprintf(bf, size, "%-6.6s %" PRIx64, ins->name, ops->target.offset);
131 } 131 }
132 132
133 static struct ins_ops jump_ops = { 133 static struct ins_ops jump_ops = {
134 .parse = jump__parse, 134 .parse = jump__parse,
135 .scnprintf = jump__scnprintf, 135 .scnprintf = jump__scnprintf,
136 }; 136 };
137 137
138 bool ins__is_jump(const struct ins *ins) 138 bool ins__is_jump(const struct ins *ins)
139 { 139 {
140 return ins->ops == &jump_ops; 140 return ins->ops == &jump_ops;
141 } 141 }
142 142
143 static int comment__symbol(char *raw, char *comment, u64 *addrp, char **namep) 143 static int comment__symbol(char *raw, char *comment, u64 *addrp, char **namep)
144 { 144 {
145 char *endptr, *name, *t; 145 char *endptr, *name, *t;
146 146
147 if (strstr(raw, "(%rip)") == NULL) 147 if (strstr(raw, "(%rip)") == NULL)
148 return 0; 148 return 0;
149 149
150 *addrp = strtoull(comment, &endptr, 16); 150 *addrp = strtoull(comment, &endptr, 16);
151 name = strchr(endptr, '<'); 151 name = strchr(endptr, '<');
152 if (name == NULL) 152 if (name == NULL)
153 return -1; 153 return -1;
154 154
155 name++; 155 name++;
156 156
157 t = strchr(name, '>'); 157 t = strchr(name, '>');
158 if (t == NULL) 158 if (t == NULL)
159 return 0; 159 return 0;
160 160
161 *t = '\0'; 161 *t = '\0';
162 *namep = strdup(name); 162 *namep = strdup(name);
163 *t = '>'; 163 *t = '>';
164 164
165 return 0; 165 return 0;
166 } 166 }
167 167
168 static int lock__parse(struct ins_operands *ops) 168 static int lock__parse(struct ins_operands *ops)
169 { 169 {
170 char *name; 170 char *name;
171 171
172 ops->locked.ops = zalloc(sizeof(*ops->locked.ops)); 172 ops->locked.ops = zalloc(sizeof(*ops->locked.ops));
173 if (ops->locked.ops == NULL) 173 if (ops->locked.ops == NULL)
174 return 0; 174 return 0;
175 175
176 if (disasm_line__parse(ops->raw, &name, &ops->locked.ops->raw) < 0) 176 if (disasm_line__parse(ops->raw, &name, &ops->locked.ops->raw) < 0)
177 goto out_free_ops; 177 goto out_free_ops;
178 178
179 ops->locked.ins = ins__find(name); 179 ops->locked.ins = ins__find(name);
180 free(name);
181
180 if (ops->locked.ins == NULL) 182 if (ops->locked.ins == NULL)
181 goto out_free_ops; 183 goto out_free_ops;
182 184
183 if (!ops->locked.ins->ops) 185 if (!ops->locked.ins->ops)
184 return 0; 186 return 0;
185 187
186 if (ops->locked.ins->ops->parse) 188 if (ops->locked.ins->ops->parse &&
187 ops->locked.ins->ops->parse(ops->locked.ops); 189 ops->locked.ins->ops->parse(ops->locked.ops) < 0)
190 goto out_free_ops;
188 191
189 return 0; 192 return 0;
190 193
191 out_free_ops: 194 out_free_ops:
192 zfree(&ops->locked.ops); 195 zfree(&ops->locked.ops);
193 return 0; 196 return 0;
194 } 197 }
195 198
196 static int lock__scnprintf(struct ins *ins, char *bf, size_t size, 199 static int lock__scnprintf(struct ins *ins, char *bf, size_t size,
197 struct ins_operands *ops) 200 struct ins_operands *ops)
198 { 201 {
199 int printed; 202 int printed;
200 203
201 if (ops->locked.ins == NULL) 204 if (ops->locked.ins == NULL)
202 return ins__raw_scnprintf(ins, bf, size, ops); 205 return ins__raw_scnprintf(ins, bf, size, ops);
203 206
204 printed = scnprintf(bf, size, "%-6.6s ", ins->name); 207 printed = scnprintf(bf, size, "%-6.6s ", ins->name);
205 return printed + ins__scnprintf(ops->locked.ins, bf + printed, 208 return printed + ins__scnprintf(ops->locked.ins, bf + printed,
206 size - printed, ops->locked.ops); 209 size - printed, ops->locked.ops);
207 } 210 }
208 211
209 static void lock__delete(struct ins_operands *ops) 212 static void lock__delete(struct ins_operands *ops)
210 { 213 {
214 struct ins *ins = ops->locked.ins;
215
216 if (ins && ins->ops->free)
217 ins->ops->free(ops->locked.ops);
218 else
219 ins__delete(ops->locked.ops);
220
211 zfree(&ops->locked.ops); 221 zfree(&ops->locked.ops);
212 zfree(&ops->target.raw); 222 zfree(&ops->target.raw);
213 zfree(&ops->target.name); 223 zfree(&ops->target.name);
214 } 224 }
215 225
216 static struct ins_ops lock_ops = { 226 static struct ins_ops lock_ops = {
217 .free = lock__delete, 227 .free = lock__delete,
218 .parse = lock__parse, 228 .parse = lock__parse,
219 .scnprintf = lock__scnprintf, 229 .scnprintf = lock__scnprintf,
220 }; 230 };
221 231
222 static int mov__parse(struct ins_operands *ops) 232 static int mov__parse(struct ins_operands *ops)
223 { 233 {
224 char *s = strchr(ops->raw, ','), *target, *comment, prev; 234 char *s = strchr(ops->raw, ','), *target, *comment, prev;
225 235
226 if (s == NULL) 236 if (s == NULL)
227 return -1; 237 return -1;
228 238
229 *s = '\0'; 239 *s = '\0';
230 ops->source.raw = strdup(ops->raw); 240 ops->source.raw = strdup(ops->raw);
231 *s = ','; 241 *s = ',';
232 242
233 if (ops->source.raw == NULL) 243 if (ops->source.raw == NULL)
234 return -1; 244 return -1;
235 245
236 target = ++s; 246 target = ++s;
237 comment = strchr(s, '#'); 247 comment = strchr(s, '#');
238 248
239 if (comment != NULL) 249 if (comment != NULL)
240 s = comment - 1; 250 s = comment - 1;
241 else 251 else
242 s = strchr(s, '\0') - 1; 252 s = strchr(s, '\0') - 1;
243 253
244 while (s > target && isspace(s[0])) 254 while (s > target && isspace(s[0]))
245 --s; 255 --s;
246 s++; 256 s++;
247 prev = *s; 257 prev = *s;
248 *s = '\0'; 258 *s = '\0';
249 259
250 ops->target.raw = strdup(target); 260 ops->target.raw = strdup(target);
251 *s = prev; 261 *s = prev;
252 262
253 if (ops->target.raw == NULL) 263 if (ops->target.raw == NULL)
254 goto out_free_source; 264 goto out_free_source;
255 265
256 if (comment == NULL) 266 if (comment == NULL)
257 return 0; 267 return 0;
258 268
259 while (comment[0] != '\0' && isspace(comment[0])) 269 while (comment[0] != '\0' && isspace(comment[0]))
260 ++comment; 270 ++comment;
261 271
262 comment__symbol(ops->source.raw, comment, &ops->source.addr, &ops->source.name); 272 comment__symbol(ops->source.raw, comment, &ops->source.addr, &ops->source.name);
263 comment__symbol(ops->target.raw, comment, &ops->target.addr, &ops->target.name); 273 comment__symbol(ops->target.raw, comment, &ops->target.addr, &ops->target.name);
264 274
265 return 0; 275 return 0;
266 276
267 out_free_source: 277 out_free_source:
268 zfree(&ops->source.raw); 278 zfree(&ops->source.raw);
269 return -1; 279 return -1;
270 } 280 }
271 281
272 static int mov__scnprintf(struct ins *ins, char *bf, size_t size, 282 static int mov__scnprintf(struct ins *ins, char *bf, size_t size,
273 struct ins_operands *ops) 283 struct ins_operands *ops)
274 { 284 {
275 return scnprintf(bf, size, "%-6.6s %s,%s", ins->name, 285 return scnprintf(bf, size, "%-6.6s %s,%s", ins->name,
276 ops->source.name ?: ops->source.raw, 286 ops->source.name ?: ops->source.raw,
277 ops->target.name ?: ops->target.raw); 287 ops->target.name ?: ops->target.raw);
278 } 288 }
279 289
280 static struct ins_ops mov_ops = { 290 static struct ins_ops mov_ops = {
281 .parse = mov__parse, 291 .parse = mov__parse,
282 .scnprintf = mov__scnprintf, 292 .scnprintf = mov__scnprintf,
283 }; 293 };
284 294
285 static int dec__parse(struct ins_operands *ops) 295 static int dec__parse(struct ins_operands *ops)
286 { 296 {
287 char *target, *comment, *s, prev; 297 char *target, *comment, *s, prev;
288 298
289 target = s = ops->raw; 299 target = s = ops->raw;
290 300
291 while (s[0] != '\0' && !isspace(s[0])) 301 while (s[0] != '\0' && !isspace(s[0]))
292 ++s; 302 ++s;
293 prev = *s; 303 prev = *s;
294 *s = '\0'; 304 *s = '\0';
295 305
296 ops->target.raw = strdup(target); 306 ops->target.raw = strdup(target);
297 *s = prev; 307 *s = prev;
298 308
299 if (ops->target.raw == NULL) 309 if (ops->target.raw == NULL)
300 return -1; 310 return -1;
301 311
302 comment = strchr(s, '#'); 312 comment = strchr(s, '#');
303 if (comment == NULL) 313 if (comment == NULL)
304 return 0; 314 return 0;
305 315
306 while (comment[0] != '\0' && isspace(comment[0])) 316 while (comment[0] != '\0' && isspace(comment[0]))
307 ++comment; 317 ++comment;
308 318
309 comment__symbol(ops->target.raw, comment, &ops->target.addr, &ops->target.name); 319 comment__symbol(ops->target.raw, comment, &ops->target.addr, &ops->target.name);
310 320
311 return 0; 321 return 0;
312 } 322 }
313 323
314 static int dec__scnprintf(struct ins *ins, char *bf, size_t size, 324 static int dec__scnprintf(struct ins *ins, char *bf, size_t size,
315 struct ins_operands *ops) 325 struct ins_operands *ops)
316 { 326 {
317 return scnprintf(bf, size, "%-6.6s %s", ins->name, 327 return scnprintf(bf, size, "%-6.6s %s", ins->name,
318 ops->target.name ?: ops->target.raw); 328 ops->target.name ?: ops->target.raw);
319 } 329 }
320 330
321 static struct ins_ops dec_ops = { 331 static struct ins_ops dec_ops = {
322 .parse = dec__parse, 332 .parse = dec__parse,
323 .scnprintf = dec__scnprintf, 333 .scnprintf = dec__scnprintf,
324 }; 334 };
325 335
326 static int nop__scnprintf(struct ins *ins __maybe_unused, char *bf, size_t size, 336 static int nop__scnprintf(struct ins *ins __maybe_unused, char *bf, size_t size,
327 struct ins_operands *ops __maybe_unused) 337 struct ins_operands *ops __maybe_unused)
328 { 338 {
329 return scnprintf(bf, size, "%-6.6s", "nop"); 339 return scnprintf(bf, size, "%-6.6s", "nop");
330 } 340 }
331 341
332 static struct ins_ops nop_ops = { 342 static struct ins_ops nop_ops = {
333 .scnprintf = nop__scnprintf, 343 .scnprintf = nop__scnprintf,
334 }; 344 };
335 345
336 /* 346 /*
337 * Must be sorted by name! 347 * Must be sorted by name!
338 */ 348 */
339 static struct ins instructions[] = { 349 static struct ins instructions[] = {
340 { .name = "add", .ops = &mov_ops, }, 350 { .name = "add", .ops = &mov_ops, },
341 { .name = "addl", .ops = &mov_ops, }, 351 { .name = "addl", .ops = &mov_ops, },
342 { .name = "addq", .ops = &mov_ops, }, 352 { .name = "addq", .ops = &mov_ops, },
343 { .name = "addw", .ops = &mov_ops, }, 353 { .name = "addw", .ops = &mov_ops, },
344 { .name = "and", .ops = &mov_ops, }, 354 { .name = "and", .ops = &mov_ops, },
345 { .name = "bts", .ops = &mov_ops, }, 355 { .name = "bts", .ops = &mov_ops, },
346 { .name = "call", .ops = &call_ops, }, 356 { .name = "call", .ops = &call_ops, },
347 { .name = "callq", .ops = &call_ops, }, 357 { .name = "callq", .ops = &call_ops, },
348 { .name = "cmp", .ops = &mov_ops, }, 358 { .name = "cmp", .ops = &mov_ops, },
349 { .name = "cmpb", .ops = &mov_ops, }, 359 { .name = "cmpb", .ops = &mov_ops, },
350 { .name = "cmpl", .ops = &mov_ops, }, 360 { .name = "cmpl", .ops = &mov_ops, },
351 { .name = "cmpq", .ops = &mov_ops, }, 361 { .name = "cmpq", .ops = &mov_ops, },
352 { .name = "cmpw", .ops = &mov_ops, }, 362 { .name = "cmpw", .ops = &mov_ops, },
353 { .name = "cmpxch", .ops = &mov_ops, }, 363 { .name = "cmpxch", .ops = &mov_ops, },
354 { .name = "dec", .ops = &dec_ops, }, 364 { .name = "dec", .ops = &dec_ops, },
355 { .name = "decl", .ops = &dec_ops, }, 365 { .name = "decl", .ops = &dec_ops, },
356 { .name = "imul", .ops = &mov_ops, }, 366 { .name = "imul", .ops = &mov_ops, },
357 { .name = "inc", .ops = &dec_ops, }, 367 { .name = "inc", .ops = &dec_ops, },
358 { .name = "incl", .ops = &dec_ops, }, 368 { .name = "incl", .ops = &dec_ops, },
359 { .name = "ja", .ops = &jump_ops, }, 369 { .name = "ja", .ops = &jump_ops, },
360 { .name = "jae", .ops = &jump_ops, }, 370 { .name = "jae", .ops = &jump_ops, },
361 { .name = "jb", .ops = &jump_ops, }, 371 { .name = "jb", .ops = &jump_ops, },
362 { .name = "jbe", .ops = &jump_ops, }, 372 { .name = "jbe", .ops = &jump_ops, },
363 { .name = "jc", .ops = &jump_ops, }, 373 { .name = "jc", .ops = &jump_ops, },
364 { .name = "jcxz", .ops = &jump_ops, }, 374 { .name = "jcxz", .ops = &jump_ops, },
365 { .name = "je", .ops = &jump_ops, }, 375 { .name = "je", .ops = &jump_ops, },
366 { .name = "jecxz", .ops = &jump_ops, }, 376 { .name = "jecxz", .ops = &jump_ops, },
367 { .name = "jg", .ops = &jump_ops, }, 377 { .name = "jg", .ops = &jump_ops, },
368 { .name = "jge", .ops = &jump_ops, }, 378 { .name = "jge", .ops = &jump_ops, },
369 { .name = "jl", .ops = &jump_ops, }, 379 { .name = "jl", .ops = &jump_ops, },
370 { .name = "jle", .ops = &jump_ops, }, 380 { .name = "jle", .ops = &jump_ops, },
371 { .name = "jmp", .ops = &jump_ops, }, 381 { .name = "jmp", .ops = &jump_ops, },
372 { .name = "jmpq", .ops = &jump_ops, }, 382 { .name = "jmpq", .ops = &jump_ops, },
373 { .name = "jna", .ops = &jump_ops, }, 383 { .name = "jna", .ops = &jump_ops, },
374 { .name = "jnae", .ops = &jump_ops, }, 384 { .name = "jnae", .ops = &jump_ops, },
375 { .name = "jnb", .ops = &jump_ops, }, 385 { .name = "jnb", .ops = &jump_ops, },
376 { .name = "jnbe", .ops = &jump_ops, }, 386 { .name = "jnbe", .ops = &jump_ops, },
377 { .name = "jnc", .ops = &jump_ops, }, 387 { .name = "jnc", .ops = &jump_ops, },
378 { .name = "jne", .ops = &jump_ops, }, 388 { .name = "jne", .ops = &jump_ops, },
379 { .name = "jng", .ops = &jump_ops, }, 389 { .name = "jng", .ops = &jump_ops, },
380 { .name = "jnge", .ops = &jump_ops, }, 390 { .name = "jnge", .ops = &jump_ops, },
381 { .name = "jnl", .ops = &jump_ops, }, 391 { .name = "jnl", .ops = &jump_ops, },
382 { .name = "jnle", .ops = &jump_ops, }, 392 { .name = "jnle", .ops = &jump_ops, },
383 { .name = "jno", .ops = &jump_ops, }, 393 { .name = "jno", .ops = &jump_ops, },
384 { .name = "jnp", .ops = &jump_ops, }, 394 { .name = "jnp", .ops = &jump_ops, },
385 { .name = "jns", .ops = &jump_ops, }, 395 { .name = "jns", .ops = &jump_ops, },
386 { .name = "jnz", .ops = &jump_ops, }, 396 { .name = "jnz", .ops = &jump_ops, },
387 { .name = "jo", .ops = &jump_ops, }, 397 { .name = "jo", .ops = &jump_ops, },
388 { .name = "jp", .ops = &jump_ops, }, 398 { .name = "jp", .ops = &jump_ops, },
389 { .name = "jpe", .ops = &jump_ops, }, 399 { .name = "jpe", .ops = &jump_ops, },
390 { .name = "jpo", .ops = &jump_ops, }, 400 { .name = "jpo", .ops = &jump_ops, },
391 { .name = "jrcxz", .ops = &jump_ops, }, 401 { .name = "jrcxz", .ops = &jump_ops, },
392 { .name = "js", .ops = &jump_ops, }, 402 { .name = "js", .ops = &jump_ops, },
393 { .name = "jz", .ops = &jump_ops, }, 403 { .name = "jz", .ops = &jump_ops, },
394 { .name = "lea", .ops = &mov_ops, }, 404 { .name = "lea", .ops = &mov_ops, },
395 { .name = "lock", .ops = &lock_ops, }, 405 { .name = "lock", .ops = &lock_ops, },
396 { .name = "mov", .ops = &mov_ops, }, 406 { .name = "mov", .ops = &mov_ops, },
397 { .name = "movb", .ops = &mov_ops, }, 407 { .name = "movb", .ops = &mov_ops, },
398 { .name = "movdqa",.ops = &mov_ops, }, 408 { .name = "movdqa",.ops = &mov_ops, },
399 { .name = "movl", .ops = &mov_ops, }, 409 { .name = "movl", .ops = &mov_ops, },
400 { .name = "movq", .ops = &mov_ops, }, 410 { .name = "movq", .ops = &mov_ops, },
401 { .name = "movslq", .ops = &mov_ops, }, 411 { .name = "movslq", .ops = &mov_ops, },
402 { .name = "movzbl", .ops = &mov_ops, }, 412 { .name = "movzbl", .ops = &mov_ops, },
403 { .name = "movzwl", .ops = &mov_ops, }, 413 { .name = "movzwl", .ops = &mov_ops, },
404 { .name = "nop", .ops = &nop_ops, }, 414 { .name = "nop", .ops = &nop_ops, },
405 { .name = "nopl", .ops = &nop_ops, }, 415 { .name = "nopl", .ops = &nop_ops, },
406 { .name = "nopw", .ops = &nop_ops, }, 416 { .name = "nopw", .ops = &nop_ops, },
407 { .name = "or", .ops = &mov_ops, }, 417 { .name = "or", .ops = &mov_ops, },
408 { .name = "orl", .ops = &mov_ops, }, 418 { .name = "orl", .ops = &mov_ops, },
409 { .name = "test", .ops = &mov_ops, }, 419 { .name = "test", .ops = &mov_ops, },
410 { .name = "testb", .ops = &mov_ops, }, 420 { .name = "testb", .ops = &mov_ops, },
411 { .name = "testl", .ops = &mov_ops, }, 421 { .name = "testl", .ops = &mov_ops, },
412 { .name = "xadd", .ops = &mov_ops, }, 422 { .name = "xadd", .ops = &mov_ops, },
413 { .name = "xbeginl", .ops = &jump_ops, }, 423 { .name = "xbeginl", .ops = &jump_ops, },
414 { .name = "xbeginq", .ops = &jump_ops, }, 424 { .name = "xbeginq", .ops = &jump_ops, },
415 }; 425 };
416 426
417 static int ins__cmp(const void *name, const void *insp) 427 static int ins__cmp(const void *name, const void *insp)
418 { 428 {
419 const struct ins *ins = insp; 429 const struct ins *ins = insp;
420 430
421 return strcmp(name, ins->name); 431 return strcmp(name, ins->name);
422 } 432 }
423 433
424 static struct ins *ins__find(const char *name) 434 static struct ins *ins__find(const char *name)
425 { 435 {
426 const int nmemb = ARRAY_SIZE(instructions); 436 const int nmemb = ARRAY_SIZE(instructions);
427 437
428 return bsearch(name, instructions, nmemb, sizeof(struct ins), ins__cmp); 438 return bsearch(name, instructions, nmemb, sizeof(struct ins), ins__cmp);
429 } 439 }
430 440
431 int symbol__annotate_init(struct map *map __maybe_unused, struct symbol *sym) 441 int symbol__annotate_init(struct map *map __maybe_unused, struct symbol *sym)
432 { 442 {
433 struct annotation *notes = symbol__annotation(sym); 443 struct annotation *notes = symbol__annotation(sym);
434 pthread_mutex_init(&notes->lock, NULL); 444 pthread_mutex_init(&notes->lock, NULL);
435 return 0; 445 return 0;
436 } 446 }
437 447
438 int symbol__alloc_hist(struct symbol *sym) 448 int symbol__alloc_hist(struct symbol *sym)
439 { 449 {
440 struct annotation *notes = symbol__annotation(sym); 450 struct annotation *notes = symbol__annotation(sym);
441 const size_t size = symbol__size(sym); 451 const size_t size = symbol__size(sym);
442 size_t sizeof_sym_hist; 452 size_t sizeof_sym_hist;
443 453
444 /* Check for overflow when calculating sizeof_sym_hist */ 454 /* Check for overflow when calculating sizeof_sym_hist */
445 if (size > (SIZE_MAX - sizeof(struct sym_hist)) / sizeof(u64)) 455 if (size > (SIZE_MAX - sizeof(struct sym_hist)) / sizeof(u64))
446 return -1; 456 return -1;
447 457
448 sizeof_sym_hist = (sizeof(struct sym_hist) + size * sizeof(u64)); 458 sizeof_sym_hist = (sizeof(struct sym_hist) + size * sizeof(u64));
449 459
450 /* Check for overflow in zalloc argument */ 460 /* Check for overflow in zalloc argument */
451 if (sizeof_sym_hist > (SIZE_MAX - sizeof(*notes->src)) 461 if (sizeof_sym_hist > (SIZE_MAX - sizeof(*notes->src))
452 / symbol_conf.nr_events) 462 / symbol_conf.nr_events)
453 return -1; 463 return -1;
454 464
455 notes->src = zalloc(sizeof(*notes->src) + symbol_conf.nr_events * sizeof_sym_hist); 465 notes->src = zalloc(sizeof(*notes->src) + symbol_conf.nr_events * sizeof_sym_hist);
456 if (notes->src == NULL) 466 if (notes->src == NULL)
457 return -1; 467 return -1;
458 notes->src->sizeof_sym_hist = sizeof_sym_hist; 468 notes->src->sizeof_sym_hist = sizeof_sym_hist;
459 notes->src->nr_histograms = symbol_conf.nr_events; 469 notes->src->nr_histograms = symbol_conf.nr_events;
460 INIT_LIST_HEAD(&notes->src->source); 470 INIT_LIST_HEAD(&notes->src->source);
461 return 0; 471 return 0;
462 } 472 }
463 473
464 void symbol__annotate_zero_histograms(struct symbol *sym) 474 void symbol__annotate_zero_histograms(struct symbol *sym)
465 { 475 {
466 struct annotation *notes = symbol__annotation(sym); 476 struct annotation *notes = symbol__annotation(sym);
467 477
468 pthread_mutex_lock(&notes->lock); 478 pthread_mutex_lock(&notes->lock);
469 if (notes->src != NULL) 479 if (notes->src != NULL)
470 memset(notes->src->histograms, 0, 480 memset(notes->src->histograms, 0,
471 notes->src->nr_histograms * notes->src->sizeof_sym_hist); 481 notes->src->nr_histograms * notes->src->sizeof_sym_hist);
472 pthread_mutex_unlock(&notes->lock); 482 pthread_mutex_unlock(&notes->lock);
473 } 483 }
474 484
475 static int __symbol__inc_addr_samples(struct symbol *sym, struct map *map, 485 static int __symbol__inc_addr_samples(struct symbol *sym, struct map *map,
476 struct annotation *notes, int evidx, u64 addr) 486 struct annotation *notes, int evidx, u64 addr)
477 { 487 {
478 unsigned offset; 488 unsigned offset;
479 struct sym_hist *h; 489 struct sym_hist *h;
480 490
481 pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr)); 491 pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr));
482 492
483 if (addr < sym->start || addr >= sym->end) 493 if (addr < sym->start || addr >= sym->end)
484 return -ERANGE; 494 return -ERANGE;
485 495
486 offset = addr - sym->start; 496 offset = addr - sym->start;
487 h = annotation__histogram(notes, evidx); 497 h = annotation__histogram(notes, evidx);
488 h->sum++; 498 h->sum++;
489 h->addr[offset]++; 499 h->addr[offset]++;
490 500
491 pr_debug3("%#" PRIx64 " %s: period++ [addr: %#" PRIx64 ", %#" PRIx64 501 pr_debug3("%#" PRIx64 " %s: period++ [addr: %#" PRIx64 ", %#" PRIx64
492 ", evidx=%d] => %" PRIu64 "\n", sym->start, sym->name, 502 ", evidx=%d] => %" PRIu64 "\n", sym->start, sym->name,
493 addr, addr - sym->start, evidx, h->addr[offset]); 503 addr, addr - sym->start, evidx, h->addr[offset]);
494 return 0; 504 return 0;
495 } 505 }
496 506
497 static int symbol__inc_addr_samples(struct symbol *sym, struct map *map, 507 static int symbol__inc_addr_samples(struct symbol *sym, struct map *map,
498 int evidx, u64 addr) 508 int evidx, u64 addr)
499 { 509 {
500 struct annotation *notes; 510 struct annotation *notes;
501 511
502 if (sym == NULL) 512 if (sym == NULL)
503 return 0; 513 return 0;
504 514
505 notes = symbol__annotation(sym); 515 notes = symbol__annotation(sym);
506 if (notes->src == NULL) { 516 if (notes->src == NULL) {
507 if (symbol__alloc_hist(sym) < 0) 517 if (symbol__alloc_hist(sym) < 0)
508 return -ENOMEM; 518 return -ENOMEM;
509 } 519 }
510 520
511 return __symbol__inc_addr_samples(sym, map, notes, evidx, addr); 521 return __symbol__inc_addr_samples(sym, map, notes, evidx, addr);
512 } 522 }
513 523
514 int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, int evidx) 524 int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, int evidx)
515 { 525 {
516 return symbol__inc_addr_samples(ams->sym, ams->map, evidx, ams->al_addr); 526 return symbol__inc_addr_samples(ams->sym, ams->map, evidx, ams->al_addr);
517 } 527 }
518 528
519 int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 ip) 529 int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 ip)
520 { 530 {
521 return symbol__inc_addr_samples(he->ms.sym, he->ms.map, evidx, ip); 531 return symbol__inc_addr_samples(he->ms.sym, he->ms.map, evidx, ip);
522 } 532 }
523 533
524 static void disasm_line__init_ins(struct disasm_line *dl) 534 static void disasm_line__init_ins(struct disasm_line *dl)
525 { 535 {
526 dl->ins = ins__find(dl->name); 536 dl->ins = ins__find(dl->name);
527 537
528 if (dl->ins == NULL) 538 if (dl->ins == NULL)
529 return; 539 return;
530 540
531 if (!dl->ins->ops) 541 if (!dl->ins->ops)
532 return; 542 return;
533 543
534 if (dl->ins->ops->parse) 544 if (dl->ins->ops->parse && dl->ins->ops->parse(&dl->ops) < 0)
535 dl->ins->ops->parse(&dl->ops); 545 dl->ins = NULL;
536 } 546 }
537 547
538 static int disasm_line__parse(char *line, char **namep, char **rawp) 548 static int disasm_line__parse(char *line, char **namep, char **rawp)
539 { 549 {
540 char *name = line, tmp; 550 char *name = line, tmp;
541 551
542 while (isspace(name[0])) 552 while (isspace(name[0]))
543 ++name; 553 ++name;
544 554
545 if (name[0] == '\0') 555 if (name[0] == '\0')
546 return -1; 556 return -1;
547 557
548 *rawp = name + 1; 558 *rawp = name + 1;
549 559
550 while ((*rawp)[0] != '\0' && !isspace((*rawp)[0])) 560 while ((*rawp)[0] != '\0' && !isspace((*rawp)[0]))
551 ++*rawp; 561 ++*rawp;
552 562
553 tmp = (*rawp)[0]; 563 tmp = (*rawp)[0];
554 (*rawp)[0] = '\0'; 564 (*rawp)[0] = '\0';
555 *namep = strdup(name); 565 *namep = strdup(name);
556 566
557 if (*namep == NULL) 567 if (*namep == NULL)
558 goto out_free_name; 568 goto out_free_name;
559 569
560 (*rawp)[0] = tmp; 570 (*rawp)[0] = tmp;
561 571
562 if ((*rawp)[0] != '\0') { 572 if ((*rawp)[0] != '\0') {
563 (*rawp)++; 573 (*rawp)++;
564 while (isspace((*rawp)[0])) 574 while (isspace((*rawp)[0]))
565 ++(*rawp); 575 ++(*rawp);
566 } 576 }
567 577
568 return 0; 578 return 0;
569 579
570 out_free_name: 580 out_free_name:
571 zfree(namep); 581 zfree(namep);
572 return -1; 582 return -1;
573 } 583 }
574 584
575 static struct disasm_line *disasm_line__new(s64 offset, char *line, 585 static struct disasm_line *disasm_line__new(s64 offset, char *line,
576 size_t privsize, int line_nr) 586 size_t privsize, int line_nr)
577 { 587 {
578 struct disasm_line *dl = zalloc(sizeof(*dl) + privsize); 588 struct disasm_line *dl = zalloc(sizeof(*dl) + privsize);
579 589
580 if (dl != NULL) { 590 if (dl != NULL) {
581 dl->offset = offset; 591 dl->offset = offset;
582 dl->line = strdup(line); 592 dl->line = strdup(line);
583 dl->line_nr = line_nr; 593 dl->line_nr = line_nr;
584 if (dl->line == NULL) 594 if (dl->line == NULL)
585 goto out_delete; 595 goto out_delete;
586 596
587 if (offset != -1) { 597 if (offset != -1) {
588 if (disasm_line__parse(dl->line, &dl->name, &dl->ops.raw) < 0) 598 if (disasm_line__parse(dl->line, &dl->name, &dl->ops.raw) < 0)
589 goto out_free_line; 599 goto out_free_line;
590 600
591 disasm_line__init_ins(dl); 601 disasm_line__init_ins(dl);
592 } 602 }
593 } 603 }
594 604
595 return dl; 605 return dl;
596 606
597 out_free_line: 607 out_free_line:
598 zfree(&dl->line); 608 zfree(&dl->line);
599 out_delete: 609 out_delete:
600 free(dl); 610 free(dl);
601 return NULL; 611 return NULL;
602 } 612 }
603 613
604 void disasm_line__free(struct disasm_line *dl) 614 void disasm_line__free(struct disasm_line *dl)
605 { 615 {
606 zfree(&dl->line); 616 zfree(&dl->line);
607 zfree(&dl->name); 617 zfree(&dl->name);
608 if (dl->ins && dl->ins->ops->free) 618 if (dl->ins && dl->ins->ops->free)
609 dl->ins->ops->free(&dl->ops); 619 dl->ins->ops->free(&dl->ops);
610 else 620 else
611 ins__delete(&dl->ops); 621 ins__delete(&dl->ops);
612 free(dl); 622 free(dl);
613 } 623 }
614 624
615 int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, bool raw) 625 int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, bool raw)
616 { 626 {
617 if (raw || !dl->ins) 627 if (raw || !dl->ins)
618 return scnprintf(bf, size, "%-6.6s %s", dl->name, dl->ops.raw); 628 return scnprintf(bf, size, "%-6.6s %s", dl->name, dl->ops.raw);
619 629
620 return ins__scnprintf(dl->ins, bf, size, &dl->ops); 630 return ins__scnprintf(dl->ins, bf, size, &dl->ops);
621 } 631 }
622 632
623 static void disasm__add(struct list_head *head, struct disasm_line *line) 633 static void disasm__add(struct list_head *head, struct disasm_line *line)
624 { 634 {
625 list_add_tail(&line->node, head); 635 list_add_tail(&line->node, head);
626 } 636 }
627 637
628 struct disasm_line *disasm__get_next_ip_line(struct list_head *head, struct disasm_line *pos) 638 struct disasm_line *disasm__get_next_ip_line(struct list_head *head, struct disasm_line *pos)
629 { 639 {
630 list_for_each_entry_continue(pos, head, node) 640 list_for_each_entry_continue(pos, head, node)
631 if (pos->offset >= 0) 641 if (pos->offset >= 0)
632 return pos; 642 return pos;
633 643
634 return NULL; 644 return NULL;
635 } 645 }
636 646
637 double disasm__calc_percent(struct annotation *notes, int evidx, s64 offset, 647 double disasm__calc_percent(struct annotation *notes, int evidx, s64 offset,
638 s64 end, const char **path) 648 s64 end, const char **path)
639 { 649 {
640 struct source_line *src_line = notes->src->lines; 650 struct source_line *src_line = notes->src->lines;
641 double percent = 0.0; 651 double percent = 0.0;
642 652
643 if (src_line) { 653 if (src_line) {
644 size_t sizeof_src_line = sizeof(*src_line) + 654 size_t sizeof_src_line = sizeof(*src_line) +
645 sizeof(src_line->p) * (src_line->nr_pcnt - 1); 655 sizeof(src_line->p) * (src_line->nr_pcnt - 1);
646 656
647 while (offset < end) { 657 while (offset < end) {
648 src_line = (void *)notes->src->lines + 658 src_line = (void *)notes->src->lines +
649 (sizeof_src_line * offset); 659 (sizeof_src_line * offset);
650 660
651 if (*path == NULL) 661 if (*path == NULL)
652 *path = src_line->path; 662 *path = src_line->path;
653 663
654 percent += src_line->p[evidx].percent; 664 percent += src_line->p[evidx].percent;
655 offset++; 665 offset++;
656 } 666 }
657 } else { 667 } else {
658 struct sym_hist *h = annotation__histogram(notes, evidx); 668 struct sym_hist *h = annotation__histogram(notes, evidx);
659 unsigned int hits = 0; 669 unsigned int hits = 0;
660 670
661 while (offset < end) 671 while (offset < end)
662 hits += h->addr[offset++]; 672 hits += h->addr[offset++];
663 673
664 if (h->sum) 674 if (h->sum)
665 percent = 100.0 * hits / h->sum; 675 percent = 100.0 * hits / h->sum;
666 } 676 }
667 677
668 return percent; 678 return percent;
669 } 679 }
670 680
671 static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 start, 681 static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 start,
672 struct perf_evsel *evsel, u64 len, int min_pcnt, int printed, 682 struct perf_evsel *evsel, u64 len, int min_pcnt, int printed,
673 int max_lines, struct disasm_line *queue) 683 int max_lines, struct disasm_line *queue)
674 { 684 {
675 static const char *prev_line; 685 static const char *prev_line;
676 static const char *prev_color; 686 static const char *prev_color;
677 687
678 if (dl->offset != -1) { 688 if (dl->offset != -1) {
679 const char *path = NULL; 689 const char *path = NULL;
680 double percent, max_percent = 0.0; 690 double percent, max_percent = 0.0;
681 double *ppercents = &percent; 691 double *ppercents = &percent;
682 int i, nr_percent = 1; 692 int i, nr_percent = 1;
683 const char *color; 693 const char *color;
684 struct annotation *notes = symbol__annotation(sym); 694 struct annotation *notes = symbol__annotation(sym);
685 s64 offset = dl->offset; 695 s64 offset = dl->offset;
686 const u64 addr = start + offset; 696 const u64 addr = start + offset;
687 struct disasm_line *next; 697 struct disasm_line *next;
688 698
689 next = disasm__get_next_ip_line(&notes->src->source, dl); 699 next = disasm__get_next_ip_line(&notes->src->source, dl);
690 700
691 if (perf_evsel__is_group_event(evsel)) { 701 if (perf_evsel__is_group_event(evsel)) {
692 nr_percent = evsel->nr_members; 702 nr_percent = evsel->nr_members;
693 ppercents = calloc(nr_percent, sizeof(double)); 703 ppercents = calloc(nr_percent, sizeof(double));
694 if (ppercents == NULL) 704 if (ppercents == NULL)
695 return -1; 705 return -1;
696 } 706 }
697 707
698 for (i = 0; i < nr_percent; i++) { 708 for (i = 0; i < nr_percent; i++) {
699 percent = disasm__calc_percent(notes, 709 percent = disasm__calc_percent(notes,
700 notes->src->lines ? i : evsel->idx + i, 710 notes->src->lines ? i : evsel->idx + i,
701 offset, 711 offset,
702 next ? next->offset : (s64) len, 712 next ? next->offset : (s64) len,
703 &path); 713 &path);
704 714
705 ppercents[i] = percent; 715 ppercents[i] = percent;
706 if (percent > max_percent) 716 if (percent > max_percent)
707 max_percent = percent; 717 max_percent = percent;
708 } 718 }
709 719
710 if (max_percent < min_pcnt) 720 if (max_percent < min_pcnt)
711 return -1; 721 return -1;
712 722
713 if (max_lines && printed >= max_lines) 723 if (max_lines && printed >= max_lines)
714 return 1; 724 return 1;
715 725
716 if (queue != NULL) { 726 if (queue != NULL) {
717 list_for_each_entry_from(queue, &notes->src->source, node) { 727 list_for_each_entry_from(queue, &notes->src->source, node) {
718 if (queue == dl) 728 if (queue == dl)
719 break; 729 break;
720 disasm_line__print(queue, sym, start, evsel, len, 730 disasm_line__print(queue, sym, start, evsel, len,
721 0, 0, 1, NULL); 731 0, 0, 1, NULL);
722 } 732 }
723 } 733 }
724 734
725 color = get_percent_color(max_percent); 735 color = get_percent_color(max_percent);
726 736
727 /* 737 /*
728 * Also color the filename and line if needed, with 738 * Also color the filename and line if needed, with
729 * the same color than the percentage. Don't print it 739 * the same color than the percentage. Don't print it
730 * twice for close colored addr with the same filename:line 740 * twice for close colored addr with the same filename:line
731 */ 741 */
732 if (path) { 742 if (path) {
733 if (!prev_line || strcmp(prev_line, path) 743 if (!prev_line || strcmp(prev_line, path)
734 || color != prev_color) { 744 || color != prev_color) {
735 color_fprintf(stdout, color, " %s", path); 745 color_fprintf(stdout, color, " %s", path);
736 prev_line = path; 746 prev_line = path;
737 prev_color = color; 747 prev_color = color;
738 } 748 }
739 } 749 }
740 750
741 for (i = 0; i < nr_percent; i++) { 751 for (i = 0; i < nr_percent; i++) {
742 percent = ppercents[i]; 752 percent = ppercents[i];
743 color = get_percent_color(percent); 753 color = get_percent_color(percent);
744 color_fprintf(stdout, color, " %7.2f", percent); 754 color_fprintf(stdout, color, " %7.2f", percent);
745 } 755 }
746 756
747 printf(" : "); 757 printf(" : ");
748 color_fprintf(stdout, PERF_COLOR_MAGENTA, " %" PRIx64 ":", addr); 758 color_fprintf(stdout, PERF_COLOR_MAGENTA, " %" PRIx64 ":", addr);
749 color_fprintf(stdout, PERF_COLOR_BLUE, "%s\n", dl->line); 759 color_fprintf(stdout, PERF_COLOR_BLUE, "%s\n", dl->line);
750 760
751 if (ppercents != &percent) 761 if (ppercents != &percent)
752 free(ppercents); 762 free(ppercents);
753 763
754 } else if (max_lines && printed >= max_lines) 764 } else if (max_lines && printed >= max_lines)
755 return 1; 765 return 1;
756 else { 766 else {
757 int width = 8; 767 int width = 8;
758 768
759 if (queue) 769 if (queue)
760 return -1; 770 return -1;
761 771
762 if (perf_evsel__is_group_event(evsel)) 772 if (perf_evsel__is_group_event(evsel))
763 width *= evsel->nr_members; 773 width *= evsel->nr_members;
764 774
765 if (!*dl->line) 775 if (!*dl->line)
766 printf(" %*s:\n", width, " "); 776 printf(" %*s:\n", width, " ");
767 else 777 else
768 printf(" %*s: %s\n", width, " ", dl->line); 778 printf(" %*s: %s\n", width, " ", dl->line);
769 } 779 }
770 780
771 return 0; 781 return 0;
772 } 782 }
773 783
774 /* 784 /*
775 * symbol__parse_objdump_line() parses objdump output (with -d --no-show-raw) 785 * symbol__parse_objdump_line() parses objdump output (with -d --no-show-raw)
776 * which looks like following 786 * which looks like following
777 * 787 *
778 * 0000000000415500 <_init>: 788 * 0000000000415500 <_init>:
779 * 415500: sub $0x8,%rsp 789 * 415500: sub $0x8,%rsp
780 * 415504: mov 0x2f5ad5(%rip),%rax # 70afe0 <_DYNAMIC+0x2f8> 790 * 415504: mov 0x2f5ad5(%rip),%rax # 70afe0 <_DYNAMIC+0x2f8>
781 * 41550b: test %rax,%rax 791 * 41550b: test %rax,%rax
782 * 41550e: je 415515 <_init+0x15> 792 * 41550e: je 415515 <_init+0x15>
783 * 415510: callq 416e70 <__gmon_start__@plt> 793 * 415510: callq 416e70 <__gmon_start__@plt>
784 * 415515: add $0x8,%rsp 794 * 415515: add $0x8,%rsp
785 * 415519: retq 795 * 415519: retq
786 * 796 *
787 * it will be parsed and saved into struct disasm_line as 797 * it will be parsed and saved into struct disasm_line as
788 * <offset> <name> <ops.raw> 798 * <offset> <name> <ops.raw>
789 * 799 *
790 * The offset will be a relative offset from the start of the symbol and -1 800 * The offset will be a relative offset from the start of the symbol and -1
791 * means that it's not a disassembly line so should be treated differently. 801 * means that it's not a disassembly line so should be treated differently.
792 * The ops.raw part will be parsed further according to type of the instruction. 802 * The ops.raw part will be parsed further according to type of the instruction.
793 */ 803 */
794 static int symbol__parse_objdump_line(struct symbol *sym, struct map *map, 804 static int symbol__parse_objdump_line(struct symbol *sym, struct map *map,
795 FILE *file, size_t privsize, 805 FILE *file, size_t privsize,
796 int *line_nr) 806 int *line_nr)
797 { 807 {
798 struct annotation *notes = symbol__annotation(sym); 808 struct annotation *notes = symbol__annotation(sym);
799 struct disasm_line *dl; 809 struct disasm_line *dl;
800 char *line = NULL, *parsed_line, *tmp, *tmp2, *c; 810 char *line = NULL, *parsed_line, *tmp, *tmp2, *c;
801 size_t line_len; 811 size_t line_len;
802 s64 line_ip, offset = -1; 812 s64 line_ip, offset = -1;
803 regmatch_t match[2]; 813 regmatch_t match[2];
804 814
805 if (getline(&line, &line_len, file) < 0) 815 if (getline(&line, &line_len, file) < 0)
806 return -1; 816 return -1;
807 817
808 if (!line) 818 if (!line)
809 return -1; 819 return -1;
810 820
811 while (line_len != 0 && isspace(line[line_len - 1])) 821 while (line_len != 0 && isspace(line[line_len - 1]))
812 line[--line_len] = '\0'; 822 line[--line_len] = '\0';
813 823
814 c = strchr(line, '\n'); 824 c = strchr(line, '\n');
815 if (c) 825 if (c)
816 *c = 0; 826 *c = 0;
817 827
818 line_ip = -1; 828 line_ip = -1;
819 parsed_line = line; 829 parsed_line = line;
820 830
821 /* /filename:linenr ? Save line number and ignore. */ 831 /* /filename:linenr ? Save line number and ignore. */
822 if (regexec(&file_lineno, line, 2, match, 0) == 0) { 832 if (regexec(&file_lineno, line, 2, match, 0) == 0) {
823 *line_nr = atoi(line + match[1].rm_so); 833 *line_nr = atoi(line + match[1].rm_so);
824 return 0; 834 return 0;
825 } 835 }
826 836
827 /* 837 /*
828 * Strip leading spaces: 838 * Strip leading spaces:
829 */ 839 */
830 tmp = line; 840 tmp = line;
831 while (*tmp) { 841 while (*tmp) {
832 if (*tmp != ' ') 842 if (*tmp != ' ')
833 break; 843 break;
834 tmp++; 844 tmp++;
835 } 845 }
836 846
837 if (*tmp) { 847 if (*tmp) {
838 /* 848 /*
839 * Parse hexa addresses followed by ':' 849 * Parse hexa addresses followed by ':'
840 */ 850 */
841 line_ip = strtoull(tmp, &tmp2, 16); 851 line_ip = strtoull(tmp, &tmp2, 16);
842 if (*tmp2 != ':' || tmp == tmp2 || tmp2[1] == '\0') 852 if (*tmp2 != ':' || tmp == tmp2 || tmp2[1] == '\0')
843 line_ip = -1; 853 line_ip = -1;
844 } 854 }
845 855
846 if (line_ip != -1) { 856 if (line_ip != -1) {
847 u64 start = map__rip_2objdump(map, sym->start), 857 u64 start = map__rip_2objdump(map, sym->start),
848 end = map__rip_2objdump(map, sym->end); 858 end = map__rip_2objdump(map, sym->end);
849 859
850 offset = line_ip - start; 860 offset = line_ip - start;
851 if ((u64)line_ip < start || (u64)line_ip >= end) 861 if ((u64)line_ip < start || (u64)line_ip >= end)
852 offset = -1; 862 offset = -1;
853 else 863 else
854 parsed_line = tmp2 + 1; 864 parsed_line = tmp2 + 1;
855 } 865 }
856 866
857 dl = disasm_line__new(offset, parsed_line, privsize, *line_nr); 867 dl = disasm_line__new(offset, parsed_line, privsize, *line_nr);
858 free(line); 868 free(line);
859 (*line_nr)++; 869 (*line_nr)++;
860 870
861 if (dl == NULL) 871 if (dl == NULL)
862 return -1; 872 return -1;
863 873
864 if (dl->ops.target.offset == UINT64_MAX) 874 if (dl->ops.target.offset == UINT64_MAX)
865 dl->ops.target.offset = dl->ops.target.addr - 875 dl->ops.target.offset = dl->ops.target.addr -
866 map__rip_2objdump(map, sym->start); 876 map__rip_2objdump(map, sym->start);
867 877
868 /* kcore has no symbols, so add the call target name */ 878 /* kcore has no symbols, so add the call target name */
869 if (dl->ins && ins__is_call(dl->ins) && !dl->ops.target.name) { 879 if (dl->ins && ins__is_call(dl->ins) && !dl->ops.target.name) {
870 struct addr_map_symbol target = { 880 struct addr_map_symbol target = {
871 .map = map, 881 .map = map,
872 .addr = dl->ops.target.addr, 882 .addr = dl->ops.target.addr,
873 }; 883 };
874 884
875 if (!map_groups__find_ams(&target, NULL) && 885 if (!map_groups__find_ams(&target, NULL) &&
876 target.sym->start == target.al_addr) 886 target.sym->start == target.al_addr)
877 dl->ops.target.name = strdup(target.sym->name); 887 dl->ops.target.name = strdup(target.sym->name);
878 } 888 }
879 889
880 disasm__add(&notes->src->source, dl); 890 disasm__add(&notes->src->source, dl);
881 891
882 return 0; 892 return 0;
883 } 893 }
884 894
885 static __attribute__((constructor)) void symbol__init_regexpr(void) 895 static __attribute__((constructor)) void symbol__init_regexpr(void)
886 { 896 {
887 regcomp(&file_lineno, "^/[^:]+:([0-9]+)", REG_EXTENDED); 897 regcomp(&file_lineno, "^/[^:]+:([0-9]+)", REG_EXTENDED);
888 } 898 }
889 899
890 static void delete_last_nop(struct symbol *sym) 900 static void delete_last_nop(struct symbol *sym)
891 { 901 {
892 struct annotation *notes = symbol__annotation(sym); 902 struct annotation *notes = symbol__annotation(sym);
893 struct list_head *list = &notes->src->source; 903 struct list_head *list = &notes->src->source;
894 struct disasm_line *dl; 904 struct disasm_line *dl;
895 905
896 while (!list_empty(list)) { 906 while (!list_empty(list)) {
897 dl = list_entry(list->prev, struct disasm_line, node); 907 dl = list_entry(list->prev, struct disasm_line, node);
898 908
899 if (dl->ins && dl->ins->ops) { 909 if (dl->ins && dl->ins->ops) {
900 if (dl->ins->ops != &nop_ops) 910 if (dl->ins->ops != &nop_ops)
901 return; 911 return;
902 } else { 912 } else {
903 if (!strstr(dl->line, " nop ") && 913 if (!strstr(dl->line, " nop ") &&
904 !strstr(dl->line, " nopl ") && 914 !strstr(dl->line, " nopl ") &&
905 !strstr(dl->line, " nopw ")) 915 !strstr(dl->line, " nopw "))
906 return; 916 return;
907 } 917 }
908 918
909 list_del(&dl->node); 919 list_del(&dl->node);
910 disasm_line__free(dl); 920 disasm_line__free(dl);
911 } 921 }
912 } 922 }
913 923
914 int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize) 924 int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize)
915 { 925 {
916 struct dso *dso = map->dso; 926 struct dso *dso = map->dso;
917 char *filename = dso__build_id_filename(dso, NULL, 0); 927 char *filename = dso__build_id_filename(dso, NULL, 0);
918 bool free_filename = true; 928 bool free_filename = true;
919 char command[PATH_MAX * 2]; 929 char command[PATH_MAX * 2];
920 FILE *file; 930 FILE *file;
921 int err = 0; 931 int err = 0;
922 char symfs_filename[PATH_MAX]; 932 char symfs_filename[PATH_MAX];
923 struct kcore_extract kce; 933 struct kcore_extract kce;
924 bool delete_extract = false; 934 bool delete_extract = false;
925 int lineno = 0; 935 int lineno = 0;
926 936
927 if (filename) 937 if (filename)
928 symbol__join_symfs(symfs_filename, filename); 938 symbol__join_symfs(symfs_filename, filename);
929 939
930 if (filename == NULL) { 940 if (filename == NULL) {
931 if (dso->has_build_id) { 941 if (dso->has_build_id) {
932 pr_err("Can't annotate %s: not enough memory\n", 942 pr_err("Can't annotate %s: not enough memory\n",
933 sym->name); 943 sym->name);
934 return -ENOMEM; 944 return -ENOMEM;
935 } 945 }
936 goto fallback; 946 goto fallback;
937 } else if (dso__is_kcore(dso)) { 947 } else if (dso__is_kcore(dso)) {
938 goto fallback; 948 goto fallback;
939 } else if (readlink(symfs_filename, command, sizeof(command)) < 0 || 949 } else if (readlink(symfs_filename, command, sizeof(command)) < 0 ||
940 strstr(command, "[kernel.kallsyms]") || 950 strstr(command, "[kernel.kallsyms]") ||
941 access(symfs_filename, R_OK)) { 951 access(symfs_filename, R_OK)) {
942 free(filename); 952 free(filename);
943 fallback: 953 fallback:
944 /* 954 /*
945 * If we don't have build-ids or the build-id file isn't in the 955 * If we don't have build-ids or the build-id file isn't in the
946 * cache, or is just a kallsyms file, well, lets hope that this 956 * cache, or is just a kallsyms file, well, lets hope that this
947 * DSO is the same as when 'perf record' ran. 957 * DSO is the same as when 'perf record' ran.
948 */ 958 */
949 filename = (char *)dso->long_name; 959 filename = (char *)dso->long_name;
950 symbol__join_symfs(symfs_filename, filename); 960 symbol__join_symfs(symfs_filename, filename);
951 free_filename = false; 961 free_filename = false;
952 } 962 }
953 963
954 if (dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS && 964 if (dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS &&
955 !dso__is_kcore(dso)) { 965 !dso__is_kcore(dso)) {
956 char bf[BUILD_ID_SIZE * 2 + 16] = " with build id "; 966 char bf[BUILD_ID_SIZE * 2 + 16] = " with build id ";
957 char *build_id_msg = NULL; 967 char *build_id_msg = NULL;
958 968
959 if (dso->annotate_warned) 969 if (dso->annotate_warned)
960 goto out_free_filename; 970 goto out_free_filename;
961 971
962 if (dso->has_build_id) { 972 if (dso->has_build_id) {
963 build_id__sprintf(dso->build_id, 973 build_id__sprintf(dso->build_id,
964 sizeof(dso->build_id), bf + 15); 974 sizeof(dso->build_id), bf + 15);
965 build_id_msg = bf; 975 build_id_msg = bf;
966 } 976 }
967 err = -ENOENT; 977 err = -ENOENT;
968 dso->annotate_warned = 1; 978 dso->annotate_warned = 1;
969 pr_err("Can't annotate %s:\n\n" 979 pr_err("Can't annotate %s:\n\n"
970 "No vmlinux file%s\nwas found in the path.\n\n" 980 "No vmlinux file%s\nwas found in the path.\n\n"
971 "Please use:\n\n" 981 "Please use:\n\n"
972 " perf buildid-cache -vu vmlinux\n\n" 982 " perf buildid-cache -vu vmlinux\n\n"
973 "or:\n\n" 983 "or:\n\n"
974 " --vmlinux vmlinux\n", 984 " --vmlinux vmlinux\n",
975 sym->name, build_id_msg ?: ""); 985 sym->name, build_id_msg ?: "");
976 goto out_free_filename; 986 goto out_free_filename;
977 } 987 }
978 988
979 pr_debug("%s: filename=%s, sym=%s, start=%#" PRIx64 ", end=%#" PRIx64 "\n", __func__, 989 pr_debug("%s: filename=%s, sym=%s, start=%#" PRIx64 ", end=%#" PRIx64 "\n", __func__,
980 filename, sym->name, map->unmap_ip(map, sym->start), 990 filename, sym->name, map->unmap_ip(map, sym->start),
981 map->unmap_ip(map, sym->end)); 991 map->unmap_ip(map, sym->end));
982 992
983 pr_debug("annotating [%p] %30s : [%p] %30s\n", 993 pr_debug("annotating [%p] %30s : [%p] %30s\n",
984 dso, dso->long_name, sym, sym->name); 994 dso, dso->long_name, sym, sym->name);
985 995
986 if (dso__is_kcore(dso)) { 996 if (dso__is_kcore(dso)) {
987 kce.kcore_filename = symfs_filename; 997 kce.kcore_filename = symfs_filename;
988 kce.addr = map__rip_2objdump(map, sym->start); 998 kce.addr = map__rip_2objdump(map, sym->start);
989 kce.offs = sym->start; 999 kce.offs = sym->start;
990 kce.len = sym->end - sym->start; 1000 kce.len = sym->end - sym->start;
991 if (!kcore_extract__create(&kce)) { 1001 if (!kcore_extract__create(&kce)) {
992 delete_extract = true; 1002 delete_extract = true;
993 strlcpy(symfs_filename, kce.extract_filename, 1003 strlcpy(symfs_filename, kce.extract_filename,
994 sizeof(symfs_filename)); 1004 sizeof(symfs_filename));
995 if (free_filename) { 1005 if (free_filename) {
996 free(filename); 1006 free(filename);
997 free_filename = false; 1007 free_filename = false;
998 } 1008 }
999 filename = symfs_filename; 1009 filename = symfs_filename;
1000 } 1010 }
1001 } 1011 }
1002 1012
1003 snprintf(command, sizeof(command), 1013 snprintf(command, sizeof(command),
1004 "%s %s%s --start-address=0x%016" PRIx64 1014 "%s %s%s --start-address=0x%016" PRIx64
1005 " --stop-address=0x%016" PRIx64 1015 " --stop-address=0x%016" PRIx64
1006 " -l -d %s %s -C %s 2>/dev/null|grep -v %s|expand", 1016 " -l -d %s %s -C %s 2>/dev/null|grep -v %s|expand",
1007 objdump_path ? objdump_path : "objdump", 1017 objdump_path ? objdump_path : "objdump",
1008 disassembler_style ? "-M " : "", 1018 disassembler_style ? "-M " : "",
1009 disassembler_style ? disassembler_style : "", 1019 disassembler_style ? disassembler_style : "",
1010 map__rip_2objdump(map, sym->start), 1020 map__rip_2objdump(map, sym->start),
1011 map__rip_2objdump(map, sym->end), 1021 map__rip_2objdump(map, sym->end),
1012 symbol_conf.annotate_asm_raw ? "" : "--no-show-raw", 1022 symbol_conf.annotate_asm_raw ? "" : "--no-show-raw",
1013 symbol_conf.annotate_src ? "-S" : "", 1023 symbol_conf.annotate_src ? "-S" : "",
1014 symfs_filename, filename); 1024 symfs_filename, filename);
1015 1025
1016 pr_debug("Executing: %s\n", command); 1026 pr_debug("Executing: %s\n", command);
1017 1027
1018 file = popen(command, "r"); 1028 file = popen(command, "r");
1019 if (!file) 1029 if (!file)
1020 goto out_free_filename; 1030 goto out_free_filename;
1021 1031
1022 while (!feof(file)) 1032 while (!feof(file))
1023 if (symbol__parse_objdump_line(sym, map, file, privsize, 1033 if (symbol__parse_objdump_line(sym, map, file, privsize,
1024 &lineno) < 0) 1034 &lineno) < 0)
1025 break; 1035 break;
1026 1036
1027 /* 1037 /*
1028 * kallsyms does not have symbol sizes so there may a nop at the end. 1038 * kallsyms does not have symbol sizes so there may a nop at the end.
1029 * Remove it. 1039 * Remove it.
1030 */ 1040 */
1031 if (dso__is_kcore(dso)) 1041 if (dso__is_kcore(dso))
1032 delete_last_nop(sym); 1042 delete_last_nop(sym);
1033 1043
1034 pclose(file); 1044 pclose(file);
1035 out_free_filename: 1045 out_free_filename:
1036 if (delete_extract) 1046 if (delete_extract)
1037 kcore_extract__delete(&kce); 1047 kcore_extract__delete(&kce);
1038 if (free_filename) 1048 if (free_filename)
1039 free(filename); 1049 free(filename);
1040 return err; 1050 return err;
1041 } 1051 }
1042 1052
1043 static void insert_source_line(struct rb_root *root, struct source_line *src_line) 1053 static void insert_source_line(struct rb_root *root, struct source_line *src_line)
1044 { 1054 {
1045 struct source_line *iter; 1055 struct source_line *iter;
1046 struct rb_node **p = &root->rb_node; 1056 struct rb_node **p = &root->rb_node;
1047 struct rb_node *parent = NULL; 1057 struct rb_node *parent = NULL;
1048 int i, ret; 1058 int i, ret;
1049 1059
1050 while (*p != NULL) { 1060 while (*p != NULL) {
1051 parent = *p; 1061 parent = *p;
1052 iter = rb_entry(parent, struct source_line, node); 1062 iter = rb_entry(parent, struct source_line, node);
1053 1063
1054 ret = strcmp(iter->path, src_line->path); 1064 ret = strcmp(iter->path, src_line->path);
1055 if (ret == 0) { 1065 if (ret == 0) {
1056 for (i = 0; i < src_line->nr_pcnt; i++) 1066 for (i = 0; i < src_line->nr_pcnt; i++)
1057 iter->p[i].percent_sum += src_line->p[i].percent; 1067 iter->p[i].percent_sum += src_line->p[i].percent;
1058 return; 1068 return;
1059 } 1069 }
1060 1070
1061 if (ret < 0) 1071 if (ret < 0)
1062 p = &(*p)->rb_left; 1072 p = &(*p)->rb_left;
1063 else 1073 else
1064 p = &(*p)->rb_right; 1074 p = &(*p)->rb_right;
1065 } 1075 }
1066 1076
1067 for (i = 0; i < src_line->nr_pcnt; i++) 1077 for (i = 0; i < src_line->nr_pcnt; i++)
1068 src_line->p[i].percent_sum = src_line->p[i].percent; 1078 src_line->p[i].percent_sum = src_line->p[i].percent;
1069 1079
1070 rb_link_node(&src_line->node, parent, p); 1080 rb_link_node(&src_line->node, parent, p);
1071 rb_insert_color(&src_line->node, root); 1081 rb_insert_color(&src_line->node, root);
1072 } 1082 }
1073 1083
1074 static int cmp_source_line(struct source_line *a, struct source_line *b) 1084 static int cmp_source_line(struct source_line *a, struct source_line *b)
1075 { 1085 {
1076 int i; 1086 int i;
1077 1087
1078 for (i = 0; i < a->nr_pcnt; i++) { 1088 for (i = 0; i < a->nr_pcnt; i++) {
1079 if (a->p[i].percent_sum == b->p[i].percent_sum) 1089 if (a->p[i].percent_sum == b->p[i].percent_sum)
1080 continue; 1090 continue;
1081 return a->p[i].percent_sum > b->p[i].percent_sum; 1091 return a->p[i].percent_sum > b->p[i].percent_sum;
1082 } 1092 }
1083 1093
1084 return 0; 1094 return 0;
1085 } 1095 }
1086 1096
1087 static void __resort_source_line(struct rb_root *root, struct source_line *src_line) 1097 static void __resort_source_line(struct rb_root *root, struct source_line *src_line)
1088 { 1098 {
1089 struct source_line *iter; 1099 struct source_line *iter;
1090 struct rb_node **p = &root->rb_node; 1100 struct rb_node **p = &root->rb_node;
1091 struct rb_node *parent = NULL; 1101 struct rb_node *parent = NULL;
1092 1102
1093 while (*p != NULL) { 1103 while (*p != NULL) {
1094 parent = *p; 1104 parent = *p;
1095 iter = rb_entry(parent, struct source_line, node); 1105 iter = rb_entry(parent, struct source_line, node);
1096 1106
1097 if (cmp_source_line(src_line, iter)) 1107 if (cmp_source_line(src_line, iter))
1098 p = &(*p)->rb_left; 1108 p = &(*p)->rb_left;
1099 else 1109 else
1100 p = &(*p)->rb_right; 1110 p = &(*p)->rb_right;
1101 } 1111 }
1102 1112
1103 rb_link_node(&src_line->node, parent, p); 1113 rb_link_node(&src_line->node, parent, p);
1104 rb_insert_color(&src_line->node, root); 1114 rb_insert_color(&src_line->node, root);
1105 } 1115 }
1106 1116
1107 static void resort_source_line(struct rb_root *dest_root, struct rb_root *src_root) 1117 static void resort_source_line(struct rb_root *dest_root, struct rb_root *src_root)
1108 { 1118 {
1109 struct source_line *src_line; 1119 struct source_line *src_line;
1110 struct rb_node *node; 1120 struct rb_node *node;
1111 1121
1112 node = rb_first(src_root); 1122 node = rb_first(src_root);
1113 while (node) { 1123 while (node) {
1114 struct rb_node *next; 1124 struct rb_node *next;
1115 1125
1116 src_line = rb_entry(node, struct source_line, node); 1126 src_line = rb_entry(node, struct source_line, node);
1117 next = rb_next(node); 1127 next = rb_next(node);
1118 rb_erase(node, src_root); 1128 rb_erase(node, src_root);
1119 1129
1120 __resort_source_line(dest_root, src_line); 1130 __resort_source_line(dest_root, src_line);
1121 node = next; 1131 node = next;
1122 } 1132 }
1123 } 1133 }
1124 1134
1125 static void symbol__free_source_line(struct symbol *sym, int len) 1135 static void symbol__free_source_line(struct symbol *sym, int len)
1126 { 1136 {
1127 struct annotation *notes = symbol__annotation(sym); 1137 struct annotation *notes = symbol__annotation(sym);
1128 struct source_line *src_line = notes->src->lines; 1138 struct source_line *src_line = notes->src->lines;
1129 size_t sizeof_src_line; 1139 size_t sizeof_src_line;
1130 int i; 1140 int i;
1131 1141
1132 sizeof_src_line = sizeof(*src_line) + 1142 sizeof_src_line = sizeof(*src_line) +
1133 (sizeof(src_line->p) * (src_line->nr_pcnt - 1)); 1143 (sizeof(src_line->p) * (src_line->nr_pcnt - 1));
1134 1144
1135 for (i = 0; i < len; i++) { 1145 for (i = 0; i < len; i++) {
1136 free_srcline(src_line->path); 1146 free_srcline(src_line->path);
1137 src_line = (void *)src_line + sizeof_src_line; 1147 src_line = (void *)src_line + sizeof_src_line;
1138 } 1148 }
1139 1149
1140 zfree(&notes->src->lines); 1150 zfree(&notes->src->lines);
1141 } 1151 }
1142 1152
1143 /* Get the filename:line for the colored entries */ 1153 /* Get the filename:line for the colored entries */
1144 static int symbol__get_source_line(struct symbol *sym, struct map *map, 1154 static int symbol__get_source_line(struct symbol *sym, struct map *map,
1145 struct perf_evsel *evsel, 1155 struct perf_evsel *evsel,
1146 struct rb_root *root, int len) 1156 struct rb_root *root, int len)
1147 { 1157 {
1148 u64 start; 1158 u64 start;
1149 int i, k; 1159 int i, k;
1150 int evidx = evsel->idx; 1160 int evidx = evsel->idx;
1151 struct source_line *src_line; 1161 struct source_line *src_line;
1152 struct annotation *notes = symbol__annotation(sym); 1162 struct annotation *notes = symbol__annotation(sym);
1153 struct sym_hist *h = annotation__histogram(notes, evidx); 1163 struct sym_hist *h = annotation__histogram(notes, evidx);
1154 struct rb_root tmp_root = RB_ROOT; 1164 struct rb_root tmp_root = RB_ROOT;
1155 int nr_pcnt = 1; 1165 int nr_pcnt = 1;
1156 u64 h_sum = h->sum; 1166 u64 h_sum = h->sum;
1157 size_t sizeof_src_line = sizeof(struct source_line); 1167 size_t sizeof_src_line = sizeof(struct source_line);
1158 1168
1159 if (perf_evsel__is_group_event(evsel)) { 1169 if (perf_evsel__is_group_event(evsel)) {
1160 for (i = 1; i < evsel->nr_members; i++) { 1170 for (i = 1; i < evsel->nr_members; i++) {
1161 h = annotation__histogram(notes, evidx + i); 1171 h = annotation__histogram(notes, evidx + i);
1162 h_sum += h->sum; 1172 h_sum += h->sum;
1163 } 1173 }
1164 nr_pcnt = evsel->nr_members; 1174 nr_pcnt = evsel->nr_members;
1165 sizeof_src_line += (nr_pcnt - 1) * sizeof(src_line->p); 1175 sizeof_src_line += (nr_pcnt - 1) * sizeof(src_line->p);
1166 } 1176 }
1167 1177
1168 if (!h_sum) 1178 if (!h_sum)
1169 return 0; 1179 return 0;
1170 1180
1171 src_line = notes->src->lines = calloc(len, sizeof_src_line); 1181 src_line = notes->src->lines = calloc(len, sizeof_src_line);
1172 if (!notes->src->lines) 1182 if (!notes->src->lines)
1173 return -1; 1183 return -1;
1174 1184
1175 start = map__rip_2objdump(map, sym->start); 1185 start = map__rip_2objdump(map, sym->start);
1176 1186
1177 for (i = 0; i < len; i++) { 1187 for (i = 0; i < len; i++) {
1178 u64 offset; 1188 u64 offset;
1179 double percent_max = 0.0; 1189 double percent_max = 0.0;
1180 1190
1181 src_line->nr_pcnt = nr_pcnt; 1191 src_line->nr_pcnt = nr_pcnt;
1182 1192
1183 for (k = 0; k < nr_pcnt; k++) { 1193 for (k = 0; k < nr_pcnt; k++) {
1184 h = annotation__histogram(notes, evidx + k); 1194 h = annotation__histogram(notes, evidx + k);
1185 src_line->p[k].percent = 100.0 * h->addr[i] / h->sum; 1195 src_line->p[k].percent = 100.0 * h->addr[i] / h->sum;
1186 1196
1187 if (src_line->p[k].percent > percent_max) 1197 if (src_line->p[k].percent > percent_max)
1188 percent_max = src_line->p[k].percent; 1198 percent_max = src_line->p[k].percent;
1189 } 1199 }
1190 1200
1191 if (percent_max <= 0.5) 1201 if (percent_max <= 0.5)
1192 goto next; 1202 goto next;
1193 1203
1194 offset = start + i; 1204 offset = start + i;
1195 src_line->path = get_srcline(map->dso, offset, NULL, false); 1205 src_line->path = get_srcline(map->dso, offset, NULL, false);
1196 insert_source_line(&tmp_root, src_line); 1206 insert_source_line(&tmp_root, src_line);
1197 1207
1198 next: 1208 next:
1199 src_line = (void *)src_line + sizeof_src_line; 1209 src_line = (void *)src_line + sizeof_src_line;
1200 } 1210 }
1201 1211
1202 resort_source_line(root, &tmp_root); 1212 resort_source_line(root, &tmp_root);
1203 return 0; 1213 return 0;
1204 } 1214 }
1205 1215
1206 static void print_summary(struct rb_root *root, const char *filename) 1216 static void print_summary(struct rb_root *root, const char *filename)
1207 { 1217 {
1208 struct source_line *src_line; 1218 struct source_line *src_line;
1209 struct rb_node *node; 1219 struct rb_node *node;
1210 1220
1211 printf("\nSorted summary for file %s\n", filename); 1221 printf("\nSorted summary for file %s\n", filename);
1212 printf("----------------------------------------------\n\n"); 1222 printf("----------------------------------------------\n\n");
1213 1223
1214 if (RB_EMPTY_ROOT(root)) { 1224 if (RB_EMPTY_ROOT(root)) {
1215 printf(" Nothing higher than %1.1f%%\n", MIN_GREEN); 1225 printf(" Nothing higher than %1.1f%%\n", MIN_GREEN);
1216 return; 1226 return;
1217 } 1227 }
1218 1228
1219 node = rb_first(root); 1229 node = rb_first(root);
1220 while (node) { 1230 while (node) {
1221 double percent, percent_max = 0.0; 1231 double percent, percent_max = 0.0;
1222 const char *color; 1232 const char *color;
1223 char *path; 1233 char *path;
1224 int i; 1234 int i;
1225 1235
1226 src_line = rb_entry(node, struct source_line, node); 1236 src_line = rb_entry(node, struct source_line, node);
1227 for (i = 0; i < src_line->nr_pcnt; i++) { 1237 for (i = 0; i < src_line->nr_pcnt; i++) {
1228 percent = src_line->p[i].percent_sum; 1238 percent = src_line->p[i].percent_sum;
1229 color = get_percent_color(percent); 1239 color = get_percent_color(percent);
1230 color_fprintf(stdout, color, " %7.2f", percent); 1240 color_fprintf(stdout, color, " %7.2f", percent);
1231 1241
1232 if (percent > percent_max) 1242 if (percent > percent_max)
1233 percent_max = percent; 1243 percent_max = percent;
1234 } 1244 }
1235 1245
1236 path = src_line->path; 1246 path = src_line->path;
1237 color = get_percent_color(percent_max); 1247 color = get_percent_color(percent_max);
1238 color_fprintf(stdout, color, " %s\n", path); 1248 color_fprintf(stdout, color, " %s\n", path);
1239 1249
1240 node = rb_next(node); 1250 node = rb_next(node);
1241 } 1251 }
1242 } 1252 }
1243 1253
1244 static void symbol__annotate_hits(struct symbol *sym, struct perf_evsel *evsel) 1254 static void symbol__annotate_hits(struct symbol *sym, struct perf_evsel *evsel)
1245 { 1255 {
1246 struct annotation *notes = symbol__annotation(sym); 1256 struct annotation *notes = symbol__annotation(sym);
1247 struct sym_hist *h = annotation__histogram(notes, evsel->idx); 1257 struct sym_hist *h = annotation__histogram(notes, evsel->idx);
1248 u64 len = symbol__size(sym), offset; 1258 u64 len = symbol__size(sym), offset;
1249 1259
1250 for (offset = 0; offset < len; ++offset) 1260 for (offset = 0; offset < len; ++offset)
1251 if (h->addr[offset] != 0) 1261 if (h->addr[offset] != 0)
1252 printf("%*" PRIx64 ": %" PRIu64 "\n", BITS_PER_LONG / 2, 1262 printf("%*" PRIx64 ": %" PRIu64 "\n", BITS_PER_LONG / 2,
1253 sym->start + offset, h->addr[offset]); 1263 sym->start + offset, h->addr[offset]);
1254 printf("%*s: %" PRIu64 "\n", BITS_PER_LONG / 2, "h->sum", h->sum); 1264 printf("%*s: %" PRIu64 "\n", BITS_PER_LONG / 2, "h->sum", h->sum);
1255 } 1265 }
1256 1266
1257 int symbol__annotate_printf(struct symbol *sym, struct map *map, 1267 int symbol__annotate_printf(struct symbol *sym, struct map *map,
1258 struct perf_evsel *evsel, bool full_paths, 1268 struct perf_evsel *evsel, bool full_paths,
1259 int min_pcnt, int max_lines, int context) 1269 int min_pcnt, int max_lines, int context)
1260 { 1270 {
1261 struct dso *dso = map->dso; 1271 struct dso *dso = map->dso;
1262 char *filename; 1272 char *filename;
1263 const char *d_filename; 1273 const char *d_filename;
1264 const char *evsel_name = perf_evsel__name(evsel); 1274 const char *evsel_name = perf_evsel__name(evsel);
1265 struct annotation *notes = symbol__annotation(sym); 1275 struct annotation *notes = symbol__annotation(sym);
1266 struct disasm_line *pos, *queue = NULL; 1276 struct disasm_line *pos, *queue = NULL;
1267 u64 start = map__rip_2objdump(map, sym->start); 1277 u64 start = map__rip_2objdump(map, sym->start);
1268 int printed = 2, queue_len = 0; 1278 int printed = 2, queue_len = 0;
1269 int more = 0; 1279 int more = 0;
1270 u64 len; 1280 u64 len;
1271 int width = 8; 1281 int width = 8;
1272 int namelen, evsel_name_len, graph_dotted_len; 1282 int namelen, evsel_name_len, graph_dotted_len;
1273 1283
1274 filename = strdup(dso->long_name); 1284 filename = strdup(dso->long_name);
1275 if (!filename) 1285 if (!filename)
1276 return -ENOMEM; 1286 return -ENOMEM;
1277 1287
1278 if (full_paths) 1288 if (full_paths)
1279 d_filename = filename; 1289 d_filename = filename;
1280 else 1290 else
1281 d_filename = basename(filename); 1291 d_filename = basename(filename);
1282 1292
1283 len = symbol__size(sym); 1293 len = symbol__size(sym);
1284 namelen = strlen(d_filename); 1294 namelen = strlen(d_filename);
1285 evsel_name_len = strlen(evsel_name); 1295 evsel_name_len = strlen(evsel_name);
1286 1296
1287 if (perf_evsel__is_group_event(evsel)) 1297 if (perf_evsel__is_group_event(evsel))
1288 width *= evsel->nr_members; 1298 width *= evsel->nr_members;
1289 1299
1290 printf(" %-*.*s| Source code & Disassembly of %s for %s\n", 1300 printf(" %-*.*s| Source code & Disassembly of %s for %s\n",
1291 width, width, "Percent", d_filename, evsel_name); 1301 width, width, "Percent", d_filename, evsel_name);
1292 1302
1293 graph_dotted_len = width + namelen + evsel_name_len; 1303 graph_dotted_len = width + namelen + evsel_name_len;
1294 printf("-%-*.*s-----------------------------------------\n", 1304 printf("-%-*.*s-----------------------------------------\n",
1295 graph_dotted_len, graph_dotted_len, graph_dotted_line); 1305 graph_dotted_len, graph_dotted_len, graph_dotted_line);
1296 1306
1297 if (verbose) 1307 if (verbose)
1298 symbol__annotate_hits(sym, evsel); 1308 symbol__annotate_hits(sym, evsel);
1299 1309
1300 list_for_each_entry(pos, &notes->src->source, node) { 1310 list_for_each_entry(pos, &notes->src->source, node) {
1301 if (context && queue == NULL) { 1311 if (context && queue == NULL) {
1302 queue = pos; 1312 queue = pos;
1303 queue_len = 0; 1313 queue_len = 0;
1304 } 1314 }
1305 1315
1306 switch (disasm_line__print(pos, sym, start, evsel, len, 1316 switch (disasm_line__print(pos, sym, start, evsel, len,
1307 min_pcnt, printed, max_lines, 1317 min_pcnt, printed, max_lines,
1308 queue)) { 1318 queue)) {
1309 case 0: 1319 case 0:
1310 ++printed; 1320 ++printed;
1311 if (context) { 1321 if (context) {
1312 printed += queue_len; 1322 printed += queue_len;
1313 queue = NULL; 1323 queue = NULL;
1314 queue_len = 0; 1324 queue_len = 0;
1315 } 1325 }
1316 break; 1326 break;
1317 case 1: 1327 case 1:
1318 /* filtered by max_lines */ 1328 /* filtered by max_lines */
1319 ++more; 1329 ++more;
1320 break; 1330 break;
1321 case -1: 1331 case -1:
1322 default: 1332 default:
1323 /* 1333 /*
1324 * Filtered by min_pcnt or non IP lines when 1334 * Filtered by min_pcnt or non IP lines when
1325 * context != 0 1335 * context != 0
1326 */ 1336 */
1327 if (!context) 1337 if (!context)
1328 break; 1338 break;
1329 if (queue_len == context) 1339 if (queue_len == context)
1330 queue = list_entry(queue->node.next, typeof(*queue), node); 1340 queue = list_entry(queue->node.next, typeof(*queue), node);
1331 else 1341 else
1332 ++queue_len; 1342 ++queue_len;
1333 break; 1343 break;
1334 } 1344 }
1335 } 1345 }
1336 1346
1337 free(filename); 1347 free(filename);
1338 1348
1339 return more; 1349 return more;
1340 } 1350 }
1341 1351
1342 void symbol__annotate_zero_histogram(struct symbol *sym, int evidx) 1352 void symbol__annotate_zero_histogram(struct symbol *sym, int evidx)
1343 { 1353 {
1344 struct annotation *notes = symbol__annotation(sym); 1354 struct annotation *notes = symbol__annotation(sym);
1345 struct sym_hist *h = annotation__histogram(notes, evidx); 1355 struct sym_hist *h = annotation__histogram(notes, evidx);
1346 1356
1347 memset(h, 0, notes->src->sizeof_sym_hist); 1357 memset(h, 0, notes->src->sizeof_sym_hist);
1348 } 1358 }
1349 1359
1350 void symbol__annotate_decay_histogram(struct symbol *sym, int evidx) 1360 void symbol__annotate_decay_histogram(struct symbol *sym, int evidx)
1351 { 1361 {
1352 struct annotation *notes = symbol__annotation(sym); 1362 struct annotation *notes = symbol__annotation(sym);
1353 struct sym_hist *h = annotation__histogram(notes, evidx); 1363 struct sym_hist *h = annotation__histogram(notes, evidx);
1354 int len = symbol__size(sym), offset; 1364 int len = symbol__size(sym), offset;
1355 1365
1356 h->sum = 0; 1366 h->sum = 0;
1357 for (offset = 0; offset < len; ++offset) { 1367 for (offset = 0; offset < len; ++offset) {
1358 h->addr[offset] = h->addr[offset] * 7 / 8; 1368 h->addr[offset] = h->addr[offset] * 7 / 8;
1359 h->sum += h->addr[offset]; 1369 h->sum += h->addr[offset];
1360 } 1370 }
1361 } 1371 }
1362 1372
1363 void disasm__purge(struct list_head *head) 1373 void disasm__purge(struct list_head *head)
1364 { 1374 {
1365 struct disasm_line *pos, *n; 1375 struct disasm_line *pos, *n;
1366 1376
1367 list_for_each_entry_safe(pos, n, head, node) { 1377 list_for_each_entry_safe(pos, n, head, node) {
1368 list_del(&pos->node); 1378 list_del(&pos->node);
1369 disasm_line__free(pos); 1379 disasm_line__free(pos);
1370 } 1380 }
1371 } 1381 }
1372 1382
1373 static size_t disasm_line__fprintf(struct disasm_line *dl, FILE *fp) 1383 static size_t disasm_line__fprintf(struct disasm_line *dl, FILE *fp)
1374 { 1384 {
1375 size_t printed; 1385 size_t printed;
1376 1386
1377 if (dl->offset == -1) 1387 if (dl->offset == -1)
1378 return fprintf(fp, "%s\n", dl->line); 1388 return fprintf(fp, "%s\n", dl->line);
1379 1389
1380 printed = fprintf(fp, "%#" PRIx64 " %s", dl->offset, dl->name); 1390 printed = fprintf(fp, "%#" PRIx64 " %s", dl->offset, dl->name);
1381 1391
1382 if (dl->ops.raw[0] != '\0') { 1392 if (dl->ops.raw[0] != '\0') {
1383 printed += fprintf(fp, "%.*s %s\n", 6 - (int)printed, " ", 1393 printed += fprintf(fp, "%.*s %s\n", 6 - (int)printed, " ",
1384 dl->ops.raw); 1394 dl->ops.raw);
1385 } 1395 }
1386 1396
1387 return printed + fprintf(fp, "\n"); 1397 return printed + fprintf(fp, "\n");
1388 } 1398 }
1389 1399
1390 size_t disasm__fprintf(struct list_head *head, FILE *fp) 1400 size_t disasm__fprintf(struct list_head *head, FILE *fp)
1391 { 1401 {
1392 struct disasm_line *pos; 1402 struct disasm_line *pos;
1393 size_t printed = 0; 1403 size_t printed = 0;
1394 1404
1395 list_for_each_entry(pos, head, node) 1405 list_for_each_entry(pos, head, node)
1396 printed += disasm_line__fprintf(pos, fp); 1406 printed += disasm_line__fprintf(pos, fp);
1397 1407
1398 return printed; 1408 return printed;
1399 } 1409 }
1400 1410
1401 int symbol__tty_annotate(struct symbol *sym, struct map *map, 1411 int symbol__tty_annotate(struct symbol *sym, struct map *map,
1402 struct perf_evsel *evsel, bool print_lines, 1412 struct perf_evsel *evsel, bool print_lines,
1403 bool full_paths, int min_pcnt, int max_lines) 1413 bool full_paths, int min_pcnt, int max_lines)
1404 { 1414 {
1405 struct dso *dso = map->dso; 1415 struct dso *dso = map->dso;
1406 struct rb_root source_line = RB_ROOT; 1416 struct rb_root source_line = RB_ROOT;
1407 u64 len; 1417 u64 len;
1408 1418
1409 if (symbol__annotate(sym, map, 0) < 0) 1419 if (symbol__annotate(sym, map, 0) < 0)
1410 return -1; 1420 return -1;
1411 1421
1412 len = symbol__size(sym); 1422 len = symbol__size(sym);
1413 1423
1414 if (print_lines) { 1424 if (print_lines) {
1415 symbol__get_source_line(sym, map, evsel, &source_line, len); 1425 symbol__get_source_line(sym, map, evsel, &source_line, len);
1416 print_summary(&source_line, dso->long_name); 1426 print_summary(&source_line, dso->long_name);
1417 } 1427 }
1418 1428
1419 symbol__annotate_printf(sym, map, evsel, full_paths, 1429 symbol__annotate_printf(sym, map, evsel, full_paths,
1420 min_pcnt, max_lines, 0); 1430 min_pcnt, max_lines, 0);
1421 if (print_lines) 1431 if (print_lines)
1422 symbol__free_source_line(sym, len); 1432 symbol__free_source_line(sym, len);
1423 1433
1424 disasm__purge(&symbol__annotation(sym)->src->source); 1434 disasm__purge(&symbol__annotation(sym)->src->source);
1425 1435
1426 return 0; 1436 return 0;
1427 } 1437 }
1428 1438
1429 int hist_entry__annotate(struct hist_entry *he, size_t privsize) 1439 int hist_entry__annotate(struct hist_entry *he, size_t privsize)
1430 { 1440 {
1431 return symbol__annotate(he->ms.sym, he->ms.map, privsize); 1441 return symbol__annotate(he->ms.sym, he->ms.map, privsize);
1432 } 1442 }
1433 1443
1434 bool ui__has_annotation(void) 1444 bool ui__has_annotation(void)
1435 { 1445 {
1436 return use_browser == 1 && sort__has_sym; 1446 return use_browser == 1 && sort__has_sym;
1437 } 1447 }
1438 1448
tools/perf/util/evlist.c
1 /* 1 /*
2 * Copyright (C) 2011, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com> 2 * Copyright (C) 2011, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
3 * 3 *
4 * Parts came from builtin-{top,stat,record}.c, see those files for further 4 * Parts came from builtin-{top,stat,record}.c, see those files for further
5 * copyright notes. 5 * copyright notes.
6 * 6 *
7 * Released under the GPL v2. (and only v2, not any later version) 7 * Released under the GPL v2. (and only v2, not any later version)
8 */ 8 */
9 #include "util.h" 9 #include "util.h"
10 #include <api/fs/debugfs.h> 10 #include <api/fs/debugfs.h>
11 #include <api/fs/fs.h> 11 #include <api/fs/fs.h>
12 #include <poll.h> 12 #include <poll.h>
13 #include "cpumap.h" 13 #include "cpumap.h"
14 #include "thread_map.h" 14 #include "thread_map.h"
15 #include "target.h" 15 #include "target.h"
16 #include "evlist.h" 16 #include "evlist.h"
17 #include "evsel.h" 17 #include "evsel.h"
18 #include "debug.h" 18 #include "debug.h"
19 #include <unistd.h> 19 #include <unistd.h>
20 20
21 #include "parse-events.h" 21 #include "parse-events.h"
22 #include "parse-options.h" 22 #include "parse-options.h"
23 23
24 #include <sys/mman.h> 24 #include <sys/mman.h>
25 25
26 #include <linux/bitops.h> 26 #include <linux/bitops.h>
27 #include <linux/hash.h> 27 #include <linux/hash.h>
28 #include <linux/log2.h> 28 #include <linux/log2.h>
29 29
30 static void perf_evlist__mmap_put(struct perf_evlist *evlist, int idx); 30 static void perf_evlist__mmap_put(struct perf_evlist *evlist, int idx);
31 static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx); 31 static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx);
32 32
33 #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) 33 #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
34 #define SID(e, x, y) xyarray__entry(e->sample_id, x, y) 34 #define SID(e, x, y) xyarray__entry(e->sample_id, x, y)
35 35
36 void perf_evlist__init(struct perf_evlist *evlist, struct cpu_map *cpus, 36 void perf_evlist__init(struct perf_evlist *evlist, struct cpu_map *cpus,
37 struct thread_map *threads) 37 struct thread_map *threads)
38 { 38 {
39 int i; 39 int i;
40 40
41 for (i = 0; i < PERF_EVLIST__HLIST_SIZE; ++i) 41 for (i = 0; i < PERF_EVLIST__HLIST_SIZE; ++i)
42 INIT_HLIST_HEAD(&evlist->heads[i]); 42 INIT_HLIST_HEAD(&evlist->heads[i]);
43 INIT_LIST_HEAD(&evlist->entries); 43 INIT_LIST_HEAD(&evlist->entries);
44 perf_evlist__set_maps(evlist, cpus, threads); 44 perf_evlist__set_maps(evlist, cpus, threads);
45 fdarray__init(&evlist->pollfd, 64); 45 fdarray__init(&evlist->pollfd, 64);
46 evlist->workload.pid = -1; 46 evlist->workload.pid = -1;
47 } 47 }
48 48
49 struct perf_evlist *perf_evlist__new(void) 49 struct perf_evlist *perf_evlist__new(void)
50 { 50 {
51 struct perf_evlist *evlist = zalloc(sizeof(*evlist)); 51 struct perf_evlist *evlist = zalloc(sizeof(*evlist));
52 52
53 if (evlist != NULL) 53 if (evlist != NULL)
54 perf_evlist__init(evlist, NULL, NULL); 54 perf_evlist__init(evlist, NULL, NULL);
55 55
56 return evlist; 56 return evlist;
57 } 57 }
58 58
59 struct perf_evlist *perf_evlist__new_default(void) 59 struct perf_evlist *perf_evlist__new_default(void)
60 { 60 {
61 struct perf_evlist *evlist = perf_evlist__new(); 61 struct perf_evlist *evlist = perf_evlist__new();
62 62
63 if (evlist && perf_evlist__add_default(evlist)) { 63 if (evlist && perf_evlist__add_default(evlist)) {
64 perf_evlist__delete(evlist); 64 perf_evlist__delete(evlist);
65 evlist = NULL; 65 evlist = NULL;
66 } 66 }
67 67
68 return evlist; 68 return evlist;
69 } 69 }
70 70
71 /** 71 /**
72 * perf_evlist__set_id_pos - set the positions of event ids. 72 * perf_evlist__set_id_pos - set the positions of event ids.
73 * @evlist: selected event list 73 * @evlist: selected event list
74 * 74 *
75 * Events with compatible sample types all have the same id_pos 75 * Events with compatible sample types all have the same id_pos
76 * and is_pos. For convenience, put a copy on evlist. 76 * and is_pos. For convenience, put a copy on evlist.
77 */ 77 */
78 void perf_evlist__set_id_pos(struct perf_evlist *evlist) 78 void perf_evlist__set_id_pos(struct perf_evlist *evlist)
79 { 79 {
80 struct perf_evsel *first = perf_evlist__first(evlist); 80 struct perf_evsel *first = perf_evlist__first(evlist);
81 81
82 evlist->id_pos = first->id_pos; 82 evlist->id_pos = first->id_pos;
83 evlist->is_pos = first->is_pos; 83 evlist->is_pos = first->is_pos;
84 } 84 }
85 85
86 static void perf_evlist__update_id_pos(struct perf_evlist *evlist) 86 static void perf_evlist__update_id_pos(struct perf_evlist *evlist)
87 { 87 {
88 struct perf_evsel *evsel; 88 struct perf_evsel *evsel;
89 89
90 evlist__for_each(evlist, evsel) 90 evlist__for_each(evlist, evsel)
91 perf_evsel__calc_id_pos(evsel); 91 perf_evsel__calc_id_pos(evsel);
92 92
93 perf_evlist__set_id_pos(evlist); 93 perf_evlist__set_id_pos(evlist);
94 } 94 }
95 95
96 static void perf_evlist__purge(struct perf_evlist *evlist) 96 static void perf_evlist__purge(struct perf_evlist *evlist)
97 { 97 {
98 struct perf_evsel *pos, *n; 98 struct perf_evsel *pos, *n;
99 99
100 evlist__for_each_safe(evlist, n, pos) { 100 evlist__for_each_safe(evlist, n, pos) {
101 list_del_init(&pos->node); 101 list_del_init(&pos->node);
102 perf_evsel__delete(pos); 102 perf_evsel__delete(pos);
103 } 103 }
104 104
105 evlist->nr_entries = 0; 105 evlist->nr_entries = 0;
106 } 106 }
107 107
108 void perf_evlist__exit(struct perf_evlist *evlist) 108 void perf_evlist__exit(struct perf_evlist *evlist)
109 { 109 {
110 zfree(&evlist->mmap); 110 zfree(&evlist->mmap);
111 fdarray__exit(&evlist->pollfd); 111 fdarray__exit(&evlist->pollfd);
112 } 112 }
113 113
114 void perf_evlist__delete(struct perf_evlist *evlist) 114 void perf_evlist__delete(struct perf_evlist *evlist)
115 { 115 {
116 perf_evlist__munmap(evlist); 116 perf_evlist__munmap(evlist);
117 perf_evlist__close(evlist); 117 perf_evlist__close(evlist);
118 cpu_map__delete(evlist->cpus); 118 cpu_map__delete(evlist->cpus);
119 thread_map__delete(evlist->threads); 119 thread_map__delete(evlist->threads);
120 evlist->cpus = NULL; 120 evlist->cpus = NULL;
121 evlist->threads = NULL; 121 evlist->threads = NULL;
122 perf_evlist__purge(evlist); 122 perf_evlist__purge(evlist);
123 perf_evlist__exit(evlist); 123 perf_evlist__exit(evlist);
124 free(evlist); 124 free(evlist);
125 } 125 }
126 126
127 void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry) 127 void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry)
128 { 128 {
129 list_add_tail(&entry->node, &evlist->entries); 129 list_add_tail(&entry->node, &evlist->entries);
130 entry->idx = evlist->nr_entries; 130 entry->idx = evlist->nr_entries;
131 entry->tracking = !entry->idx; 131 entry->tracking = !entry->idx;
132 132
133 if (!evlist->nr_entries++) 133 if (!evlist->nr_entries++)
134 perf_evlist__set_id_pos(evlist); 134 perf_evlist__set_id_pos(evlist);
135 } 135 }
136 136
137 void perf_evlist__splice_list_tail(struct perf_evlist *evlist, 137 void perf_evlist__splice_list_tail(struct perf_evlist *evlist,
138 struct list_head *list, 138 struct list_head *list,
139 int nr_entries) 139 int nr_entries)
140 { 140 {
141 bool set_id_pos = !evlist->nr_entries; 141 bool set_id_pos = !evlist->nr_entries;
142 142
143 list_splice_tail(list, &evlist->entries); 143 list_splice_tail(list, &evlist->entries);
144 evlist->nr_entries += nr_entries; 144 evlist->nr_entries += nr_entries;
145 if (set_id_pos) 145 if (set_id_pos)
146 perf_evlist__set_id_pos(evlist); 146 perf_evlist__set_id_pos(evlist);
147 } 147 }
148 148
149 void __perf_evlist__set_leader(struct list_head *list) 149 void __perf_evlist__set_leader(struct list_head *list)
150 { 150 {
151 struct perf_evsel *evsel, *leader; 151 struct perf_evsel *evsel, *leader;
152 152
153 leader = list_entry(list->next, struct perf_evsel, node); 153 leader = list_entry(list->next, struct perf_evsel, node);
154 evsel = list_entry(list->prev, struct perf_evsel, node); 154 evsel = list_entry(list->prev, struct perf_evsel, node);
155 155
156 leader->nr_members = evsel->idx - leader->idx + 1; 156 leader->nr_members = evsel->idx - leader->idx + 1;
157 157
158 __evlist__for_each(list, evsel) { 158 __evlist__for_each(list, evsel) {
159 evsel->leader = leader; 159 evsel->leader = leader;
160 } 160 }
161 } 161 }
162 162
163 void perf_evlist__set_leader(struct perf_evlist *evlist) 163 void perf_evlist__set_leader(struct perf_evlist *evlist)
164 { 164 {
165 if (evlist->nr_entries) { 165 if (evlist->nr_entries) {
166 evlist->nr_groups = evlist->nr_entries > 1 ? 1 : 0; 166 evlist->nr_groups = evlist->nr_entries > 1 ? 1 : 0;
167 __perf_evlist__set_leader(&evlist->entries); 167 __perf_evlist__set_leader(&evlist->entries);
168 } 168 }
169 } 169 }
170 170
171 int perf_evlist__add_default(struct perf_evlist *evlist) 171 int perf_evlist__add_default(struct perf_evlist *evlist)
172 { 172 {
173 struct perf_event_attr attr = { 173 struct perf_event_attr attr = {
174 .type = PERF_TYPE_HARDWARE, 174 .type = PERF_TYPE_HARDWARE,
175 .config = PERF_COUNT_HW_CPU_CYCLES, 175 .config = PERF_COUNT_HW_CPU_CYCLES,
176 }; 176 };
177 struct perf_evsel *evsel; 177 struct perf_evsel *evsel;
178 178
179 event_attr_init(&attr); 179 event_attr_init(&attr);
180 180
181 evsel = perf_evsel__new(&attr); 181 evsel = perf_evsel__new(&attr);
182 if (evsel == NULL) 182 if (evsel == NULL)
183 goto error; 183 goto error;
184 184
185 /* use strdup() because free(evsel) assumes name is allocated */ 185 /* use strdup() because free(evsel) assumes name is allocated */
186 evsel->name = strdup("cycles"); 186 evsel->name = strdup("cycles");
187 if (!evsel->name) 187 if (!evsel->name)
188 goto error_free; 188 goto error_free;
189 189
190 perf_evlist__add(evlist, evsel); 190 perf_evlist__add(evlist, evsel);
191 return 0; 191 return 0;
192 error_free: 192 error_free:
193 perf_evsel__delete(evsel); 193 perf_evsel__delete(evsel);
194 error: 194 error:
195 return -ENOMEM; 195 return -ENOMEM;
196 } 196 }
197 197
198 static int perf_evlist__add_attrs(struct perf_evlist *evlist, 198 static int perf_evlist__add_attrs(struct perf_evlist *evlist,
199 struct perf_event_attr *attrs, size_t nr_attrs) 199 struct perf_event_attr *attrs, size_t nr_attrs)
200 { 200 {
201 struct perf_evsel *evsel, *n; 201 struct perf_evsel *evsel, *n;
202 LIST_HEAD(head); 202 LIST_HEAD(head);
203 size_t i; 203 size_t i;
204 204
205 for (i = 0; i < nr_attrs; i++) { 205 for (i = 0; i < nr_attrs; i++) {
206 evsel = perf_evsel__new_idx(attrs + i, evlist->nr_entries + i); 206 evsel = perf_evsel__new_idx(attrs + i, evlist->nr_entries + i);
207 if (evsel == NULL) 207 if (evsel == NULL)
208 goto out_delete_partial_list; 208 goto out_delete_partial_list;
209 list_add_tail(&evsel->node, &head); 209 list_add_tail(&evsel->node, &head);
210 } 210 }
211 211
212 perf_evlist__splice_list_tail(evlist, &head, nr_attrs); 212 perf_evlist__splice_list_tail(evlist, &head, nr_attrs);
213 213
214 return 0; 214 return 0;
215 215
216 out_delete_partial_list: 216 out_delete_partial_list:
217 __evlist__for_each_safe(&head, n, evsel) 217 __evlist__for_each_safe(&head, n, evsel)
218 perf_evsel__delete(evsel); 218 perf_evsel__delete(evsel);
219 return -1; 219 return -1;
220 } 220 }
221 221
222 int __perf_evlist__add_default_attrs(struct perf_evlist *evlist, 222 int __perf_evlist__add_default_attrs(struct perf_evlist *evlist,
223 struct perf_event_attr *attrs, size_t nr_attrs) 223 struct perf_event_attr *attrs, size_t nr_attrs)
224 { 224 {
225 size_t i; 225 size_t i;
226 226
227 for (i = 0; i < nr_attrs; i++) 227 for (i = 0; i < nr_attrs; i++)
228 event_attr_init(attrs + i); 228 event_attr_init(attrs + i);
229 229
230 return perf_evlist__add_attrs(evlist, attrs, nr_attrs); 230 return perf_evlist__add_attrs(evlist, attrs, nr_attrs);
231 } 231 }
232 232
233 struct perf_evsel * 233 struct perf_evsel *
234 perf_evlist__find_tracepoint_by_id(struct perf_evlist *evlist, int id) 234 perf_evlist__find_tracepoint_by_id(struct perf_evlist *evlist, int id)
235 { 235 {
236 struct perf_evsel *evsel; 236 struct perf_evsel *evsel;
237 237
238 evlist__for_each(evlist, evsel) { 238 evlist__for_each(evlist, evsel) {
239 if (evsel->attr.type == PERF_TYPE_TRACEPOINT && 239 if (evsel->attr.type == PERF_TYPE_TRACEPOINT &&
240 (int)evsel->attr.config == id) 240 (int)evsel->attr.config == id)
241 return evsel; 241 return evsel;
242 } 242 }
243 243
244 return NULL; 244 return NULL;
245 } 245 }
246 246
247 struct perf_evsel * 247 struct perf_evsel *
248 perf_evlist__find_tracepoint_by_name(struct perf_evlist *evlist, 248 perf_evlist__find_tracepoint_by_name(struct perf_evlist *evlist,
249 const char *name) 249 const char *name)
250 { 250 {
251 struct perf_evsel *evsel; 251 struct perf_evsel *evsel;
252 252
253 evlist__for_each(evlist, evsel) { 253 evlist__for_each(evlist, evsel) {
254 if ((evsel->attr.type == PERF_TYPE_TRACEPOINT) && 254 if ((evsel->attr.type == PERF_TYPE_TRACEPOINT) &&
255 (strcmp(evsel->name, name) == 0)) 255 (strcmp(evsel->name, name) == 0))
256 return evsel; 256 return evsel;
257 } 257 }
258 258
259 return NULL; 259 return NULL;
260 } 260 }
261 261
262 int perf_evlist__add_newtp(struct perf_evlist *evlist, 262 int perf_evlist__add_newtp(struct perf_evlist *evlist,
263 const char *sys, const char *name, void *handler) 263 const char *sys, const char *name, void *handler)
264 { 264 {
265 struct perf_evsel *evsel = perf_evsel__newtp(sys, name); 265 struct perf_evsel *evsel = perf_evsel__newtp(sys, name);
266 266
267 if (evsel == NULL) 267 if (evsel == NULL)
268 return -1; 268 return -1;
269 269
270 evsel->handler = handler; 270 evsel->handler = handler;
271 perf_evlist__add(evlist, evsel); 271 perf_evlist__add(evlist, evsel);
272 return 0; 272 return 0;
273 } 273 }
274 274
275 static int perf_evlist__nr_threads(struct perf_evlist *evlist, 275 static int perf_evlist__nr_threads(struct perf_evlist *evlist,
276 struct perf_evsel *evsel) 276 struct perf_evsel *evsel)
277 { 277 {
278 if (evsel->system_wide) 278 if (evsel->system_wide)
279 return 1; 279 return 1;
280 else 280 else
281 return thread_map__nr(evlist->threads); 281 return thread_map__nr(evlist->threads);
282 } 282 }
283 283
284 void perf_evlist__disable(struct perf_evlist *evlist) 284 void perf_evlist__disable(struct perf_evlist *evlist)
285 { 285 {
286 int cpu, thread; 286 int cpu, thread;
287 struct perf_evsel *pos; 287 struct perf_evsel *pos;
288 int nr_cpus = cpu_map__nr(evlist->cpus); 288 int nr_cpus = cpu_map__nr(evlist->cpus);
289 int nr_threads; 289 int nr_threads;
290 290
291 for (cpu = 0; cpu < nr_cpus; cpu++) { 291 for (cpu = 0; cpu < nr_cpus; cpu++) {
292 evlist__for_each(evlist, pos) { 292 evlist__for_each(evlist, pos) {
293 if (!perf_evsel__is_group_leader(pos) || !pos->fd) 293 if (!perf_evsel__is_group_leader(pos) || !pos->fd)
294 continue; 294 continue;
295 nr_threads = perf_evlist__nr_threads(evlist, pos); 295 nr_threads = perf_evlist__nr_threads(evlist, pos);
296 for (thread = 0; thread < nr_threads; thread++) 296 for (thread = 0; thread < nr_threads; thread++)
297 ioctl(FD(pos, cpu, thread), 297 ioctl(FD(pos, cpu, thread),
298 PERF_EVENT_IOC_DISABLE, 0); 298 PERF_EVENT_IOC_DISABLE, 0);
299 } 299 }
300 } 300 }
301 } 301 }
302 302
303 void perf_evlist__enable(struct perf_evlist *evlist) 303 void perf_evlist__enable(struct perf_evlist *evlist)
304 { 304 {
305 int cpu, thread; 305 int cpu, thread;
306 struct perf_evsel *pos; 306 struct perf_evsel *pos;
307 int nr_cpus = cpu_map__nr(evlist->cpus); 307 int nr_cpus = cpu_map__nr(evlist->cpus);
308 int nr_threads; 308 int nr_threads;
309 309
310 for (cpu = 0; cpu < nr_cpus; cpu++) { 310 for (cpu = 0; cpu < nr_cpus; cpu++) {
311 evlist__for_each(evlist, pos) { 311 evlist__for_each(evlist, pos) {
312 if (!perf_evsel__is_group_leader(pos) || !pos->fd) 312 if (!perf_evsel__is_group_leader(pos) || !pos->fd)
313 continue; 313 continue;
314 nr_threads = perf_evlist__nr_threads(evlist, pos); 314 nr_threads = perf_evlist__nr_threads(evlist, pos);
315 for (thread = 0; thread < nr_threads; thread++) 315 for (thread = 0; thread < nr_threads; thread++)
316 ioctl(FD(pos, cpu, thread), 316 ioctl(FD(pos, cpu, thread),
317 PERF_EVENT_IOC_ENABLE, 0); 317 PERF_EVENT_IOC_ENABLE, 0);
318 } 318 }
319 } 319 }
320 } 320 }
321 321
322 int perf_evlist__disable_event(struct perf_evlist *evlist, 322 int perf_evlist__disable_event(struct perf_evlist *evlist,
323 struct perf_evsel *evsel) 323 struct perf_evsel *evsel)
324 { 324 {
325 int cpu, thread, err; 325 int cpu, thread, err;
326 int nr_cpus = cpu_map__nr(evlist->cpus); 326 int nr_cpus = cpu_map__nr(evlist->cpus);
327 int nr_threads = perf_evlist__nr_threads(evlist, evsel); 327 int nr_threads = perf_evlist__nr_threads(evlist, evsel);
328 328
329 if (!evsel->fd) 329 if (!evsel->fd)
330 return 0; 330 return 0;
331 331
332 for (cpu = 0; cpu < nr_cpus; cpu++) { 332 for (cpu = 0; cpu < nr_cpus; cpu++) {
333 for (thread = 0; thread < nr_threads; thread++) { 333 for (thread = 0; thread < nr_threads; thread++) {
334 err = ioctl(FD(evsel, cpu, thread), 334 err = ioctl(FD(evsel, cpu, thread),
335 PERF_EVENT_IOC_DISABLE, 0); 335 PERF_EVENT_IOC_DISABLE, 0);
336 if (err) 336 if (err)
337 return err; 337 return err;
338 } 338 }
339 } 339 }
340 return 0; 340 return 0;
341 } 341 }
342 342
343 int perf_evlist__enable_event(struct perf_evlist *evlist, 343 int perf_evlist__enable_event(struct perf_evlist *evlist,
344 struct perf_evsel *evsel) 344 struct perf_evsel *evsel)
345 { 345 {
346 int cpu, thread, err; 346 int cpu, thread, err;
347 int nr_cpus = cpu_map__nr(evlist->cpus); 347 int nr_cpus = cpu_map__nr(evlist->cpus);
348 int nr_threads = perf_evlist__nr_threads(evlist, evsel); 348 int nr_threads = perf_evlist__nr_threads(evlist, evsel);
349 349
350 if (!evsel->fd) 350 if (!evsel->fd)
351 return -EINVAL; 351 return -EINVAL;
352 352
353 for (cpu = 0; cpu < nr_cpus; cpu++) { 353 for (cpu = 0; cpu < nr_cpus; cpu++) {
354 for (thread = 0; thread < nr_threads; thread++) { 354 for (thread = 0; thread < nr_threads; thread++) {
355 err = ioctl(FD(evsel, cpu, thread), 355 err = ioctl(FD(evsel, cpu, thread),
356 PERF_EVENT_IOC_ENABLE, 0); 356 PERF_EVENT_IOC_ENABLE, 0);
357 if (err) 357 if (err)
358 return err; 358 return err;
359 } 359 }
360 } 360 }
361 return 0; 361 return 0;
362 } 362 }
363 363
364 static int perf_evlist__enable_event_cpu(struct perf_evlist *evlist, 364 static int perf_evlist__enable_event_cpu(struct perf_evlist *evlist,
365 struct perf_evsel *evsel, int cpu) 365 struct perf_evsel *evsel, int cpu)
366 { 366 {
367 int thread, err; 367 int thread, err;
368 int nr_threads = perf_evlist__nr_threads(evlist, evsel); 368 int nr_threads = perf_evlist__nr_threads(evlist, evsel);
369 369
370 if (!evsel->fd) 370 if (!evsel->fd)
371 return -EINVAL; 371 return -EINVAL;
372 372
373 for (thread = 0; thread < nr_threads; thread++) { 373 for (thread = 0; thread < nr_threads; thread++) {
374 err = ioctl(FD(evsel, cpu, thread), 374 err = ioctl(FD(evsel, cpu, thread),
375 PERF_EVENT_IOC_ENABLE, 0); 375 PERF_EVENT_IOC_ENABLE, 0);
376 if (err) 376 if (err)
377 return err; 377 return err;
378 } 378 }
379 return 0; 379 return 0;
380 } 380 }
381 381
382 static int perf_evlist__enable_event_thread(struct perf_evlist *evlist, 382 static int perf_evlist__enable_event_thread(struct perf_evlist *evlist,
383 struct perf_evsel *evsel, 383 struct perf_evsel *evsel,
384 int thread) 384 int thread)
385 { 385 {
386 int cpu, err; 386 int cpu, err;
387 int nr_cpus = cpu_map__nr(evlist->cpus); 387 int nr_cpus = cpu_map__nr(evlist->cpus);
388 388
389 if (!evsel->fd) 389 if (!evsel->fd)
390 return -EINVAL; 390 return -EINVAL;
391 391
392 for (cpu = 0; cpu < nr_cpus; cpu++) { 392 for (cpu = 0; cpu < nr_cpus; cpu++) {
393 err = ioctl(FD(evsel, cpu, thread), PERF_EVENT_IOC_ENABLE, 0); 393 err = ioctl(FD(evsel, cpu, thread), PERF_EVENT_IOC_ENABLE, 0);
394 if (err) 394 if (err)
395 return err; 395 return err;
396 } 396 }
397 return 0; 397 return 0;
398 } 398 }
399 399
400 int perf_evlist__enable_event_idx(struct perf_evlist *evlist, 400 int perf_evlist__enable_event_idx(struct perf_evlist *evlist,
401 struct perf_evsel *evsel, int idx) 401 struct perf_evsel *evsel, int idx)
402 { 402 {
403 bool per_cpu_mmaps = !cpu_map__empty(evlist->cpus); 403 bool per_cpu_mmaps = !cpu_map__empty(evlist->cpus);
404 404
405 if (per_cpu_mmaps) 405 if (per_cpu_mmaps)
406 return perf_evlist__enable_event_cpu(evlist, evsel, idx); 406 return perf_evlist__enable_event_cpu(evlist, evsel, idx);
407 else 407 else
408 return perf_evlist__enable_event_thread(evlist, evsel, idx); 408 return perf_evlist__enable_event_thread(evlist, evsel, idx);
409 } 409 }
410 410
411 int perf_evlist__alloc_pollfd(struct perf_evlist *evlist) 411 int perf_evlist__alloc_pollfd(struct perf_evlist *evlist)
412 { 412 {
413 int nr_cpus = cpu_map__nr(evlist->cpus); 413 int nr_cpus = cpu_map__nr(evlist->cpus);
414 int nr_threads = thread_map__nr(evlist->threads); 414 int nr_threads = thread_map__nr(evlist->threads);
415 int nfds = 0; 415 int nfds = 0;
416 struct perf_evsel *evsel; 416 struct perf_evsel *evsel;
417 417
418 evlist__for_each(evlist, evsel) { 418 evlist__for_each(evlist, evsel) {
419 if (evsel->system_wide) 419 if (evsel->system_wide)
420 nfds += nr_cpus; 420 nfds += nr_cpus;
421 else 421 else
422 nfds += nr_cpus * nr_threads; 422 nfds += nr_cpus * nr_threads;
423 } 423 }
424 424
425 if (fdarray__available_entries(&evlist->pollfd) < nfds && 425 if (fdarray__available_entries(&evlist->pollfd) < nfds &&
426 fdarray__grow(&evlist->pollfd, nfds) < 0) 426 fdarray__grow(&evlist->pollfd, nfds) < 0)
427 return -ENOMEM; 427 return -ENOMEM;
428 428
429 return 0; 429 return 0;
430 } 430 }
431 431
432 static int __perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd, int idx) 432 static int __perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd, int idx)
433 { 433 {
434 int pos = fdarray__add(&evlist->pollfd, fd, POLLIN | POLLERR | POLLHUP); 434 int pos = fdarray__add(&evlist->pollfd, fd, POLLIN | POLLERR | POLLHUP);
435 /* 435 /*
436 * Save the idx so that when we filter out fds POLLHUP'ed we can 436 * Save the idx so that when we filter out fds POLLHUP'ed we can
437 * close the associated evlist->mmap[] entry. 437 * close the associated evlist->mmap[] entry.
438 */ 438 */
439 if (pos >= 0) { 439 if (pos >= 0) {
440 evlist->pollfd.priv[pos].idx = idx; 440 evlist->pollfd.priv[pos].idx = idx;
441 441
442 fcntl(fd, F_SETFL, O_NONBLOCK); 442 fcntl(fd, F_SETFL, O_NONBLOCK);
443 } 443 }
444 444
445 return pos; 445 return pos;
446 } 446 }
447 447
448 int perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd) 448 int perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd)
449 { 449 {
450 return __perf_evlist__add_pollfd(evlist, fd, -1); 450 return __perf_evlist__add_pollfd(evlist, fd, -1);
451 } 451 }
452 452
453 static void perf_evlist__munmap_filtered(struct fdarray *fda, int fd) 453 static void perf_evlist__munmap_filtered(struct fdarray *fda, int fd)
454 { 454 {
455 struct perf_evlist *evlist = container_of(fda, struct perf_evlist, pollfd); 455 struct perf_evlist *evlist = container_of(fda, struct perf_evlist, pollfd);
456 456
457 perf_evlist__mmap_put(evlist, fda->priv[fd].idx); 457 perf_evlist__mmap_put(evlist, fda->priv[fd].idx);
458 } 458 }
459 459
460 int perf_evlist__filter_pollfd(struct perf_evlist *evlist, short revents_and_mask) 460 int perf_evlist__filter_pollfd(struct perf_evlist *evlist, short revents_and_mask)
461 { 461 {
462 return fdarray__filter(&evlist->pollfd, revents_and_mask, 462 return fdarray__filter(&evlist->pollfd, revents_and_mask,
463 perf_evlist__munmap_filtered); 463 perf_evlist__munmap_filtered);
464 } 464 }
465 465
466 int perf_evlist__poll(struct perf_evlist *evlist, int timeout) 466 int perf_evlist__poll(struct perf_evlist *evlist, int timeout)
467 { 467 {
468 return fdarray__poll(&evlist->pollfd, timeout); 468 return fdarray__poll(&evlist->pollfd, timeout);
469 } 469 }
470 470
471 static void perf_evlist__id_hash(struct perf_evlist *evlist, 471 static void perf_evlist__id_hash(struct perf_evlist *evlist,
472 struct perf_evsel *evsel, 472 struct perf_evsel *evsel,
473 int cpu, int thread, u64 id) 473 int cpu, int thread, u64 id)
474 { 474 {
475 int hash; 475 int hash;
476 struct perf_sample_id *sid = SID(evsel, cpu, thread); 476 struct perf_sample_id *sid = SID(evsel, cpu, thread);
477 477
478 sid->id = id; 478 sid->id = id;
479 sid->evsel = evsel; 479 sid->evsel = evsel;
480 hash = hash_64(sid->id, PERF_EVLIST__HLIST_BITS); 480 hash = hash_64(sid->id, PERF_EVLIST__HLIST_BITS);
481 hlist_add_head(&sid->node, &evlist->heads[hash]); 481 hlist_add_head(&sid->node, &evlist->heads[hash]);
482 } 482 }
483 483
484 void perf_evlist__id_add(struct perf_evlist *evlist, struct perf_evsel *evsel, 484 void perf_evlist__id_add(struct perf_evlist *evlist, struct perf_evsel *evsel,
485 int cpu, int thread, u64 id) 485 int cpu, int thread, u64 id)
486 { 486 {
487 perf_evlist__id_hash(evlist, evsel, cpu, thread, id); 487 perf_evlist__id_hash(evlist, evsel, cpu, thread, id);
488 evsel->id[evsel->ids++] = id; 488 evsel->id[evsel->ids++] = id;
489 } 489 }
490 490
491 static int perf_evlist__id_add_fd(struct perf_evlist *evlist, 491 static int perf_evlist__id_add_fd(struct perf_evlist *evlist,
492 struct perf_evsel *evsel, 492 struct perf_evsel *evsel,
493 int cpu, int thread, int fd) 493 int cpu, int thread, int fd)
494 { 494 {
495 u64 read_data[4] = { 0, }; 495 u64 read_data[4] = { 0, };
496 int id_idx = 1; /* The first entry is the counter value */ 496 int id_idx = 1; /* The first entry is the counter value */
497 u64 id; 497 u64 id;
498 int ret; 498 int ret;
499 499
500 ret = ioctl(fd, PERF_EVENT_IOC_ID, &id); 500 ret = ioctl(fd, PERF_EVENT_IOC_ID, &id);
501 if (!ret) 501 if (!ret)
502 goto add; 502 goto add;
503 503
504 if (errno != ENOTTY) 504 if (errno != ENOTTY)
505 return -1; 505 return -1;
506 506
507 /* Legacy way to get event id.. All hail to old kernels! */ 507 /* Legacy way to get event id.. All hail to old kernels! */
508 508
509 /* 509 /*
510 * This way does not work with group format read, so bail 510 * This way does not work with group format read, so bail
511 * out in that case. 511 * out in that case.
512 */ 512 */
513 if (perf_evlist__read_format(evlist) & PERF_FORMAT_GROUP) 513 if (perf_evlist__read_format(evlist) & PERF_FORMAT_GROUP)
514 return -1; 514 return -1;
515 515
516 if (!(evsel->attr.read_format & PERF_FORMAT_ID) || 516 if (!(evsel->attr.read_format & PERF_FORMAT_ID) ||
517 read(fd, &read_data, sizeof(read_data)) == -1) 517 read(fd, &read_data, sizeof(read_data)) == -1)
518 return -1; 518 return -1;
519 519
520 if (evsel->attr.read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) 520 if (evsel->attr.read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
521 ++id_idx; 521 ++id_idx;
522 if (evsel->attr.read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) 522 if (evsel->attr.read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
523 ++id_idx; 523 ++id_idx;
524 524
525 id = read_data[id_idx]; 525 id = read_data[id_idx];
526 526
527 add: 527 add:
528 perf_evlist__id_add(evlist, evsel, cpu, thread, id); 528 perf_evlist__id_add(evlist, evsel, cpu, thread, id);
529 return 0; 529 return 0;
530 } 530 }
531 531
532 static void perf_evlist__set_sid_idx(struct perf_evlist *evlist, 532 static void perf_evlist__set_sid_idx(struct perf_evlist *evlist,
533 struct perf_evsel *evsel, int idx, int cpu, 533 struct perf_evsel *evsel, int idx, int cpu,
534 int thread) 534 int thread)
535 { 535 {
536 struct perf_sample_id *sid = SID(evsel, cpu, thread); 536 struct perf_sample_id *sid = SID(evsel, cpu, thread);
537 sid->idx = idx; 537 sid->idx = idx;
538 if (evlist->cpus && cpu >= 0) 538 if (evlist->cpus && cpu >= 0)
539 sid->cpu = evlist->cpus->map[cpu]; 539 sid->cpu = evlist->cpus->map[cpu];
540 else 540 else
541 sid->cpu = -1; 541 sid->cpu = -1;
542 if (!evsel->system_wide && evlist->threads && thread >= 0) 542 if (!evsel->system_wide && evlist->threads && thread >= 0)
543 sid->tid = evlist->threads->map[thread]; 543 sid->tid = evlist->threads->map[thread];
544 else 544 else
545 sid->tid = -1; 545 sid->tid = -1;
546 } 546 }
547 547
548 struct perf_sample_id *perf_evlist__id2sid(struct perf_evlist *evlist, u64 id) 548 struct perf_sample_id *perf_evlist__id2sid(struct perf_evlist *evlist, u64 id)
549 { 549 {
550 struct hlist_head *head; 550 struct hlist_head *head;
551 struct perf_sample_id *sid; 551 struct perf_sample_id *sid;
552 int hash; 552 int hash;
553 553
554 hash = hash_64(id, PERF_EVLIST__HLIST_BITS); 554 hash = hash_64(id, PERF_EVLIST__HLIST_BITS);
555 head = &evlist->heads[hash]; 555 head = &evlist->heads[hash];
556 556
557 hlist_for_each_entry(sid, head, node) 557 hlist_for_each_entry(sid, head, node)
558 if (sid->id == id) 558 if (sid->id == id)
559 return sid; 559 return sid;
560 560
561 return NULL; 561 return NULL;
562 } 562 }
563 563
564 struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id) 564 struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id)
565 { 565 {
566 struct perf_sample_id *sid; 566 struct perf_sample_id *sid;
567 567
568 if (evlist->nr_entries == 1) 568 if (evlist->nr_entries == 1)
569 return perf_evlist__first(evlist); 569 return perf_evlist__first(evlist);
570 570
571 sid = perf_evlist__id2sid(evlist, id); 571 sid = perf_evlist__id2sid(evlist, id);
572 if (sid) 572 if (sid)
573 return sid->evsel; 573 return sid->evsel;
574 574
575 if (!perf_evlist__sample_id_all(evlist)) 575 if (!perf_evlist__sample_id_all(evlist))
576 return perf_evlist__first(evlist); 576 return perf_evlist__first(evlist);
577 577
578 return NULL; 578 return NULL;
579 } 579 }
580 580
581 static int perf_evlist__event2id(struct perf_evlist *evlist, 581 static int perf_evlist__event2id(struct perf_evlist *evlist,
582 union perf_event *event, u64 *id) 582 union perf_event *event, u64 *id)
583 { 583 {
584 const u64 *array = event->sample.array; 584 const u64 *array = event->sample.array;
585 ssize_t n; 585 ssize_t n;
586 586
587 n = (event->header.size - sizeof(event->header)) >> 3; 587 n = (event->header.size - sizeof(event->header)) >> 3;
588 588
589 if (event->header.type == PERF_RECORD_SAMPLE) { 589 if (event->header.type == PERF_RECORD_SAMPLE) {
590 if (evlist->id_pos >= n) 590 if (evlist->id_pos >= n)
591 return -1; 591 return -1;
592 *id = array[evlist->id_pos]; 592 *id = array[evlist->id_pos];
593 } else { 593 } else {
594 if (evlist->is_pos > n) 594 if (evlist->is_pos > n)
595 return -1; 595 return -1;
596 n -= evlist->is_pos; 596 n -= evlist->is_pos;
597 *id = array[n]; 597 *id = array[n];
598 } 598 }
599 return 0; 599 return 0;
600 } 600 }
601 601
602 static struct perf_evsel *perf_evlist__event2evsel(struct perf_evlist *evlist, 602 static struct perf_evsel *perf_evlist__event2evsel(struct perf_evlist *evlist,
603 union perf_event *event) 603 union perf_event *event)
604 { 604 {
605 struct perf_evsel *first = perf_evlist__first(evlist); 605 struct perf_evsel *first = perf_evlist__first(evlist);
606 struct hlist_head *head; 606 struct hlist_head *head;
607 struct perf_sample_id *sid; 607 struct perf_sample_id *sid;
608 int hash; 608 int hash;
609 u64 id; 609 u64 id;
610 610
611 if (evlist->nr_entries == 1) 611 if (evlist->nr_entries == 1)
612 return first; 612 return first;
613 613
614 if (!first->attr.sample_id_all && 614 if (!first->attr.sample_id_all &&
615 event->header.type != PERF_RECORD_SAMPLE) 615 event->header.type != PERF_RECORD_SAMPLE)
616 return first; 616 return first;
617 617
618 if (perf_evlist__event2id(evlist, event, &id)) 618 if (perf_evlist__event2id(evlist, event, &id))
619 return NULL; 619 return NULL;
620 620
621 /* Synthesized events have an id of zero */ 621 /* Synthesized events have an id of zero */
622 if (!id) 622 if (!id)
623 return first; 623 return first;
624 624
625 hash = hash_64(id, PERF_EVLIST__HLIST_BITS); 625 hash = hash_64(id, PERF_EVLIST__HLIST_BITS);
626 head = &evlist->heads[hash]; 626 head = &evlist->heads[hash];
627 627
628 hlist_for_each_entry(sid, head, node) { 628 hlist_for_each_entry(sid, head, node) {
629 if (sid->id == id) 629 if (sid->id == id)
630 return sid->evsel; 630 return sid->evsel;
631 } 631 }
632 return NULL; 632 return NULL;
633 } 633 }
634 634
635 union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx) 635 union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
636 { 636 {
637 struct perf_mmap *md = &evlist->mmap[idx]; 637 struct perf_mmap *md = &evlist->mmap[idx];
638 unsigned int head = perf_mmap__read_head(md); 638 unsigned int head = perf_mmap__read_head(md);
639 unsigned int old = md->prev; 639 unsigned int old = md->prev;
640 unsigned char *data = md->base + page_size; 640 unsigned char *data = md->base + page_size;
641 union perf_event *event = NULL; 641 union perf_event *event = NULL;
642 642
643 if (evlist->overwrite) { 643 if (evlist->overwrite) {
644 /* 644 /*
645 * If we're further behind than half the buffer, there's a chance 645 * If we're further behind than half the buffer, there's a chance
646 * the writer will bite our tail and mess up the samples under us. 646 * the writer will bite our tail and mess up the samples under us.
647 * 647 *
648 * If we somehow ended up ahead of the head, we got messed up. 648 * If we somehow ended up ahead of the head, we got messed up.
649 * 649 *
650 * In either case, truncate and restart at head. 650 * In either case, truncate and restart at head.
651 */ 651 */
652 int diff = head - old; 652 int diff = head - old;
653 if (diff > md->mask / 2 || diff < 0) { 653 if (diff > md->mask / 2 || diff < 0) {
654 fprintf(stderr, "WARNING: failed to keep up with mmap data.\n"); 654 fprintf(stderr, "WARNING: failed to keep up with mmap data.\n");
655 655
656 /* 656 /*
657 * head points to a known good entry, start there. 657 * head points to a known good entry, start there.
658 */ 658 */
659 old = head; 659 old = head;
660 } 660 }
661 } 661 }
662 662
663 if (old != head) { 663 if (old != head) {
664 size_t size; 664 size_t size;
665 665
666 event = (union perf_event *)&data[old & md->mask]; 666 event = (union perf_event *)&data[old & md->mask];
667 size = event->header.size; 667 size = event->header.size;
668 668
669 /* 669 /*
670 * Event straddles the mmap boundary -- header should always 670 * Event straddles the mmap boundary -- header should always
671 * be inside due to u64 alignment of output. 671 * be inside due to u64 alignment of output.
672 */ 672 */
673 if ((old & md->mask) + size != ((old + size) & md->mask)) { 673 if ((old & md->mask) + size != ((old + size) & md->mask)) {
674 unsigned int offset = old; 674 unsigned int offset = old;
675 unsigned int len = min(sizeof(*event), size), cpy; 675 unsigned int len = min(sizeof(*event), size), cpy;
676 void *dst = md->event_copy; 676 void *dst = md->event_copy;
677 677
678 do { 678 do {
679 cpy = min(md->mask + 1 - (offset & md->mask), len); 679 cpy = min(md->mask + 1 - (offset & md->mask), len);
680 memcpy(dst, &data[offset & md->mask], cpy); 680 memcpy(dst, &data[offset & md->mask], cpy);
681 offset += cpy; 681 offset += cpy;
682 dst += cpy; 682 dst += cpy;
683 len -= cpy; 683 len -= cpy;
684 } while (len); 684 } while (len);
685 685
686 event = (union perf_event *) md->event_copy; 686 event = (union perf_event *) md->event_copy;
687 } 687 }
688 688
689 old += size; 689 old += size;
690 } 690 }
691 691
692 md->prev = old; 692 md->prev = old;
693 693
694 return event; 694 return event;
695 } 695 }
696 696
697 static bool perf_mmap__empty(struct perf_mmap *md) 697 static bool perf_mmap__empty(struct perf_mmap *md)
698 { 698 {
699 return perf_mmap__read_head(md) != md->prev; 699 return perf_mmap__read_head(md) != md->prev;
700 } 700 }
701 701
702 static void perf_evlist__mmap_get(struct perf_evlist *evlist, int idx) 702 static void perf_evlist__mmap_get(struct perf_evlist *evlist, int idx)
703 { 703 {
704 ++evlist->mmap[idx].refcnt; 704 ++evlist->mmap[idx].refcnt;
705 } 705 }
706 706
707 static void perf_evlist__mmap_put(struct perf_evlist *evlist, int idx) 707 static void perf_evlist__mmap_put(struct perf_evlist *evlist, int idx)
708 { 708 {
709 BUG_ON(evlist->mmap[idx].refcnt == 0); 709 BUG_ON(evlist->mmap[idx].refcnt == 0);
710 710
711 if (--evlist->mmap[idx].refcnt == 0) 711 if (--evlist->mmap[idx].refcnt == 0)
712 __perf_evlist__munmap(evlist, idx); 712 __perf_evlist__munmap(evlist, idx);
713 } 713 }
714 714
715 void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx) 715 void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx)
716 { 716 {
717 struct perf_mmap *md = &evlist->mmap[idx]; 717 struct perf_mmap *md = &evlist->mmap[idx];
718 718
719 if (!evlist->overwrite) { 719 if (!evlist->overwrite) {
720 unsigned int old = md->prev; 720 unsigned int old = md->prev;
721 721
722 perf_mmap__write_tail(md, old); 722 perf_mmap__write_tail(md, old);
723 } 723 }
724 724
725 if (md->refcnt == 1 && perf_mmap__empty(md)) 725 if (md->refcnt == 1 && perf_mmap__empty(md))
726 perf_evlist__mmap_put(evlist, idx); 726 perf_evlist__mmap_put(evlist, idx);
727 } 727 }
728 728
729 static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx) 729 static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx)
730 { 730 {
731 if (evlist->mmap[idx].base != NULL) { 731 if (evlist->mmap[idx].base != NULL) {
732 munmap(evlist->mmap[idx].base, evlist->mmap_len); 732 munmap(evlist->mmap[idx].base, evlist->mmap_len);
733 evlist->mmap[idx].base = NULL; 733 evlist->mmap[idx].base = NULL;
734 evlist->mmap[idx].refcnt = 0; 734 evlist->mmap[idx].refcnt = 0;
735 } 735 }
736 } 736 }
737 737
738 void perf_evlist__munmap(struct perf_evlist *evlist) 738 void perf_evlist__munmap(struct perf_evlist *evlist)
739 { 739 {
740 int i; 740 int i;
741 741
742 if (evlist->mmap == NULL) 742 if (evlist->mmap == NULL)
743 return; 743 return;
744 744
745 for (i = 0; i < evlist->nr_mmaps; i++) 745 for (i = 0; i < evlist->nr_mmaps; i++)
746 __perf_evlist__munmap(evlist, i); 746 __perf_evlist__munmap(evlist, i);
747 747
748 zfree(&evlist->mmap); 748 zfree(&evlist->mmap);
749 } 749 }
750 750
751 static int perf_evlist__alloc_mmap(struct perf_evlist *evlist) 751 static int perf_evlist__alloc_mmap(struct perf_evlist *evlist)
752 { 752 {
753 evlist->nr_mmaps = cpu_map__nr(evlist->cpus); 753 evlist->nr_mmaps = cpu_map__nr(evlist->cpus);
754 if (cpu_map__empty(evlist->cpus)) 754 if (cpu_map__empty(evlist->cpus))
755 evlist->nr_mmaps = thread_map__nr(evlist->threads); 755 evlist->nr_mmaps = thread_map__nr(evlist->threads);
756 evlist->mmap = zalloc(evlist->nr_mmaps * sizeof(struct perf_mmap)); 756 evlist->mmap = zalloc(evlist->nr_mmaps * sizeof(struct perf_mmap));
757 return evlist->mmap != NULL ? 0 : -ENOMEM; 757 return evlist->mmap != NULL ? 0 : -ENOMEM;
758 } 758 }
759 759
760 struct mmap_params { 760 struct mmap_params {
761 int prot; 761 int prot;
762 int mask; 762 int mask;
763 }; 763 };
764 764
765 static int __perf_evlist__mmap(struct perf_evlist *evlist, int idx, 765 static int __perf_evlist__mmap(struct perf_evlist *evlist, int idx,
766 struct mmap_params *mp, int fd) 766 struct mmap_params *mp, int fd)
767 { 767 {
768 /* 768 /*
769 * The last one will be done at perf_evlist__mmap_consume(), so that we 769 * The last one will be done at perf_evlist__mmap_consume(), so that we
770 * make sure we don't prevent tools from consuming every last event in 770 * make sure we don't prevent tools from consuming every last event in
771 * the ring buffer. 771 * the ring buffer.
772 * 772 *
773 * I.e. we can get the POLLHUP meaning that the fd doesn't exist 773 * I.e. we can get the POLLHUP meaning that the fd doesn't exist
774 * anymore, but the last events for it are still in the ring buffer, 774 * anymore, but the last events for it are still in the ring buffer,
775 * waiting to be consumed. 775 * waiting to be consumed.
776 * 776 *
777 * Tools can chose to ignore this at their own discretion, but the 777 * Tools can chose to ignore this at their own discretion, but the
778 * evlist layer can't just drop it when filtering events in 778 * evlist layer can't just drop it when filtering events in
779 * perf_evlist__filter_pollfd(). 779 * perf_evlist__filter_pollfd().
780 */ 780 */
781 evlist->mmap[idx].refcnt = 2; 781 evlist->mmap[idx].refcnt = 2;
782 evlist->mmap[idx].prev = 0; 782 evlist->mmap[idx].prev = 0;
783 evlist->mmap[idx].mask = mp->mask; 783 evlist->mmap[idx].mask = mp->mask;
784 evlist->mmap[idx].base = mmap(NULL, evlist->mmap_len, mp->prot, 784 evlist->mmap[idx].base = mmap(NULL, evlist->mmap_len, mp->prot,
785 MAP_SHARED, fd, 0); 785 MAP_SHARED, fd, 0);
786 if (evlist->mmap[idx].base == MAP_FAILED) { 786 if (evlist->mmap[idx].base == MAP_FAILED) {
787 pr_debug2("failed to mmap perf event ring buffer, error %d\n", 787 pr_debug2("failed to mmap perf event ring buffer, error %d\n",
788 errno); 788 errno);
789 evlist->mmap[idx].base = NULL; 789 evlist->mmap[idx].base = NULL;
790 return -1; 790 return -1;
791 } 791 }
792 792
793 return 0; 793 return 0;
794 } 794 }
795 795
796 static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx, 796 static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx,
797 struct mmap_params *mp, int cpu, 797 struct mmap_params *mp, int cpu,
798 int thread, int *output) 798 int thread, int *output)
799 { 799 {
800 struct perf_evsel *evsel; 800 struct perf_evsel *evsel;
801 801
802 evlist__for_each(evlist, evsel) { 802 evlist__for_each(evlist, evsel) {
803 int fd; 803 int fd;
804 804
805 if (evsel->system_wide && thread) 805 if (evsel->system_wide && thread)
806 continue; 806 continue;
807 807
808 fd = FD(evsel, cpu, thread); 808 fd = FD(evsel, cpu, thread);
809 809
810 if (*output == -1) { 810 if (*output == -1) {
811 *output = fd; 811 *output = fd;
812 if (__perf_evlist__mmap(evlist, idx, mp, *output) < 0) 812 if (__perf_evlist__mmap(evlist, idx, mp, *output) < 0)
813 return -1; 813 return -1;
814 } else { 814 } else {
815 if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, *output) != 0) 815 if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, *output) != 0)
816 return -1; 816 return -1;
817 817
818 perf_evlist__mmap_get(evlist, idx); 818 perf_evlist__mmap_get(evlist, idx);
819 } 819 }
820 820
821 /* 821 /*
822 * The system_wide flag causes a selected event to be opened 822 * The system_wide flag causes a selected event to be opened
823 * always without a pid. Consequently it will never get a 823 * always without a pid. Consequently it will never get a
824 * POLLHUP, but it is used for tracking in combination with 824 * POLLHUP, but it is used for tracking in combination with
825 * other events, so it should not need to be polled anyway. 825 * other events, so it should not need to be polled anyway.
826 * Therefore don't add it for polling. 826 * Therefore don't add it for polling.
827 */ 827 */
828 if (!evsel->system_wide && 828 if (!evsel->system_wide &&
829 __perf_evlist__add_pollfd(evlist, fd, idx) < 0) { 829 __perf_evlist__add_pollfd(evlist, fd, idx) < 0) {
830 perf_evlist__mmap_put(evlist, idx); 830 perf_evlist__mmap_put(evlist, idx);
831 return -1; 831 return -1;
832 } 832 }
833 833
834 if (evsel->attr.read_format & PERF_FORMAT_ID) { 834 if (evsel->attr.read_format & PERF_FORMAT_ID) {
835 if (perf_evlist__id_add_fd(evlist, evsel, cpu, thread, 835 if (perf_evlist__id_add_fd(evlist, evsel, cpu, thread,
836 fd) < 0) 836 fd) < 0)
837 return -1; 837 return -1;
838 perf_evlist__set_sid_idx(evlist, evsel, idx, cpu, 838 perf_evlist__set_sid_idx(evlist, evsel, idx, cpu,
839 thread); 839 thread);
840 } 840 }
841 } 841 }
842 842
843 return 0; 843 return 0;
844 } 844 }
845 845
846 static int perf_evlist__mmap_per_cpu(struct perf_evlist *evlist, 846 static int perf_evlist__mmap_per_cpu(struct perf_evlist *evlist,
847 struct mmap_params *mp) 847 struct mmap_params *mp)
848 { 848 {
849 int cpu, thread; 849 int cpu, thread;
850 int nr_cpus = cpu_map__nr(evlist->cpus); 850 int nr_cpus = cpu_map__nr(evlist->cpus);
851 int nr_threads = thread_map__nr(evlist->threads); 851 int nr_threads = thread_map__nr(evlist->threads);
852 852
853 pr_debug2("perf event ring buffer mmapped per cpu\n"); 853 pr_debug2("perf event ring buffer mmapped per cpu\n");
854 for (cpu = 0; cpu < nr_cpus; cpu++) { 854 for (cpu = 0; cpu < nr_cpus; cpu++) {
855 int output = -1; 855 int output = -1;
856 856
857 for (thread = 0; thread < nr_threads; thread++) { 857 for (thread = 0; thread < nr_threads; thread++) {
858 if (perf_evlist__mmap_per_evsel(evlist, cpu, mp, cpu, 858 if (perf_evlist__mmap_per_evsel(evlist, cpu, mp, cpu,
859 thread, &output)) 859 thread, &output))
860 goto out_unmap; 860 goto out_unmap;
861 } 861 }
862 } 862 }
863 863
864 return 0; 864 return 0;
865 865
866 out_unmap: 866 out_unmap:
867 for (cpu = 0; cpu < nr_cpus; cpu++) 867 for (cpu = 0; cpu < nr_cpus; cpu++)
868 __perf_evlist__munmap(evlist, cpu); 868 __perf_evlist__munmap(evlist, cpu);
869 return -1; 869 return -1;
870 } 870 }
871 871
872 static int perf_evlist__mmap_per_thread(struct perf_evlist *evlist, 872 static int perf_evlist__mmap_per_thread(struct perf_evlist *evlist,
873 struct mmap_params *mp) 873 struct mmap_params *mp)
874 { 874 {
875 int thread; 875 int thread;
876 int nr_threads = thread_map__nr(evlist->threads); 876 int nr_threads = thread_map__nr(evlist->threads);
877 877
878 pr_debug2("perf event ring buffer mmapped per thread\n"); 878 pr_debug2("perf event ring buffer mmapped per thread\n");
879 for (thread = 0; thread < nr_threads; thread++) { 879 for (thread = 0; thread < nr_threads; thread++) {
880 int output = -1; 880 int output = -1;
881 881
882 if (perf_evlist__mmap_per_evsel(evlist, thread, mp, 0, thread, 882 if (perf_evlist__mmap_per_evsel(evlist, thread, mp, 0, thread,
883 &output)) 883 &output))
884 goto out_unmap; 884 goto out_unmap;
885 } 885 }
886 886
887 return 0; 887 return 0;
888 888
889 out_unmap: 889 out_unmap:
890 for (thread = 0; thread < nr_threads; thread++) 890 for (thread = 0; thread < nr_threads; thread++)
891 __perf_evlist__munmap(evlist, thread); 891 __perf_evlist__munmap(evlist, thread);
892 return -1; 892 return -1;
893 } 893 }
894 894
895 static size_t perf_evlist__mmap_size(unsigned long pages) 895 static size_t perf_evlist__mmap_size(unsigned long pages)
896 { 896 {
897 if (pages == UINT_MAX) { 897 if (pages == UINT_MAX) {
898 int max; 898 int max;
899 899
900 if (sysctl__read_int("kernel/perf_event_mlock_kb", &max) < 0) { 900 if (sysctl__read_int("kernel/perf_event_mlock_kb", &max) < 0) {
901 /* 901 /*
902 * Pick a once upon a time good value, i.e. things look 902 * Pick a once upon a time good value, i.e. things look
903 * strange since we can't read a sysctl value, but lets not 903 * strange since we can't read a sysctl value, but lets not
904 * die yet... 904 * die yet...
905 */ 905 */
906 max = 512; 906 max = 512;
907 } else { 907 } else {
908 max -= (page_size / 1024); 908 max -= (page_size / 1024);
909 } 909 }
910 910
911 pages = (max * 1024) / page_size; 911 pages = (max * 1024) / page_size;
912 if (!is_power_of_2(pages)) 912 if (!is_power_of_2(pages))
913 pages = rounddown_pow_of_two(pages); 913 pages = rounddown_pow_of_two(pages);
914 } else if (!is_power_of_2(pages)) 914 } else if (!is_power_of_2(pages))
915 return 0; 915 return 0;
916 916
917 return (pages + 1) * page_size; 917 return (pages + 1) * page_size;
918 } 918 }
919 919
920 static long parse_pages_arg(const char *str, unsigned long min, 920 static long parse_pages_arg(const char *str, unsigned long min,
921 unsigned long max) 921 unsigned long max)
922 { 922 {
923 unsigned long pages, val; 923 unsigned long pages, val;
924 static struct parse_tag tags[] = { 924 static struct parse_tag tags[] = {
925 { .tag = 'B', .mult = 1 }, 925 { .tag = 'B', .mult = 1 },
926 { .tag = 'K', .mult = 1 << 10 }, 926 { .tag = 'K', .mult = 1 << 10 },
927 { .tag = 'M', .mult = 1 << 20 }, 927 { .tag = 'M', .mult = 1 << 20 },
928 { .tag = 'G', .mult = 1 << 30 }, 928 { .tag = 'G', .mult = 1 << 30 },
929 { .tag = 0 }, 929 { .tag = 0 },
930 }; 930 };
931 931
932 if (str == NULL) 932 if (str == NULL)
933 return -EINVAL; 933 return -EINVAL;
934 934
935 val = parse_tag_value(str, tags); 935 val = parse_tag_value(str, tags);
936 if (val != (unsigned long) -1) { 936 if (val != (unsigned long) -1) {
937 /* we got file size value */ 937 /* we got file size value */
938 pages = PERF_ALIGN(val, page_size) / page_size; 938 pages = PERF_ALIGN(val, page_size) / page_size;
939 } else { 939 } else {
940 /* we got pages count value */ 940 /* we got pages count value */
941 char *eptr; 941 char *eptr;
942 pages = strtoul(str, &eptr, 10); 942 pages = strtoul(str, &eptr, 10);
943 if (*eptr != '\0') 943 if (*eptr != '\0')
944 return -EINVAL; 944 return -EINVAL;
945 } 945 }
946 946
947 if (pages == 0 && min == 0) { 947 if (pages == 0 && min == 0) {
948 /* leave number of pages at 0 */ 948 /* leave number of pages at 0 */
949 } else if (!is_power_of_2(pages)) { 949 } else if (!is_power_of_2(pages)) {
950 /* round pages up to next power of 2 */ 950 /* round pages up to next power of 2 */
951 pages = roundup_pow_of_two(pages); 951 pages = roundup_pow_of_two(pages);
952 if (!pages) 952 if (!pages)
953 return -EINVAL; 953 return -EINVAL;
954 pr_info("rounding mmap pages size to %lu bytes (%lu pages)\n", 954 pr_info("rounding mmap pages size to %lu bytes (%lu pages)\n",
955 pages * page_size, pages); 955 pages * page_size, pages);
956 } 956 }
957 957
958 if (pages > max) 958 if (pages > max)
959 return -EINVAL; 959 return -EINVAL;
960 960
961 return pages; 961 return pages;
962 } 962 }
963 963
964 int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str, 964 int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str,
965 int unset __maybe_unused) 965 int unset __maybe_unused)
966 { 966 {
967 unsigned int *mmap_pages = opt->value; 967 unsigned int *mmap_pages = opt->value;
968 unsigned long max = UINT_MAX; 968 unsigned long max = UINT_MAX;
969 long pages; 969 long pages;
970 970
971 if (max > SIZE_MAX / page_size) 971 if (max > SIZE_MAX / page_size)
972 max = SIZE_MAX / page_size; 972 max = SIZE_MAX / page_size;
973 973
974 pages = parse_pages_arg(str, 1, max); 974 pages = parse_pages_arg(str, 1, max);
975 if (pages < 0) { 975 if (pages < 0) {
976 pr_err("Invalid argument for --mmap_pages/-m\n"); 976 pr_err("Invalid argument for --mmap_pages/-m\n");
977 return -1; 977 return -1;
978 } 978 }
979 979
980 *mmap_pages = pages; 980 *mmap_pages = pages;
981 return 0; 981 return 0;
982 } 982 }
983 983
984 /** 984 /**
985 * perf_evlist__mmap - Create mmaps to receive events. 985 * perf_evlist__mmap - Create mmaps to receive events.
986 * @evlist: list of events 986 * @evlist: list of events
987 * @pages: map length in pages 987 * @pages: map length in pages
988 * @overwrite: overwrite older events? 988 * @overwrite: overwrite older events?
989 * 989 *
990 * If @overwrite is %false the user needs to signal event consumption using 990 * If @overwrite is %false the user needs to signal event consumption using
991 * perf_mmap__write_tail(). Using perf_evlist__mmap_read() does this 991 * perf_mmap__write_tail(). Using perf_evlist__mmap_read() does this
992 * automatically. 992 * automatically.
993 * 993 *
994 * Return: %0 on success, negative error code otherwise. 994 * Return: %0 on success, negative error code otherwise.
995 */ 995 */
996 int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages, 996 int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
997 bool overwrite) 997 bool overwrite)
998 { 998 {
999 struct perf_evsel *evsel; 999 struct perf_evsel *evsel;
1000 const struct cpu_map *cpus = evlist->cpus; 1000 const struct cpu_map *cpus = evlist->cpus;
1001 const struct thread_map *threads = evlist->threads; 1001 const struct thread_map *threads = evlist->threads;
1002 struct mmap_params mp = { 1002 struct mmap_params mp = {
1003 .prot = PROT_READ | (overwrite ? 0 : PROT_WRITE), 1003 .prot = PROT_READ | (overwrite ? 0 : PROT_WRITE),
1004 }; 1004 };
1005 1005
1006 if (evlist->mmap == NULL && perf_evlist__alloc_mmap(evlist) < 0) 1006 if (evlist->mmap == NULL && perf_evlist__alloc_mmap(evlist) < 0)
1007 return -ENOMEM; 1007 return -ENOMEM;
1008 1008
1009 if (evlist->pollfd.entries == NULL && perf_evlist__alloc_pollfd(evlist) < 0) 1009 if (evlist->pollfd.entries == NULL && perf_evlist__alloc_pollfd(evlist) < 0)
1010 return -ENOMEM; 1010 return -ENOMEM;
1011 1011
1012 evlist->overwrite = overwrite; 1012 evlist->overwrite = overwrite;
1013 evlist->mmap_len = perf_evlist__mmap_size(pages); 1013 evlist->mmap_len = perf_evlist__mmap_size(pages);
1014 pr_debug("mmap size %zuB\n", evlist->mmap_len); 1014 pr_debug("mmap size %zuB\n", evlist->mmap_len);
1015 mp.mask = evlist->mmap_len - page_size - 1; 1015 mp.mask = evlist->mmap_len - page_size - 1;
1016 1016
1017 evlist__for_each(evlist, evsel) { 1017 evlist__for_each(evlist, evsel) {
1018 if ((evsel->attr.read_format & PERF_FORMAT_ID) && 1018 if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
1019 evsel->sample_id == NULL && 1019 evsel->sample_id == NULL &&
1020 perf_evsel__alloc_id(evsel, cpu_map__nr(cpus), threads->nr) < 0) 1020 perf_evsel__alloc_id(evsel, cpu_map__nr(cpus), threads->nr) < 0)
1021 return -ENOMEM; 1021 return -ENOMEM;
1022 } 1022 }
1023 1023
1024 if (cpu_map__empty(cpus)) 1024 if (cpu_map__empty(cpus))
1025 return perf_evlist__mmap_per_thread(evlist, &mp); 1025 return perf_evlist__mmap_per_thread(evlist, &mp);
1026 1026
1027 return perf_evlist__mmap_per_cpu(evlist, &mp); 1027 return perf_evlist__mmap_per_cpu(evlist, &mp);
1028 } 1028 }
1029 1029
1030 int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target) 1030 int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target)
1031 { 1031 {
1032 evlist->threads = thread_map__new_str(target->pid, target->tid, 1032 evlist->threads = thread_map__new_str(target->pid, target->tid,
1033 target->uid); 1033 target->uid);
1034 1034
1035 if (evlist->threads == NULL) 1035 if (evlist->threads == NULL)
1036 return -1; 1036 return -1;
1037 1037
1038 if (target__uses_dummy_map(target)) 1038 if (target__uses_dummy_map(target))
1039 evlist->cpus = cpu_map__dummy_new(); 1039 evlist->cpus = cpu_map__dummy_new();
1040 else 1040 else
1041 evlist->cpus = cpu_map__new(target->cpu_list); 1041 evlist->cpus = cpu_map__new(target->cpu_list);
1042 1042
1043 if (evlist->cpus == NULL) 1043 if (evlist->cpus == NULL)
1044 goto out_delete_threads; 1044 goto out_delete_threads;
1045 1045
1046 return 0; 1046 return 0;
1047 1047
1048 out_delete_threads: 1048 out_delete_threads:
1049 thread_map__delete(evlist->threads); 1049 thread_map__delete(evlist->threads);
1050 evlist->threads = NULL; 1050 evlist->threads = NULL;
1051 return -1; 1051 return -1;
1052 } 1052 }
1053 1053
1054 int perf_evlist__apply_filters(struct perf_evlist *evlist) 1054 int perf_evlist__apply_filters(struct perf_evlist *evlist)
1055 { 1055 {
1056 struct perf_evsel *evsel; 1056 struct perf_evsel *evsel;
1057 int err = 0; 1057 int err = 0;
1058 const int ncpus = cpu_map__nr(evlist->cpus), 1058 const int ncpus = cpu_map__nr(evlist->cpus),
1059 nthreads = thread_map__nr(evlist->threads); 1059 nthreads = thread_map__nr(evlist->threads);
1060 1060
1061 evlist__for_each(evlist, evsel) { 1061 evlist__for_each(evlist, evsel) {
1062 if (evsel->filter == NULL) 1062 if (evsel->filter == NULL)
1063 continue; 1063 continue;
1064 1064
1065 err = perf_evsel__set_filter(evsel, ncpus, nthreads, evsel->filter); 1065 err = perf_evsel__set_filter(evsel, ncpus, nthreads, evsel->filter);
1066 if (err) 1066 if (err)
1067 break; 1067 break;
1068 } 1068 }
1069 1069
1070 return err; 1070 return err;
1071 } 1071 }
1072 1072
1073 int perf_evlist__set_filter(struct perf_evlist *evlist, const char *filter) 1073 int perf_evlist__set_filter(struct perf_evlist *evlist, const char *filter)
1074 { 1074 {
1075 struct perf_evsel *evsel; 1075 struct perf_evsel *evsel;
1076 int err = 0; 1076 int err = 0;
1077 const int ncpus = cpu_map__nr(evlist->cpus), 1077 const int ncpus = cpu_map__nr(evlist->cpus),
1078 nthreads = thread_map__nr(evlist->threads); 1078 nthreads = thread_map__nr(evlist->threads);
1079 1079
1080 evlist__for_each(evlist, evsel) { 1080 evlist__for_each(evlist, evsel) {
1081 err = perf_evsel__set_filter(evsel, ncpus, nthreads, filter); 1081 err = perf_evsel__set_filter(evsel, ncpus, nthreads, filter);
1082 if (err) 1082 if (err)
1083 break; 1083 break;
1084 } 1084 }
1085 1085
1086 return err; 1086 return err;
1087 } 1087 }
1088 1088
1089 bool perf_evlist__valid_sample_type(struct perf_evlist *evlist) 1089 bool perf_evlist__valid_sample_type(struct perf_evlist *evlist)
1090 { 1090 {
1091 struct perf_evsel *pos; 1091 struct perf_evsel *pos;
1092 1092
1093 if (evlist->nr_entries == 1) 1093 if (evlist->nr_entries == 1)
1094 return true; 1094 return true;
1095 1095
1096 if (evlist->id_pos < 0 || evlist->is_pos < 0) 1096 if (evlist->id_pos < 0 || evlist->is_pos < 0)
1097 return false; 1097 return false;
1098 1098
1099 evlist__for_each(evlist, pos) { 1099 evlist__for_each(evlist, pos) {
1100 if (pos->id_pos != evlist->id_pos || 1100 if (pos->id_pos != evlist->id_pos ||
1101 pos->is_pos != evlist->is_pos) 1101 pos->is_pos != evlist->is_pos)
1102 return false; 1102 return false;
1103 } 1103 }
1104 1104
1105 return true; 1105 return true;
1106 } 1106 }
1107 1107
1108 u64 __perf_evlist__combined_sample_type(struct perf_evlist *evlist) 1108 u64 __perf_evlist__combined_sample_type(struct perf_evlist *evlist)
1109 { 1109 {
1110 struct perf_evsel *evsel; 1110 struct perf_evsel *evsel;
1111 1111
1112 if (evlist->combined_sample_type) 1112 if (evlist->combined_sample_type)
1113 return evlist->combined_sample_type; 1113 return evlist->combined_sample_type;
1114 1114
1115 evlist__for_each(evlist, evsel) 1115 evlist__for_each(evlist, evsel)
1116 evlist->combined_sample_type |= evsel->attr.sample_type; 1116 evlist->combined_sample_type |= evsel->attr.sample_type;
1117 1117
1118 return evlist->combined_sample_type; 1118 return evlist->combined_sample_type;
1119 } 1119 }
1120 1120
1121 u64 perf_evlist__combined_sample_type(struct perf_evlist *evlist) 1121 u64 perf_evlist__combined_sample_type(struct perf_evlist *evlist)
1122 { 1122 {
1123 evlist->combined_sample_type = 0; 1123 evlist->combined_sample_type = 0;
1124 return __perf_evlist__combined_sample_type(evlist); 1124 return __perf_evlist__combined_sample_type(evlist);
1125 } 1125 }
1126 1126
1127 bool perf_evlist__valid_read_format(struct perf_evlist *evlist) 1127 bool perf_evlist__valid_read_format(struct perf_evlist *evlist)
1128 { 1128 {
1129 struct perf_evsel *first = perf_evlist__first(evlist), *pos = first; 1129 struct perf_evsel *first = perf_evlist__first(evlist), *pos = first;
1130 u64 read_format = first->attr.read_format; 1130 u64 read_format = first->attr.read_format;
1131 u64 sample_type = first->attr.sample_type; 1131 u64 sample_type = first->attr.sample_type;
1132 1132
1133 evlist__for_each(evlist, pos) { 1133 evlist__for_each(evlist, pos) {
1134 if (read_format != pos->attr.read_format) 1134 if (read_format != pos->attr.read_format)
1135 return false; 1135 return false;
1136 } 1136 }
1137 1137
1138 /* PERF_SAMPLE_READ imples PERF_FORMAT_ID. */ 1138 /* PERF_SAMPLE_READ imples PERF_FORMAT_ID. */
1139 if ((sample_type & PERF_SAMPLE_READ) && 1139 if ((sample_type & PERF_SAMPLE_READ) &&
1140 !(read_format & PERF_FORMAT_ID)) { 1140 !(read_format & PERF_FORMAT_ID)) {
1141 return false; 1141 return false;
1142 } 1142 }
1143 1143
1144 return true; 1144 return true;
1145 } 1145 }
1146 1146
1147 u64 perf_evlist__read_format(struct perf_evlist *evlist) 1147 u64 perf_evlist__read_format(struct perf_evlist *evlist)
1148 { 1148 {
1149 struct perf_evsel *first = perf_evlist__first(evlist); 1149 struct perf_evsel *first = perf_evlist__first(evlist);
1150 return first->attr.read_format; 1150 return first->attr.read_format;
1151 } 1151 }
1152 1152
1153 u16 perf_evlist__id_hdr_size(struct perf_evlist *evlist) 1153 u16 perf_evlist__id_hdr_size(struct perf_evlist *evlist)
1154 { 1154 {
1155 struct perf_evsel *first = perf_evlist__first(evlist); 1155 struct perf_evsel *first = perf_evlist__first(evlist);
1156 struct perf_sample *data; 1156 struct perf_sample *data;
1157 u64 sample_type; 1157 u64 sample_type;
1158 u16 size = 0; 1158 u16 size = 0;
1159 1159
1160 if (!first->attr.sample_id_all) 1160 if (!first->attr.sample_id_all)
1161 goto out; 1161 goto out;
1162 1162
1163 sample_type = first->attr.sample_type; 1163 sample_type = first->attr.sample_type;
1164 1164
1165 if (sample_type & PERF_SAMPLE_TID) 1165 if (sample_type & PERF_SAMPLE_TID)
1166 size += sizeof(data->tid) * 2; 1166 size += sizeof(data->tid) * 2;
1167 1167
1168 if (sample_type & PERF_SAMPLE_TIME) 1168 if (sample_type & PERF_SAMPLE_TIME)
1169 size += sizeof(data->time); 1169 size += sizeof(data->time);
1170 1170
1171 if (sample_type & PERF_SAMPLE_ID) 1171 if (sample_type & PERF_SAMPLE_ID)
1172 size += sizeof(data->id); 1172 size += sizeof(data->id);
1173 1173
1174 if (sample_type & PERF_SAMPLE_STREAM_ID) 1174 if (sample_type & PERF_SAMPLE_STREAM_ID)
1175 size += sizeof(data->stream_id); 1175 size += sizeof(data->stream_id);
1176 1176
1177 if (sample_type & PERF_SAMPLE_CPU) 1177 if (sample_type & PERF_SAMPLE_CPU)
1178 size += sizeof(data->cpu) * 2; 1178 size += sizeof(data->cpu) * 2;
1179 1179
1180 if (sample_type & PERF_SAMPLE_IDENTIFIER) 1180 if (sample_type & PERF_SAMPLE_IDENTIFIER)
1181 size += sizeof(data->id); 1181 size += sizeof(data->id);
1182 out: 1182 out:
1183 return size; 1183 return size;
1184 } 1184 }
1185 1185
1186 bool perf_evlist__valid_sample_id_all(struct perf_evlist *evlist) 1186 bool perf_evlist__valid_sample_id_all(struct perf_evlist *evlist)
1187 { 1187 {
1188 struct perf_evsel *first = perf_evlist__first(evlist), *pos = first; 1188 struct perf_evsel *first = perf_evlist__first(evlist), *pos = first;
1189 1189
1190 evlist__for_each_continue(evlist, pos) { 1190 evlist__for_each_continue(evlist, pos) {
1191 if (first->attr.sample_id_all != pos->attr.sample_id_all) 1191 if (first->attr.sample_id_all != pos->attr.sample_id_all)
1192 return false; 1192 return false;
1193 } 1193 }
1194 1194
1195 return true; 1195 return true;
1196 } 1196 }
1197 1197
1198 bool perf_evlist__sample_id_all(struct perf_evlist *evlist) 1198 bool perf_evlist__sample_id_all(struct perf_evlist *evlist)
1199 { 1199 {
1200 struct perf_evsel *first = perf_evlist__first(evlist); 1200 struct perf_evsel *first = perf_evlist__first(evlist);
1201 return first->attr.sample_id_all; 1201 return first->attr.sample_id_all;
1202 } 1202 }
1203 1203
1204 void perf_evlist__set_selected(struct perf_evlist *evlist, 1204 void perf_evlist__set_selected(struct perf_evlist *evlist,
1205 struct perf_evsel *evsel) 1205 struct perf_evsel *evsel)
1206 { 1206 {
1207 evlist->selected = evsel; 1207 evlist->selected = evsel;
1208 } 1208 }
1209 1209
1210 void perf_evlist__close(struct perf_evlist *evlist) 1210 void perf_evlist__close(struct perf_evlist *evlist)
1211 { 1211 {
1212 struct perf_evsel *evsel; 1212 struct perf_evsel *evsel;
1213 int ncpus = cpu_map__nr(evlist->cpus); 1213 int ncpus = cpu_map__nr(evlist->cpus);
1214 int nthreads = thread_map__nr(evlist->threads); 1214 int nthreads = thread_map__nr(evlist->threads);
1215 int n; 1215 int n;
1216 1216
1217 evlist__for_each_reverse(evlist, evsel) { 1217 evlist__for_each_reverse(evlist, evsel) {
1218 n = evsel->cpus ? evsel->cpus->nr : ncpus; 1218 n = evsel->cpus ? evsel->cpus->nr : ncpus;
1219 perf_evsel__close(evsel, n, nthreads); 1219 perf_evsel__close(evsel, n, nthreads);
1220 } 1220 }
1221 } 1221 }
1222 1222
1223 static int perf_evlist__create_syswide_maps(struct perf_evlist *evlist) 1223 static int perf_evlist__create_syswide_maps(struct perf_evlist *evlist)
1224 { 1224 {
1225 int err = -ENOMEM; 1225 int err = -ENOMEM;
1226 1226
1227 /* 1227 /*
1228 * Try reading /sys/devices/system/cpu/online to get 1228 * Try reading /sys/devices/system/cpu/online to get
1229 * an all cpus map. 1229 * an all cpus map.
1230 * 1230 *
1231 * FIXME: -ENOMEM is the best we can do here, the cpu_map 1231 * FIXME: -ENOMEM is the best we can do here, the cpu_map
1232 * code needs an overhaul to properly forward the 1232 * code needs an overhaul to properly forward the
1233 * error, and we may not want to do that fallback to a 1233 * error, and we may not want to do that fallback to a
1234 * default cpu identity map :-\ 1234 * default cpu identity map :-\
1235 */ 1235 */
1236 evlist->cpus = cpu_map__new(NULL); 1236 evlist->cpus = cpu_map__new(NULL);
1237 if (evlist->cpus == NULL) 1237 if (evlist->cpus == NULL)
1238 goto out; 1238 goto out;
1239 1239
1240 evlist->threads = thread_map__new_dummy(); 1240 evlist->threads = thread_map__new_dummy();
1241 if (evlist->threads == NULL) 1241 if (evlist->threads == NULL)
1242 goto out_free_cpus; 1242 goto out_free_cpus;
1243 1243
1244 err = 0; 1244 err = 0;
1245 out: 1245 out:
1246 return err; 1246 return err;
1247 out_free_cpus: 1247 out_free_cpus:
1248 cpu_map__delete(evlist->cpus); 1248 cpu_map__delete(evlist->cpus);
1249 evlist->cpus = NULL; 1249 evlist->cpus = NULL;
1250 goto out; 1250 goto out;
1251 } 1251 }
1252 1252
1253 int perf_evlist__open(struct perf_evlist *evlist) 1253 int perf_evlist__open(struct perf_evlist *evlist)
1254 { 1254 {
1255 struct perf_evsel *evsel; 1255 struct perf_evsel *evsel;
1256 int err; 1256 int err;
1257 1257
1258 /* 1258 /*
1259 * Default: one fd per CPU, all threads, aka systemwide 1259 * Default: one fd per CPU, all threads, aka systemwide
1260 * as sys_perf_event_open(cpu = -1, thread = -1) is EINVAL 1260 * as sys_perf_event_open(cpu = -1, thread = -1) is EINVAL
1261 */ 1261 */
1262 if (evlist->threads == NULL && evlist->cpus == NULL) { 1262 if (evlist->threads == NULL && evlist->cpus == NULL) {
1263 err = perf_evlist__create_syswide_maps(evlist); 1263 err = perf_evlist__create_syswide_maps(evlist);
1264 if (err < 0) 1264 if (err < 0)
1265 goto out_err; 1265 goto out_err;
1266 } 1266 }
1267 1267
1268 perf_evlist__update_id_pos(evlist); 1268 perf_evlist__update_id_pos(evlist);
1269 1269
1270 evlist__for_each(evlist, evsel) { 1270 evlist__for_each(evlist, evsel) {
1271 err = perf_evsel__open(evsel, evlist->cpus, evlist->threads); 1271 err = perf_evsel__open(evsel, evlist->cpus, evlist->threads);
1272 if (err < 0) 1272 if (err < 0)
1273 goto out_err; 1273 goto out_err;
1274 } 1274 }
1275 1275
1276 return 0; 1276 return 0;
1277 out_err: 1277 out_err:
1278 perf_evlist__close(evlist); 1278 perf_evlist__close(evlist);
1279 errno = -err; 1279 errno = -err;
1280 return err; 1280 return err;
1281 } 1281 }
1282 1282
1283 int perf_evlist__prepare_workload(struct perf_evlist *evlist, struct target *target, 1283 int perf_evlist__prepare_workload(struct perf_evlist *evlist, struct target *target,
1284 const char *argv[], bool pipe_output, 1284 const char *argv[], bool pipe_output,
1285 void (*exec_error)(int signo, siginfo_t *info, void *ucontext)) 1285 void (*exec_error)(int signo, siginfo_t *info, void *ucontext))
1286 { 1286 {
1287 int child_ready_pipe[2], go_pipe[2]; 1287 int child_ready_pipe[2], go_pipe[2];
1288 char bf; 1288 char bf;
1289 1289
1290 if (pipe(child_ready_pipe) < 0) { 1290 if (pipe(child_ready_pipe) < 0) {
1291 perror("failed to create 'ready' pipe"); 1291 perror("failed to create 'ready' pipe");
1292 return -1; 1292 return -1;
1293 } 1293 }
1294 1294
1295 if (pipe(go_pipe) < 0) { 1295 if (pipe(go_pipe) < 0) {
1296 perror("failed to create 'go' pipe"); 1296 perror("failed to create 'go' pipe");
1297 goto out_close_ready_pipe; 1297 goto out_close_ready_pipe;
1298 } 1298 }
1299 1299
1300 evlist->workload.pid = fork(); 1300 evlist->workload.pid = fork();
1301 if (evlist->workload.pid < 0) { 1301 if (evlist->workload.pid < 0) {
1302 perror("failed to fork"); 1302 perror("failed to fork");
1303 goto out_close_pipes; 1303 goto out_close_pipes;
1304 } 1304 }
1305 1305
1306 if (!evlist->workload.pid) { 1306 if (!evlist->workload.pid) {
1307 int ret; 1307 int ret;
1308 1308
1309 if (pipe_output) 1309 if (pipe_output)
1310 dup2(2, 1); 1310 dup2(2, 1);
1311 1311
1312 signal(SIGTERM, SIG_DFL); 1312 signal(SIGTERM, SIG_DFL);
1313 1313
1314 close(child_ready_pipe[0]); 1314 close(child_ready_pipe[0]);
1315 close(go_pipe[1]); 1315 close(go_pipe[1]);
1316 fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC); 1316 fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC);
1317 1317
1318 /* 1318 /*
1319 * Tell the parent we're ready to go 1319 * Tell the parent we're ready to go
1320 */ 1320 */
1321 close(child_ready_pipe[1]); 1321 close(child_ready_pipe[1]);
1322 1322
1323 /* 1323 /*
1324 * Wait until the parent tells us to go. 1324 * Wait until the parent tells us to go.
1325 */ 1325 */
1326 ret = read(go_pipe[0], &bf, 1); 1326 ret = read(go_pipe[0], &bf, 1);
1327 /* 1327 /*
1328 * The parent will ask for the execvp() to be performed by 1328 * The parent will ask for the execvp() to be performed by
1329 * writing exactly one byte, in workload.cork_fd, usually via 1329 * writing exactly one byte, in workload.cork_fd, usually via
1330 * perf_evlist__start_workload(). 1330 * perf_evlist__start_workload().
1331 * 1331 *
1332 * For cancelling the workload without actuallin running it, 1332 * For cancelling the workload without actuallin running it,
1333 * the parent will just close workload.cork_fd, without writing 1333 * the parent will just close workload.cork_fd, without writing
1334 * anything, i.e. read will return zero and we just exit() 1334 * anything, i.e. read will return zero and we just exit()
1335 * here. 1335 * here.
1336 */ 1336 */
1337 if (ret != 1) { 1337 if (ret != 1) {
1338 if (ret == -1) 1338 if (ret == -1)
1339 perror("unable to read pipe"); 1339 perror("unable to read pipe");
1340 exit(ret); 1340 exit(ret);
1341 } 1341 }
1342 1342
1343 execvp(argv[0], (char **)argv); 1343 execvp(argv[0], (char **)argv);
1344 1344
1345 if (exec_error) { 1345 if (exec_error) {
1346 union sigval val; 1346 union sigval val;
1347 1347
1348 val.sival_int = errno; 1348 val.sival_int = errno;
1349 if (sigqueue(getppid(), SIGUSR1, val)) 1349 if (sigqueue(getppid(), SIGUSR1, val))
1350 perror(argv[0]); 1350 perror(argv[0]);
1351 } else 1351 } else
1352 perror(argv[0]); 1352 perror(argv[0]);
1353 exit(-1); 1353 exit(-1);
1354 } 1354 }
1355 1355
1356 if (exec_error) { 1356 if (exec_error) {
1357 struct sigaction act = { 1357 struct sigaction act = {
1358 .sa_flags = SA_SIGINFO, 1358 .sa_flags = SA_SIGINFO,
1359 .sa_sigaction = exec_error, 1359 .sa_sigaction = exec_error,
1360 }; 1360 };
1361 sigaction(SIGUSR1, &act, NULL); 1361 sigaction(SIGUSR1, &act, NULL);
1362 } 1362 }
1363 1363
1364 if (target__none(target)) { 1364 if (target__none(target)) {
1365 if (evlist->threads == NULL) { 1365 if (evlist->threads == NULL) {
1366 fprintf(stderr, "FATAL: evlist->threads need to be set at this point (%s:%d).\n", 1366 fprintf(stderr, "FATAL: evlist->threads need to be set at this point (%s:%d).\n",
1367 __func__, __LINE__); 1367 __func__, __LINE__);
1368 goto out_close_pipes; 1368 goto out_close_pipes;
1369 } 1369 }
1370 evlist->threads->map[0] = evlist->workload.pid; 1370 evlist->threads->map[0] = evlist->workload.pid;
1371 } 1371 }
1372 1372
1373 close(child_ready_pipe[1]); 1373 close(child_ready_pipe[1]);
1374 close(go_pipe[0]); 1374 close(go_pipe[0]);
1375 /* 1375 /*
1376 * wait for child to settle 1376 * wait for child to settle
1377 */ 1377 */
1378 if (read(child_ready_pipe[0], &bf, 1) == -1) { 1378 if (read(child_ready_pipe[0], &bf, 1) == -1) {
1379 perror("unable to read pipe"); 1379 perror("unable to read pipe");
1380 goto out_close_pipes; 1380 goto out_close_pipes;
1381 } 1381 }
1382 1382
1383 fcntl(go_pipe[1], F_SETFD, FD_CLOEXEC); 1383 fcntl(go_pipe[1], F_SETFD, FD_CLOEXEC);
1384 evlist->workload.cork_fd = go_pipe[1]; 1384 evlist->workload.cork_fd = go_pipe[1];
1385 close(child_ready_pipe[0]); 1385 close(child_ready_pipe[0]);
1386 return 0; 1386 return 0;
1387 1387
1388 out_close_pipes: 1388 out_close_pipes:
1389 close(go_pipe[0]); 1389 close(go_pipe[0]);
1390 close(go_pipe[1]); 1390 close(go_pipe[1]);
1391 out_close_ready_pipe: 1391 out_close_ready_pipe:
1392 close(child_ready_pipe[0]); 1392 close(child_ready_pipe[0]);
1393 close(child_ready_pipe[1]); 1393 close(child_ready_pipe[1]);
1394 return -1; 1394 return -1;
1395 } 1395 }
1396 1396
1397 int perf_evlist__start_workload(struct perf_evlist *evlist) 1397 int perf_evlist__start_workload(struct perf_evlist *evlist)
1398 { 1398 {
1399 if (evlist->workload.cork_fd > 0) { 1399 if (evlist->workload.cork_fd > 0) {
1400 char bf = 0; 1400 char bf = 0;
1401 int ret; 1401 int ret;
1402 /* 1402 /*
1403 * Remove the cork, let it rip! 1403 * Remove the cork, let it rip!
1404 */ 1404 */
1405 ret = write(evlist->workload.cork_fd, &bf, 1); 1405 ret = write(evlist->workload.cork_fd, &bf, 1);
1406 if (ret < 0) 1406 if (ret < 0)
1407 perror("enable to write to pipe"); 1407 perror("enable to write to pipe");
1408 1408
1409 close(evlist->workload.cork_fd); 1409 close(evlist->workload.cork_fd);
1410 return ret; 1410 return ret;
1411 } 1411 }
1412 1412
1413 return 0; 1413 return 0;
1414 } 1414 }
1415 1415
1416 int perf_evlist__parse_sample(struct perf_evlist *evlist, union perf_event *event, 1416 int perf_evlist__parse_sample(struct perf_evlist *evlist, union perf_event *event,
1417 struct perf_sample *sample) 1417 struct perf_sample *sample)
1418 { 1418 {
1419 struct perf_evsel *evsel = perf_evlist__event2evsel(evlist, event); 1419 struct perf_evsel *evsel = perf_evlist__event2evsel(evlist, event);
1420 1420
1421 if (!evsel) 1421 if (!evsel)
1422 return -EFAULT; 1422 return -EFAULT;
1423 return perf_evsel__parse_sample(evsel, event, sample); 1423 return perf_evsel__parse_sample(evsel, event, sample);
1424 } 1424 }
1425 1425
1426 size_t perf_evlist__fprintf(struct perf_evlist *evlist, FILE *fp) 1426 size_t perf_evlist__fprintf(struct perf_evlist *evlist, FILE *fp)
1427 { 1427 {
1428 struct perf_evsel *evsel; 1428 struct perf_evsel *evsel;
1429 size_t printed = 0; 1429 size_t printed = 0;
1430 1430
1431 evlist__for_each(evlist, evsel) { 1431 evlist__for_each(evlist, evsel) {
1432 printed += fprintf(fp, "%s%s", evsel->idx ? ", " : "", 1432 printed += fprintf(fp, "%s%s", evsel->idx ? ", " : "",
1433 perf_evsel__name(evsel)); 1433 perf_evsel__name(evsel));
1434 } 1434 }
1435 1435
1436 return printed + fprintf(fp, "\n"); 1436 return printed + fprintf(fp, "\n");
1437 } 1437 }
1438 1438
1439 int perf_evlist__strerror_tp(struct perf_evlist *evlist __maybe_unused, 1439 int perf_evlist__strerror_tp(struct perf_evlist *evlist __maybe_unused,
1440 int err, char *buf, size_t size) 1440 int err, char *buf, size_t size)
1441 { 1441 {
1442 char sbuf[128]; 1442 char sbuf[128];
1443 1443
1444 switch (err) { 1444 switch (err) {
1445 case ENOENT: 1445 case ENOENT:
1446 scnprintf(buf, size, "%s", 1446 scnprintf(buf, size, "%s",
1447 "Error:\tUnable to find debugfs\n" 1447 "Error:\tUnable to find debugfs\n"
1448 "Hint:\tWas your kernel was compiled with debugfs support?\n" 1448 "Hint:\tWas your kernel compiled with debugfs support?\n"
1449 "Hint:\tIs the debugfs filesystem mounted?\n" 1449 "Hint:\tIs the debugfs filesystem mounted?\n"
1450 "Hint:\tTry 'sudo mount -t debugfs nodev /sys/kernel/debug'"); 1450 "Hint:\tTry 'sudo mount -t debugfs nodev /sys/kernel/debug'");
1451 break; 1451 break;
1452 case EACCES: 1452 case EACCES:
1453 scnprintf(buf, size, 1453 scnprintf(buf, size,
1454 "Error:\tNo permissions to read %s/tracing/events/raw_syscalls\n" 1454 "Error:\tNo permissions to read %s/tracing/events/raw_syscalls\n"
1455 "Hint:\tTry 'sudo mount -o remount,mode=755 %s'\n", 1455 "Hint:\tTry 'sudo mount -o remount,mode=755 %s'\n",
1456 debugfs_mountpoint, debugfs_mountpoint); 1456 debugfs_mountpoint, debugfs_mountpoint);
1457 break; 1457 break;
1458 default: 1458 default:
1459 scnprintf(buf, size, "%s", strerror_r(err, sbuf, sizeof(sbuf))); 1459 scnprintf(buf, size, "%s", strerror_r(err, sbuf, sizeof(sbuf)));
1460 break; 1460 break;
1461 } 1461 }
1462 1462
1463 return 0; 1463 return 0;
1464 } 1464 }
1465 1465
1466 int perf_evlist__strerror_open(struct perf_evlist *evlist __maybe_unused, 1466 int perf_evlist__strerror_open(struct perf_evlist *evlist __maybe_unused,
1467 int err, char *buf, size_t size) 1467 int err, char *buf, size_t size)
1468 { 1468 {
1469 int printed, value; 1469 int printed, value;
1470 char sbuf[STRERR_BUFSIZE], *emsg = strerror_r(err, sbuf, sizeof(sbuf)); 1470 char sbuf[STRERR_BUFSIZE], *emsg = strerror_r(err, sbuf, sizeof(sbuf));
1471 1471
1472 switch (err) { 1472 switch (err) {
1473 case EACCES: 1473 case EACCES:
1474 case EPERM: 1474 case EPERM:
1475 printed = scnprintf(buf, size, 1475 printed = scnprintf(buf, size,
1476 "Error:\t%s.\n" 1476 "Error:\t%s.\n"
1477 "Hint:\tCheck /proc/sys/kernel/perf_event_paranoid setting.", emsg); 1477 "Hint:\tCheck /proc/sys/kernel/perf_event_paranoid setting.", emsg);
1478 1478
1479 value = perf_event_paranoid(); 1479 value = perf_event_paranoid();
1480 1480
1481 printed += scnprintf(buf + printed, size - printed, "\nHint:\t"); 1481 printed += scnprintf(buf + printed, size - printed, "\nHint:\t");
1482 1482
1483 if (value >= 2) { 1483 if (value >= 2) {
1484 printed += scnprintf(buf + printed, size - printed, 1484 printed += scnprintf(buf + printed, size - printed,
1485 "For your workloads it needs to be <= 1\nHint:\t"); 1485 "For your workloads it needs to be <= 1\nHint:\t");
1486 } 1486 }
1487 printed += scnprintf(buf + printed, size - printed, 1487 printed += scnprintf(buf + printed, size - printed,
1488 "For system wide tracing it needs to be set to -1.\n"); 1488 "For system wide tracing it needs to be set to -1.\n");
1489 1489
1490 printed += scnprintf(buf + printed, size - printed, 1490 printed += scnprintf(buf + printed, size - printed,
1491 "Hint:\tTry: 'sudo sh -c \"echo -1 > /proc/sys/kernel/perf_event_paranoid\"'\n" 1491 "Hint:\tTry: 'sudo sh -c \"echo -1 > /proc/sys/kernel/perf_event_paranoid\"'\n"
1492 "Hint:\tThe current value is %d.", value); 1492 "Hint:\tThe current value is %d.", value);
1493 break; 1493 break;
1494 default: 1494 default:
1495 scnprintf(buf, size, "%s", emsg); 1495 scnprintf(buf, size, "%s", emsg);
1496 break; 1496 break;
1497 } 1497 }
1498 1498
1499 return 0; 1499 return 0;
1500 } 1500 }
1501 1501
1502 int perf_evlist__strerror_mmap(struct perf_evlist *evlist, int err, char *buf, size_t size) 1502 int perf_evlist__strerror_mmap(struct perf_evlist *evlist, int err, char *buf, size_t size)
1503 { 1503 {
1504 char sbuf[STRERR_BUFSIZE], *emsg = strerror_r(err, sbuf, sizeof(sbuf)); 1504 char sbuf[STRERR_BUFSIZE], *emsg = strerror_r(err, sbuf, sizeof(sbuf));
1505 int pages_attempted = evlist->mmap_len / 1024, pages_max_per_user, printed = 0; 1505 int pages_attempted = evlist->mmap_len / 1024, pages_max_per_user, printed = 0;
1506 1506
1507 switch (err) { 1507 switch (err) {
1508 case EPERM: 1508 case EPERM:
1509 sysctl__read_int("kernel/perf_event_mlock_kb", &pages_max_per_user); 1509 sysctl__read_int("kernel/perf_event_mlock_kb", &pages_max_per_user);
1510 printed += scnprintf(buf + printed, size - printed, 1510 printed += scnprintf(buf + printed, size - printed,
1511 "Error:\t%s.\n" 1511 "Error:\t%s.\n"
1512 "Hint:\tCheck /proc/sys/kernel/perf_event_mlock_kb (%d kB) setting.\n" 1512 "Hint:\tCheck /proc/sys/kernel/perf_event_mlock_kb (%d kB) setting.\n"
1513 "Hint:\tTried using %zd kB.\n", 1513 "Hint:\tTried using %zd kB.\n",
1514 emsg, pages_max_per_user, pages_attempted); 1514 emsg, pages_max_per_user, pages_attempted);
1515 1515
1516 if (pages_attempted >= pages_max_per_user) { 1516 if (pages_attempted >= pages_max_per_user) {
1517 printed += scnprintf(buf + printed, size - printed, 1517 printed += scnprintf(buf + printed, size - printed,
1518 "Hint:\tTry 'sudo sh -c \"echo %d > /proc/sys/kernel/perf_event_mlock_kb\"', or\n", 1518 "Hint:\tTry 'sudo sh -c \"echo %d > /proc/sys/kernel/perf_event_mlock_kb\"', or\n",
1519 pages_max_per_user + pages_attempted); 1519 pages_max_per_user + pages_attempted);
1520 } 1520 }
1521 1521
1522 printed += scnprintf(buf + printed, size - printed, 1522 printed += scnprintf(buf + printed, size - printed,
1523 "Hint:\tTry using a smaller -m/--mmap-pages value."); 1523 "Hint:\tTry using a smaller -m/--mmap-pages value.");
1524 break; 1524 break;
1525 default: 1525 default:
1526 scnprintf(buf, size, "%s", emsg); 1526 scnprintf(buf, size, "%s", emsg);
1527 break; 1527 break;
1528 } 1528 }
1529 1529
1530 return 0; 1530 return 0;
1531 } 1531 }
1532 1532
1533 void perf_evlist__to_front(struct perf_evlist *evlist, 1533 void perf_evlist__to_front(struct perf_evlist *evlist,
1534 struct perf_evsel *move_evsel) 1534 struct perf_evsel *move_evsel)
1535 { 1535 {
1536 struct perf_evsel *evsel, *n; 1536 struct perf_evsel *evsel, *n;
1537 LIST_HEAD(move); 1537 LIST_HEAD(move);
1538 1538
1539 if (move_evsel == perf_evlist__first(evlist)) 1539 if (move_evsel == perf_evlist__first(evlist))
1540 return; 1540 return;
1541 1541
1542 evlist__for_each_safe(evlist, n, evsel) { 1542 evlist__for_each_safe(evlist, n, evsel) {
1543 if (evsel->leader == move_evsel->leader) 1543 if (evsel->leader == move_evsel->leader)
1544 list_move_tail(&evsel->node, &move); 1544 list_move_tail(&evsel->node, &move);
1545 } 1545 }
1546 1546
1547 list_splice(&move, &evlist->entries); 1547 list_splice(&move, &evlist->entries);
1548 } 1548 }
1549 1549
1550 void perf_evlist__set_tracking_event(struct perf_evlist *evlist, 1550 void perf_evlist__set_tracking_event(struct perf_evlist *evlist,
1551 struct perf_evsel *tracking_evsel) 1551 struct perf_evsel *tracking_evsel)
1552 { 1552 {
1553 struct perf_evsel *evsel; 1553 struct perf_evsel *evsel;
1554 1554
1555 if (tracking_evsel->tracking) 1555 if (tracking_evsel->tracking)
1556 return; 1556 return;
1557 1557
1558 evlist__for_each(evlist, evsel) { 1558 evlist__for_each(evlist, evsel) {
1559 if (evsel != tracking_evsel) 1559 if (evsel != tracking_evsel)
1560 evsel->tracking = false; 1560 evsel->tracking = false;
1561 } 1561 }
1562 1562
1563 tracking_evsel->tracking = true; 1563 tracking_evsel->tracking = true;
1564 } 1564 }
1565 1565
tools/perf/util/map.h
1 #ifndef __PERF_MAP_H 1 #ifndef __PERF_MAP_H
2 #define __PERF_MAP_H 2 #define __PERF_MAP_H
3 3
4 #include <linux/compiler.h> 4 #include <linux/compiler.h>
5 #include <linux/list.h> 5 #include <linux/list.h>
6 #include <linux/rbtree.h> 6 #include <linux/rbtree.h>
7 #include <stdio.h> 7 #include <stdio.h>
8 #include <stdbool.h> 8 #include <stdbool.h>
9 #include <linux/types.h> 9 #include <linux/types.h>
10 10
11 enum map_type { 11 enum map_type {
12 MAP__FUNCTION = 0, 12 MAP__FUNCTION = 0,
13 MAP__VARIABLE, 13 MAP__VARIABLE,
14 }; 14 };
15 15
16 #define MAP__NR_TYPES (MAP__VARIABLE + 1) 16 #define MAP__NR_TYPES (MAP__VARIABLE + 1)
17 17
18 extern const char *map_type__name[MAP__NR_TYPES]; 18 extern const char *map_type__name[MAP__NR_TYPES];
19 19
20 struct dso; 20 struct dso;
21 struct ip_callchain; 21 struct ip_callchain;
22 struct ref_reloc_sym; 22 struct ref_reloc_sym;
23 struct map_groups; 23 struct map_groups;
24 struct machine; 24 struct machine;
25 struct perf_evsel; 25 struct perf_evsel;
26 26
27 struct map { 27 struct map {
28 union { 28 union {
29 struct rb_node rb_node; 29 struct rb_node rb_node;
30 struct list_head node; 30 struct list_head node;
31 }; 31 };
32 u64 start; 32 u64 start;
33 u64 end; 33 u64 end;
34 u8 /* enum map_type */ type; 34 u8 /* enum map_type */ type;
35 bool referenced; 35 bool referenced;
36 bool erange_warned; 36 bool erange_warned;
37 u32 priv; 37 u32 priv;
38 u32 prot; 38 u32 prot;
39 u32 flags; 39 u32 flags;
40 u64 pgoff; 40 u64 pgoff;
41 u64 reloc; 41 u64 reloc;
42 u32 maj, min; /* only valid for MMAP2 record */ 42 u32 maj, min; /* only valid for MMAP2 record */
43 u64 ino; /* only valid for MMAP2 record */ 43 u64 ino; /* only valid for MMAP2 record */
44 u64 ino_generation;/* only valid for MMAP2 record */ 44 u64 ino_generation;/* only valid for MMAP2 record */
45 45
46 /* ip -> dso rip */ 46 /* ip -> dso rip */
47 u64 (*map_ip)(struct map *, u64); 47 u64 (*map_ip)(struct map *, u64);
48 /* dso rip -> ip */ 48 /* dso rip -> ip */
49 u64 (*unmap_ip)(struct map *, u64); 49 u64 (*unmap_ip)(struct map *, u64);
50 50
51 struct dso *dso; 51 struct dso *dso;
52 struct map_groups *groups; 52 struct map_groups *groups;
53 }; 53 };
54 54
55 struct kmap { 55 struct kmap {
56 struct ref_reloc_sym *ref_reloc_sym; 56 struct ref_reloc_sym *ref_reloc_sym;
57 struct map_groups *kmaps; 57 struct map_groups *kmaps;
58 }; 58 };
59 59
60 struct map_groups { 60 struct map_groups {
61 struct rb_root maps[MAP__NR_TYPES]; 61 struct rb_root maps[MAP__NR_TYPES];
62 struct list_head removed_maps[MAP__NR_TYPES]; 62 struct list_head removed_maps[MAP__NR_TYPES];
63 struct machine *machine; 63 struct machine *machine;
64 int refcnt; 64 int refcnt;
65 }; 65 };
66 66
67 struct map_groups *map_groups__new(struct machine *machine); 67 struct map_groups *map_groups__new(struct machine *machine);
68 void map_groups__delete(struct map_groups *mg); 68 void map_groups__delete(struct map_groups *mg);
69 bool map_groups__empty(struct map_groups *mg); 69 bool map_groups__empty(struct map_groups *mg);
70 70
71 static inline struct map_groups *map_groups__get(struct map_groups *mg) 71 static inline struct map_groups *map_groups__get(struct map_groups *mg)
72 { 72 {
73 ++mg->refcnt; 73 ++mg->refcnt;
74 return mg; 74 return mg;
75 } 75 }
76 76
77 void map_groups__put(struct map_groups *mg); 77 void map_groups__put(struct map_groups *mg);
78 78
79 static inline struct kmap *map__kmap(struct map *map) 79 static inline struct kmap *map__kmap(struct map *map)
80 { 80 {
81 return (struct kmap *)(map + 1); 81 return (struct kmap *)(map + 1);
82 } 82 }
83 83
84 static inline u64 map__map_ip(struct map *map, u64 ip) 84 static inline u64 map__map_ip(struct map *map, u64 ip)
85 { 85 {
86 return ip - map->start + map->pgoff; 86 return ip - map->start + map->pgoff;
87 } 87 }
88 88
89 static inline u64 map__unmap_ip(struct map *map, u64 ip) 89 static inline u64 map__unmap_ip(struct map *map, u64 ip)
90 { 90 {
91 return ip + map->start - map->pgoff; 91 return ip + map->start - map->pgoff;
92 } 92 }
93 93
94 static inline u64 identity__map_ip(struct map *map __maybe_unused, u64 ip) 94 static inline u64 identity__map_ip(struct map *map __maybe_unused, u64 ip)
95 { 95 {
96 return ip; 96 return ip;
97 } 97 }
98 98
99 99
100 /* rip/ip <-> addr suitable for passing to `objdump --start-address=` */ 100 /* rip/ip <-> addr suitable for passing to `objdump --start-address=` */
101 u64 map__rip_2objdump(struct map *map, u64 rip); 101 u64 map__rip_2objdump(struct map *map, u64 rip);
102 102
103 /* objdump address -> memory address */ 103 /* objdump address -> memory address */
104 u64 map__objdump_2mem(struct map *map, u64 ip); 104 u64 map__objdump_2mem(struct map *map, u64 ip);
105 105
106 struct symbol; 106 struct symbol;
107 struct thread; 107 struct thread;
108 108
109 /* map__for_each_symbol - iterate over the symbols in the given map 109 /* map__for_each_symbol - iterate over the symbols in the given map
110 * 110 *
111 * @map: the 'struct map *' in which symbols itereated 111 * @map: the 'struct map *' in which symbols itereated
112 * @pos: the 'struct symbol *' to use as a loop cursor 112 * @pos: the 'struct symbol *' to use as a loop cursor
113 * @n: the 'struct rb_node *' to use as a temporary storage 113 * @n: the 'struct rb_node *' to use as a temporary storage
114 * Note: caller must ensure map->dso is not NULL (map is loaded). 114 * Note: caller must ensure map->dso is not NULL (map is loaded).
115 */ 115 */
116 #define map__for_each_symbol(map, pos, n) \ 116 #define map__for_each_symbol(map, pos, n) \
117 dso__for_each_symbol(map->dso, pos, n, map->type) 117 dso__for_each_symbol(map->dso, pos, n, map->type)
118 118
119 /* map__for_each_symbol_with_name - iterate over the symbols in the given map
120 * that have the given name
121 *
122 * @map: the 'struct map *' in which symbols itereated
123 * @sym_name: the symbol name
124 * @pos: the 'struct symbol *' to use as a loop cursor
125 * @filter: to use when loading the DSO
126 */
127 #define __map__for_each_symbol_by_name(map, sym_name, pos, filter) \
128 for (pos = map__find_symbol_by_name(map, sym_name, filter); \
129 pos && strcmp(pos->name, sym_name) == 0; \
130 pos = symbol__next_by_name(pos))
131
132 #define map__for_each_symbol_by_name(map, sym_name, pos) \
133 __map__for_each_symbol_by_name(map, sym_name, (pos), NULL)
134
119 typedef int (*symbol_filter_t)(struct map *map, struct symbol *sym); 135 typedef int (*symbol_filter_t)(struct map *map, struct symbol *sym);
120 136
121 void map__init(struct map *map, enum map_type type, 137 void map__init(struct map *map, enum map_type type,
122 u64 start, u64 end, u64 pgoff, struct dso *dso); 138 u64 start, u64 end, u64 pgoff, struct dso *dso);
123 struct map *map__new(struct machine *machine, u64 start, u64 len, 139 struct map *map__new(struct machine *machine, u64 start, u64 len,
124 u64 pgoff, u32 pid, u32 d_maj, u32 d_min, u64 ino, 140 u64 pgoff, u32 pid, u32 d_maj, u32 d_min, u64 ino,
125 u64 ino_gen, u32 prot, u32 flags, 141 u64 ino_gen, u32 prot, u32 flags,
126 char *filename, enum map_type type, struct thread *thread); 142 char *filename, enum map_type type, struct thread *thread);
127 struct map *map__new2(u64 start, struct dso *dso, enum map_type type); 143 struct map *map__new2(u64 start, struct dso *dso, enum map_type type);
128 void map__delete(struct map *map); 144 void map__delete(struct map *map);
129 struct map *map__clone(struct map *map); 145 struct map *map__clone(struct map *map);
130 int map__overlap(struct map *l, struct map *r); 146 int map__overlap(struct map *l, struct map *r);
131 size_t map__fprintf(struct map *map, FILE *fp); 147 size_t map__fprintf(struct map *map, FILE *fp);
132 size_t map__fprintf_dsoname(struct map *map, FILE *fp); 148 size_t map__fprintf_dsoname(struct map *map, FILE *fp);
133 int map__fprintf_srcline(struct map *map, u64 addr, const char *prefix, 149 int map__fprintf_srcline(struct map *map, u64 addr, const char *prefix,
134 FILE *fp); 150 FILE *fp);
135 151
136 int map__load(struct map *map, symbol_filter_t filter); 152 int map__load(struct map *map, symbol_filter_t filter);
137 struct symbol *map__find_symbol(struct map *map, 153 struct symbol *map__find_symbol(struct map *map,
138 u64 addr, symbol_filter_t filter); 154 u64 addr, symbol_filter_t filter);
139 struct symbol *map__find_symbol_by_name(struct map *map, const char *name, 155 struct symbol *map__find_symbol_by_name(struct map *map, const char *name,
140 symbol_filter_t filter); 156 symbol_filter_t filter);
141 void map__fixup_start(struct map *map); 157 void map__fixup_start(struct map *map);
142 void map__fixup_end(struct map *map); 158 void map__fixup_end(struct map *map);
143 159
144 void map__reloc_vmlinux(struct map *map); 160 void map__reloc_vmlinux(struct map *map);
145 161
146 size_t __map_groups__fprintf_maps(struct map_groups *mg, enum map_type type, 162 size_t __map_groups__fprintf_maps(struct map_groups *mg, enum map_type type,
147 FILE *fp); 163 FILE *fp);
148 void maps__insert(struct rb_root *maps, struct map *map); 164 void maps__insert(struct rb_root *maps, struct map *map);
149 void maps__remove(struct rb_root *maps, struct map *map); 165 void maps__remove(struct rb_root *maps, struct map *map);
150 struct map *maps__find(struct rb_root *maps, u64 addr); 166 struct map *maps__find(struct rb_root *maps, u64 addr);
151 struct map *maps__first(struct rb_root *maps); 167 struct map *maps__first(struct rb_root *maps);
152 struct map *maps__next(struct map *map); 168 struct map *maps__next(struct map *map);
153 void map_groups__init(struct map_groups *mg, struct machine *machine); 169 void map_groups__init(struct map_groups *mg, struct machine *machine);
154 void map_groups__exit(struct map_groups *mg); 170 void map_groups__exit(struct map_groups *mg);
155 int map_groups__clone(struct map_groups *mg, 171 int map_groups__clone(struct map_groups *mg,
156 struct map_groups *parent, enum map_type type); 172 struct map_groups *parent, enum map_type type);
157 size_t map_groups__fprintf(struct map_groups *mg, FILE *fp); 173 size_t map_groups__fprintf(struct map_groups *mg, FILE *fp);
158 174
159 int maps__set_kallsyms_ref_reloc_sym(struct map **maps, const char *symbol_name, 175 int maps__set_kallsyms_ref_reloc_sym(struct map **maps, const char *symbol_name,
160 u64 addr); 176 u64 addr);
161 177
162 static inline void map_groups__insert(struct map_groups *mg, struct map *map) 178 static inline void map_groups__insert(struct map_groups *mg, struct map *map)
163 { 179 {
164 maps__insert(&mg->maps[map->type], map); 180 maps__insert(&mg->maps[map->type], map);
165 map->groups = mg; 181 map->groups = mg;
166 } 182 }
167 183
168 static inline void map_groups__remove(struct map_groups *mg, struct map *map) 184 static inline void map_groups__remove(struct map_groups *mg, struct map *map)
169 { 185 {
170 maps__remove(&mg->maps[map->type], map); 186 maps__remove(&mg->maps[map->type], map);
171 } 187 }
172 188
173 static inline struct map *map_groups__find(struct map_groups *mg, 189 static inline struct map *map_groups__find(struct map_groups *mg,
174 enum map_type type, u64 addr) 190 enum map_type type, u64 addr)
175 { 191 {
176 return maps__find(&mg->maps[type], addr); 192 return maps__find(&mg->maps[type], addr);
177 } 193 }
178 194
179 static inline struct map *map_groups__first(struct map_groups *mg, 195 static inline struct map *map_groups__first(struct map_groups *mg,
180 enum map_type type) 196 enum map_type type)
181 { 197 {
182 return maps__first(&mg->maps[type]); 198 return maps__first(&mg->maps[type]);
183 } 199 }
184 200
185 static inline struct map *map_groups__next(struct map *map) 201 static inline struct map *map_groups__next(struct map *map)
186 { 202 {
187 return maps__next(map); 203 return maps__next(map);
188 } 204 }
189 205
190 struct symbol *map_groups__find_symbol(struct map_groups *mg, 206 struct symbol *map_groups__find_symbol(struct map_groups *mg,
191 enum map_type type, u64 addr, 207 enum map_type type, u64 addr,
192 struct map **mapp, 208 struct map **mapp,
193 symbol_filter_t filter); 209 symbol_filter_t filter);
194 210
195 struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg, 211 struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg,
196 enum map_type type, 212 enum map_type type,
197 const char *name, 213 const char *name,
198 struct map **mapp, 214 struct map **mapp,
199 symbol_filter_t filter); 215 symbol_filter_t filter);
200 216
201 struct addr_map_symbol; 217 struct addr_map_symbol;
202 218
203 int map_groups__find_ams(struct addr_map_symbol *ams, symbol_filter_t filter); 219 int map_groups__find_ams(struct addr_map_symbol *ams, symbol_filter_t filter);
204 220
205 static inline 221 static inline
206 struct symbol *map_groups__find_function_by_name(struct map_groups *mg, 222 struct symbol *map_groups__find_function_by_name(struct map_groups *mg,
207 const char *name, struct map **mapp, 223 const char *name, struct map **mapp,
208 symbol_filter_t filter) 224 symbol_filter_t filter)
209 { 225 {
210 return map_groups__find_symbol_by_name(mg, MAP__FUNCTION, name, mapp, filter); 226 return map_groups__find_symbol_by_name(mg, MAP__FUNCTION, name, mapp, filter);
211 } 227 }
212 228
213 int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map, 229 int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map,
214 FILE *fp); 230 FILE *fp);
215 231
216 struct map *map_groups__find_by_name(struct map_groups *mg, 232 struct map *map_groups__find_by_name(struct map_groups *mg,
217 enum map_type type, const char *name); 233 enum map_type type, const char *name);
218 234
219 void map_groups__flush(struct map_groups *mg); 235 void map_groups__flush(struct map_groups *mg);
220 236
221 #endif /* __PERF_MAP_H */ 237 #endif /* __PERF_MAP_H */
222 238
tools/perf/util/probe-event.c
1 /* 1 /*
2 * probe-event.c : perf-probe definition to probe_events format converter 2 * probe-event.c : perf-probe definition to probe_events format converter
3 * 3 *
4 * Written by Masami Hiramatsu <mhiramat@redhat.com> 4 * Written by Masami Hiramatsu <mhiramat@redhat.com>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or 8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version. 9 * (at your option) any later version.
10 * 10 *
11 * This program is distributed in the hope that it will be useful, 11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License 16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 * 19 *
20 */ 20 */
21 21
22 #include <sys/utsname.h> 22 #include <sys/utsname.h>
23 #include <sys/types.h> 23 #include <sys/types.h>
24 #include <sys/stat.h> 24 #include <sys/stat.h>
25 #include <fcntl.h> 25 #include <fcntl.h>
26 #include <errno.h> 26 #include <errno.h>
27 #include <stdio.h> 27 #include <stdio.h>
28 #include <unistd.h> 28 #include <unistd.h>
29 #include <stdlib.h> 29 #include <stdlib.h>
30 #include <string.h> 30 #include <string.h>
31 #include <stdarg.h> 31 #include <stdarg.h>
32 #include <limits.h> 32 #include <limits.h>
33 #include <elf.h> 33 #include <elf.h>
34 34
35 #include "util.h" 35 #include "util.h"
36 #include "event.h" 36 #include "event.h"
37 #include "strlist.h" 37 #include "strlist.h"
38 #include "debug.h" 38 #include "debug.h"
39 #include "cache.h" 39 #include "cache.h"
40 #include "color.h" 40 #include "color.h"
41 #include "symbol.h" 41 #include "symbol.h"
42 #include "thread.h" 42 #include "thread.h"
43 #include <api/fs/debugfs.h> 43 #include <api/fs/debugfs.h>
44 #include "trace-event.h" /* For __maybe_unused */ 44 #include "trace-event.h" /* For __maybe_unused */
45 #include "probe-event.h" 45 #include "probe-event.h"
46 #include "probe-finder.h" 46 #include "probe-finder.h"
47 #include "session.h" 47 #include "session.h"
48 48
49 #define MAX_CMDLEN 256 49 #define MAX_CMDLEN 256
50 #define PERFPROBE_GROUP "probe" 50 #define PERFPROBE_GROUP "probe"
51 51
52 bool probe_event_dry_run; /* Dry run flag */ 52 bool probe_event_dry_run; /* Dry run flag */
53 53
54 #define semantic_error(msg ...) pr_err("Semantic error :" msg) 54 #define semantic_error(msg ...) pr_err("Semantic error :" msg)
55 55
56 /* If there is no space to write, returns -E2BIG. */ 56 /* If there is no space to write, returns -E2BIG. */
57 static int e_snprintf(char *str, size_t size, const char *format, ...) 57 static int e_snprintf(char *str, size_t size, const char *format, ...)
58 __attribute__((format(printf, 3, 4))); 58 __attribute__((format(printf, 3, 4)));
59 59
60 static int e_snprintf(char *str, size_t size, const char *format, ...) 60 static int e_snprintf(char *str, size_t size, const char *format, ...)
61 { 61 {
62 int ret; 62 int ret;
63 va_list ap; 63 va_list ap;
64 va_start(ap, format); 64 va_start(ap, format);
65 ret = vsnprintf(str, size, format, ap); 65 ret = vsnprintf(str, size, format, ap);
66 va_end(ap); 66 va_end(ap);
67 if (ret >= (int)size) 67 if (ret >= (int)size)
68 ret = -E2BIG; 68 ret = -E2BIG;
69 return ret; 69 return ret;
70 } 70 }
71 71
72 static char *synthesize_perf_probe_point(struct perf_probe_point *pp); 72 static char *synthesize_perf_probe_point(struct perf_probe_point *pp);
73 static void clear_probe_trace_event(struct probe_trace_event *tev); 73 static void clear_probe_trace_event(struct probe_trace_event *tev);
74 static struct machine *host_machine; 74 static struct machine *host_machine;
75 75
76 /* Initialize symbol maps and path of vmlinux/modules */ 76 /* Initialize symbol maps and path of vmlinux/modules */
77 static int init_symbol_maps(bool user_only) 77 static int init_symbol_maps(bool user_only)
78 { 78 {
79 int ret; 79 int ret;
80 80
81 symbol_conf.sort_by_name = true; 81 symbol_conf.sort_by_name = true;
82 ret = symbol__init(NULL); 82 ret = symbol__init(NULL);
83 if (ret < 0) { 83 if (ret < 0) {
84 pr_debug("Failed to init symbol map.\n"); 84 pr_debug("Failed to init symbol map.\n");
85 goto out; 85 goto out;
86 } 86 }
87 87
88 if (host_machine || user_only) /* already initialized */ 88 if (host_machine || user_only) /* already initialized */
89 return 0; 89 return 0;
90 90
91 if (symbol_conf.vmlinux_name) 91 if (symbol_conf.vmlinux_name)
92 pr_debug("Use vmlinux: %s\n", symbol_conf.vmlinux_name); 92 pr_debug("Use vmlinux: %s\n", symbol_conf.vmlinux_name);
93 93
94 host_machine = machine__new_host(); 94 host_machine = machine__new_host();
95 if (!host_machine) { 95 if (!host_machine) {
96 pr_debug("machine__new_host() failed.\n"); 96 pr_debug("machine__new_host() failed.\n");
97 symbol__exit(); 97 symbol__exit();
98 ret = -1; 98 ret = -1;
99 } 99 }
100 out: 100 out:
101 if (ret < 0) 101 if (ret < 0)
102 pr_warning("Failed to init vmlinux path.\n"); 102 pr_warning("Failed to init vmlinux path.\n");
103 return ret; 103 return ret;
104 } 104 }
105 105
106 static void exit_symbol_maps(void) 106 static void exit_symbol_maps(void)
107 { 107 {
108 if (host_machine) { 108 if (host_machine) {
109 machine__delete(host_machine); 109 machine__delete(host_machine);
110 host_machine = NULL; 110 host_machine = NULL;
111 } 111 }
112 symbol__exit(); 112 symbol__exit();
113 } 113 }
114 114
115 static struct symbol *__find_kernel_function_by_name(const char *name, 115 static struct symbol *__find_kernel_function_by_name(const char *name,
116 struct map **mapp) 116 struct map **mapp)
117 { 117 {
118 return machine__find_kernel_function_by_name(host_machine, name, mapp, 118 return machine__find_kernel_function_by_name(host_machine, name, mapp,
119 NULL); 119 NULL);
120 } 120 }
121 121
122 static struct symbol *__find_kernel_function(u64 addr, struct map **mapp) 122 static struct symbol *__find_kernel_function(u64 addr, struct map **mapp)
123 { 123 {
124 return machine__find_kernel_function(host_machine, addr, mapp, NULL); 124 return machine__find_kernel_function(host_machine, addr, mapp, NULL);
125 } 125 }
126 126
127 static struct ref_reloc_sym *kernel_get_ref_reloc_sym(void) 127 static struct ref_reloc_sym *kernel_get_ref_reloc_sym(void)
128 { 128 {
129 /* kmap->ref_reloc_sym should be set if host_machine is initialized */ 129 /* kmap->ref_reloc_sym should be set if host_machine is initialized */
130 struct kmap *kmap; 130 struct kmap *kmap;
131 131
132 if (map__load(host_machine->vmlinux_maps[MAP__FUNCTION], NULL) < 0) 132 if (map__load(host_machine->vmlinux_maps[MAP__FUNCTION], NULL) < 0)
133 return NULL; 133 return NULL;
134 134
135 kmap = map__kmap(host_machine->vmlinux_maps[MAP__FUNCTION]); 135 kmap = map__kmap(host_machine->vmlinux_maps[MAP__FUNCTION]);
136 return kmap->ref_reloc_sym; 136 return kmap->ref_reloc_sym;
137 } 137 }
138 138
139 static u64 kernel_get_symbol_address_by_name(const char *name, bool reloc) 139 static u64 kernel_get_symbol_address_by_name(const char *name, bool reloc)
140 { 140 {
141 struct ref_reloc_sym *reloc_sym; 141 struct ref_reloc_sym *reloc_sym;
142 struct symbol *sym; 142 struct symbol *sym;
143 struct map *map; 143 struct map *map;
144 144
145 /* ref_reloc_sym is just a label. Need a special fix*/ 145 /* ref_reloc_sym is just a label. Need a special fix*/
146 reloc_sym = kernel_get_ref_reloc_sym(); 146 reloc_sym = kernel_get_ref_reloc_sym();
147 if (reloc_sym && strcmp(name, reloc_sym->name) == 0) 147 if (reloc_sym && strcmp(name, reloc_sym->name) == 0)
148 return (reloc) ? reloc_sym->addr : reloc_sym->unrelocated_addr; 148 return (reloc) ? reloc_sym->addr : reloc_sym->unrelocated_addr;
149 else { 149 else {
150 sym = __find_kernel_function_by_name(name, &map); 150 sym = __find_kernel_function_by_name(name, &map);
151 if (sym) 151 if (sym)
152 return map->unmap_ip(map, sym->start) - 152 return map->unmap_ip(map, sym->start) -
153 (reloc) ? 0 : map->reloc; 153 (reloc) ? 0 : map->reloc;
154 } 154 }
155 return 0; 155 return 0;
156 } 156 }
157 157
158 static struct map *kernel_get_module_map(const char *module) 158 static struct map *kernel_get_module_map(const char *module)
159 { 159 {
160 struct rb_node *nd; 160 struct rb_node *nd;
161 struct map_groups *grp = &host_machine->kmaps; 161 struct map_groups *grp = &host_machine->kmaps;
162 162
163 /* A file path -- this is an offline module */ 163 /* A file path -- this is an offline module */
164 if (module && strchr(module, '/')) 164 if (module && strchr(module, '/'))
165 return machine__new_module(host_machine, 0, module); 165 return machine__new_module(host_machine, 0, module);
166 166
167 if (!module) 167 if (!module)
168 module = "kernel"; 168 module = "kernel";
169 169
170 for (nd = rb_first(&grp->maps[MAP__FUNCTION]); nd; nd = rb_next(nd)) { 170 for (nd = rb_first(&grp->maps[MAP__FUNCTION]); nd; nd = rb_next(nd)) {
171 struct map *pos = rb_entry(nd, struct map, rb_node); 171 struct map *pos = rb_entry(nd, struct map, rb_node);
172 if (strncmp(pos->dso->short_name + 1, module, 172 if (strncmp(pos->dso->short_name + 1, module,
173 pos->dso->short_name_len - 2) == 0) { 173 pos->dso->short_name_len - 2) == 0) {
174 return pos; 174 return pos;
175 } 175 }
176 } 176 }
177 return NULL; 177 return NULL;
178 } 178 }
179 179
180 static struct dso *kernel_get_module_dso(const char *module) 180 static struct dso *kernel_get_module_dso(const char *module)
181 { 181 {
182 struct dso *dso; 182 struct dso *dso;
183 struct map *map; 183 struct map *map;
184 const char *vmlinux_name; 184 const char *vmlinux_name;
185 185
186 if (module) { 186 if (module) {
187 list_for_each_entry(dso, &host_machine->kernel_dsos.head, 187 list_for_each_entry(dso, &host_machine->kernel_dsos.head,
188 node) { 188 node) {
189 if (strncmp(dso->short_name + 1, module, 189 if (strncmp(dso->short_name + 1, module,
190 dso->short_name_len - 2) == 0) 190 dso->short_name_len - 2) == 0)
191 goto found; 191 goto found;
192 } 192 }
193 pr_debug("Failed to find module %s.\n", module); 193 pr_debug("Failed to find module %s.\n", module);
194 return NULL; 194 return NULL;
195 } 195 }
196 196
197 map = host_machine->vmlinux_maps[MAP__FUNCTION]; 197 map = host_machine->vmlinux_maps[MAP__FUNCTION];
198 dso = map->dso; 198 dso = map->dso;
199 199
200 vmlinux_name = symbol_conf.vmlinux_name; 200 vmlinux_name = symbol_conf.vmlinux_name;
201 if (vmlinux_name) { 201 if (vmlinux_name) {
202 if (dso__load_vmlinux(dso, map, vmlinux_name, false, NULL) <= 0) 202 if (dso__load_vmlinux(dso, map, vmlinux_name, false, NULL) <= 0)
203 return NULL; 203 return NULL;
204 } else { 204 } else {
205 if (dso__load_vmlinux_path(dso, map, NULL) <= 0) { 205 if (dso__load_vmlinux_path(dso, map, NULL) <= 0) {
206 pr_debug("Failed to load kernel map.\n"); 206 pr_debug("Failed to load kernel map.\n");
207 return NULL; 207 return NULL;
208 } 208 }
209 } 209 }
210 found: 210 found:
211 return dso; 211 return dso;
212 } 212 }
213 213
214 const char *kernel_get_module_path(const char *module) 214 const char *kernel_get_module_path(const char *module)
215 { 215 {
216 struct dso *dso = kernel_get_module_dso(module); 216 struct dso *dso = kernel_get_module_dso(module);
217 return (dso) ? dso->long_name : NULL; 217 return (dso) ? dso->long_name : NULL;
218 } 218 }
219 219
220 static int convert_exec_to_group(const char *exec, char **result) 220 static int convert_exec_to_group(const char *exec, char **result)
221 { 221 {
222 char *ptr1, *ptr2, *exec_copy; 222 char *ptr1, *ptr2, *exec_copy;
223 char buf[64]; 223 char buf[64];
224 int ret; 224 int ret;
225 225
226 exec_copy = strdup(exec); 226 exec_copy = strdup(exec);
227 if (!exec_copy) 227 if (!exec_copy)
228 return -ENOMEM; 228 return -ENOMEM;
229 229
230 ptr1 = basename(exec_copy); 230 ptr1 = basename(exec_copy);
231 if (!ptr1) { 231 if (!ptr1) {
232 ret = -EINVAL; 232 ret = -EINVAL;
233 goto out; 233 goto out;
234 } 234 }
235 235
236 ptr2 = strpbrk(ptr1, "-._"); 236 ptr2 = strpbrk(ptr1, "-._");
237 if (ptr2) 237 if (ptr2)
238 *ptr2 = '\0'; 238 *ptr2 = '\0';
239 ret = e_snprintf(buf, 64, "%s_%s", PERFPROBE_GROUP, ptr1); 239 ret = e_snprintf(buf, 64, "%s_%s", PERFPROBE_GROUP, ptr1);
240 if (ret < 0) 240 if (ret < 0)
241 goto out; 241 goto out;
242 242
243 *result = strdup(buf); 243 *result = strdup(buf);
244 ret = *result ? 0 : -ENOMEM; 244 ret = *result ? 0 : -ENOMEM;
245 245
246 out: 246 out:
247 free(exec_copy); 247 free(exec_copy);
248 return ret; 248 return ret;
249 } 249 }
250 250
251 static void clear_probe_trace_events(struct probe_trace_event *tevs, int ntevs) 251 static void clear_probe_trace_events(struct probe_trace_event *tevs, int ntevs)
252 { 252 {
253 int i; 253 int i;
254 254
255 for (i = 0; i < ntevs; i++) 255 for (i = 0; i < ntevs; i++)
256 clear_probe_trace_event(tevs + i); 256 clear_probe_trace_event(tevs + i);
257 } 257 }
258 258
259 #ifdef HAVE_DWARF_SUPPORT 259 #ifdef HAVE_DWARF_SUPPORT
260 260
261 /* Open new debuginfo of given module */ 261 /* Open new debuginfo of given module */
262 static struct debuginfo *open_debuginfo(const char *module, bool silent) 262 static struct debuginfo *open_debuginfo(const char *module, bool silent)
263 { 263 {
264 const char *path = module; 264 const char *path = module;
265 struct debuginfo *ret; 265 struct debuginfo *ret;
266 266
267 if (!module || !strchr(module, '/')) { 267 if (!module || !strchr(module, '/')) {
268 path = kernel_get_module_path(module); 268 path = kernel_get_module_path(module);
269 if (!path) { 269 if (!path) {
270 if (!silent) 270 if (!silent)
271 pr_err("Failed to find path of %s module.\n", 271 pr_err("Failed to find path of %s module.\n",
272 module ?: "kernel"); 272 module ?: "kernel");
273 return NULL; 273 return NULL;
274 } 274 }
275 } 275 }
276 ret = debuginfo__new(path); 276 ret = debuginfo__new(path);
277 if (!ret && !silent) { 277 if (!ret && !silent) {
278 pr_warning("The %s file has no debug information.\n", path); 278 pr_warning("The %s file has no debug information.\n", path);
279 if (!module || !strtailcmp(path, ".ko")) 279 if (!module || !strtailcmp(path, ".ko"))
280 pr_warning("Rebuild with CONFIG_DEBUG_INFO=y, "); 280 pr_warning("Rebuild with CONFIG_DEBUG_INFO=y, ");
281 else 281 else
282 pr_warning("Rebuild with -g, "); 282 pr_warning("Rebuild with -g, ");
283 pr_warning("or install an appropriate debuginfo package.\n"); 283 pr_warning("or install an appropriate debuginfo package.\n");
284 } 284 }
285 return ret; 285 return ret;
286 } 286 }
287 287
288 288
289 static int get_text_start_address(const char *exec, unsigned long *address) 289 static int get_text_start_address(const char *exec, unsigned long *address)
290 { 290 {
291 Elf *elf; 291 Elf *elf;
292 GElf_Ehdr ehdr; 292 GElf_Ehdr ehdr;
293 GElf_Shdr shdr; 293 GElf_Shdr shdr;
294 int fd, ret = -ENOENT; 294 int fd, ret = -ENOENT;
295 295
296 fd = open(exec, O_RDONLY); 296 fd = open(exec, O_RDONLY);
297 if (fd < 0) 297 if (fd < 0)
298 return -errno; 298 return -errno;
299 299
300 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL); 300 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
301 if (elf == NULL) 301 if (elf == NULL)
302 return -EINVAL; 302 return -EINVAL;
303 303
304 if (gelf_getehdr(elf, &ehdr) == NULL) 304 if (gelf_getehdr(elf, &ehdr) == NULL)
305 goto out; 305 goto out;
306 306
307 if (!elf_section_by_name(elf, &ehdr, &shdr, ".text", NULL)) 307 if (!elf_section_by_name(elf, &ehdr, &shdr, ".text", NULL))
308 goto out; 308 goto out;
309 309
310 *address = shdr.sh_addr - shdr.sh_offset; 310 *address = shdr.sh_addr - shdr.sh_offset;
311 ret = 0; 311 ret = 0;
312 out: 312 out:
313 elf_end(elf); 313 elf_end(elf);
314 return ret; 314 return ret;
315 } 315 }
316 316
317 /* 317 /*
318 * Convert trace point to probe point with debuginfo 318 * Convert trace point to probe point with debuginfo
319 */ 319 */
320 static int find_perf_probe_point_from_dwarf(struct probe_trace_point *tp, 320 static int find_perf_probe_point_from_dwarf(struct probe_trace_point *tp,
321 struct perf_probe_point *pp, 321 struct perf_probe_point *pp,
322 bool is_kprobe) 322 bool is_kprobe)
323 { 323 {
324 struct debuginfo *dinfo = NULL; 324 struct debuginfo *dinfo = NULL;
325 unsigned long stext = 0; 325 unsigned long stext = 0;
326 u64 addr = tp->address; 326 u64 addr = tp->address;
327 int ret = -ENOENT; 327 int ret = -ENOENT;
328 328
329 /* convert the address to dwarf address */ 329 /* convert the address to dwarf address */
330 if (!is_kprobe) { 330 if (!is_kprobe) {
331 if (!addr) { 331 if (!addr) {
332 ret = -EINVAL; 332 ret = -EINVAL;
333 goto error; 333 goto error;
334 } 334 }
335 ret = get_text_start_address(tp->module, &stext); 335 ret = get_text_start_address(tp->module, &stext);
336 if (ret < 0) 336 if (ret < 0)
337 goto error; 337 goto error;
338 addr += stext; 338 addr += stext;
339 } else { 339 } else {
340 addr = kernel_get_symbol_address_by_name(tp->symbol, false); 340 addr = kernel_get_symbol_address_by_name(tp->symbol, false);
341 if (addr == 0) 341 if (addr == 0)
342 goto error; 342 goto error;
343 addr += tp->offset; 343 addr += tp->offset;
344 } 344 }
345 345
346 pr_debug("try to find information at %" PRIx64 " in %s\n", addr, 346 pr_debug("try to find information at %" PRIx64 " in %s\n", addr,
347 tp->module ? : "kernel"); 347 tp->module ? : "kernel");
348 348
349 dinfo = open_debuginfo(tp->module, verbose == 0); 349 dinfo = open_debuginfo(tp->module, verbose == 0);
350 if (dinfo) { 350 if (dinfo) {
351 ret = debuginfo__find_probe_point(dinfo, 351 ret = debuginfo__find_probe_point(dinfo,
352 (unsigned long)addr, pp); 352 (unsigned long)addr, pp);
353 debuginfo__delete(dinfo); 353 debuginfo__delete(dinfo);
354 } else 354 } else
355 ret = -ENOENT; 355 ret = -ENOENT;
356 356
357 if (ret > 0) { 357 if (ret > 0) {
358 pp->retprobe = tp->retprobe; 358 pp->retprobe = tp->retprobe;
359 return 0; 359 return 0;
360 } 360 }
361 error: 361 error:
362 pr_debug("Failed to find corresponding probes from debuginfo.\n"); 362 pr_debug("Failed to find corresponding probes from debuginfo.\n");
363 return ret ? : -ENOENT; 363 return ret ? : -ENOENT;
364 } 364 }
365 365
366 static int add_exec_to_probe_trace_events(struct probe_trace_event *tevs, 366 static int add_exec_to_probe_trace_events(struct probe_trace_event *tevs,
367 int ntevs, const char *exec) 367 int ntevs, const char *exec)
368 { 368 {
369 int i, ret = 0; 369 int i, ret = 0;
370 unsigned long stext = 0; 370 unsigned long stext = 0;
371 371
372 if (!exec) 372 if (!exec)
373 return 0; 373 return 0;
374 374
375 ret = get_text_start_address(exec, &stext); 375 ret = get_text_start_address(exec, &stext);
376 if (ret < 0) 376 if (ret < 0)
377 return ret; 377 return ret;
378 378
379 for (i = 0; i < ntevs && ret >= 0; i++) { 379 for (i = 0; i < ntevs && ret >= 0; i++) {
380 /* point.address is the addres of point.symbol + point.offset */ 380 /* point.address is the addres of point.symbol + point.offset */
381 tevs[i].point.address -= stext; 381 tevs[i].point.address -= stext;
382 tevs[i].point.module = strdup(exec); 382 tevs[i].point.module = strdup(exec);
383 if (!tevs[i].point.module) { 383 if (!tevs[i].point.module) {
384 ret = -ENOMEM; 384 ret = -ENOMEM;
385 break; 385 break;
386 } 386 }
387 tevs[i].uprobes = true; 387 tevs[i].uprobes = true;
388 } 388 }
389 389
390 return ret; 390 return ret;
391 } 391 }
392 392
393 static int add_module_to_probe_trace_events(struct probe_trace_event *tevs, 393 static int add_module_to_probe_trace_events(struct probe_trace_event *tevs,
394 int ntevs, const char *module) 394 int ntevs, const char *module)
395 { 395 {
396 int i, ret = 0; 396 int i, ret = 0;
397 char *tmp; 397 char *tmp;
398 398
399 if (!module) 399 if (!module)
400 return 0; 400 return 0;
401 401
402 tmp = strrchr(module, '/'); 402 tmp = strrchr(module, '/');
403 if (tmp) { 403 if (tmp) {
404 /* This is a module path -- get the module name */ 404 /* This is a module path -- get the module name */
405 module = strdup(tmp + 1); 405 module = strdup(tmp + 1);
406 if (!module) 406 if (!module)
407 return -ENOMEM; 407 return -ENOMEM;
408 tmp = strchr(module, '.'); 408 tmp = strchr(module, '.');
409 if (tmp) 409 if (tmp)
410 *tmp = '\0'; 410 *tmp = '\0';
411 tmp = (char *)module; /* For free() */ 411 tmp = (char *)module; /* For free() */
412 } 412 }
413 413
414 for (i = 0; i < ntevs; i++) { 414 for (i = 0; i < ntevs; i++) {
415 tevs[i].point.module = strdup(module); 415 tevs[i].point.module = strdup(module);
416 if (!tevs[i].point.module) { 416 if (!tevs[i].point.module) {
417 ret = -ENOMEM; 417 ret = -ENOMEM;
418 break; 418 break;
419 } 419 }
420 } 420 }
421 421
422 free(tmp); 422 free(tmp);
423 return ret; 423 return ret;
424 } 424 }
425 425
426 /* Post processing the probe events */ 426 /* Post processing the probe events */
427 static int post_process_probe_trace_events(struct probe_trace_event *tevs, 427 static int post_process_probe_trace_events(struct probe_trace_event *tevs,
428 int ntevs, const char *module, 428 int ntevs, const char *module,
429 bool uprobe) 429 bool uprobe)
430 { 430 {
431 struct ref_reloc_sym *reloc_sym; 431 struct ref_reloc_sym *reloc_sym;
432 char *tmp; 432 char *tmp;
433 int i; 433 int i;
434 434
435 if (uprobe) 435 if (uprobe)
436 return add_exec_to_probe_trace_events(tevs, ntevs, module); 436 return add_exec_to_probe_trace_events(tevs, ntevs, module);
437 437
438 /* Note that currently ref_reloc_sym based probe is not for drivers */ 438 /* Note that currently ref_reloc_sym based probe is not for drivers */
439 if (module) 439 if (module)
440 return add_module_to_probe_trace_events(tevs, ntevs, module); 440 return add_module_to_probe_trace_events(tevs, ntevs, module);
441 441
442 reloc_sym = kernel_get_ref_reloc_sym(); 442 reloc_sym = kernel_get_ref_reloc_sym();
443 if (!reloc_sym) { 443 if (!reloc_sym) {
444 pr_warning("Relocated base symbol is not found!\n"); 444 pr_warning("Relocated base symbol is not found!\n");
445 return -EINVAL; 445 return -EINVAL;
446 } 446 }
447 447
448 for (i = 0; i < ntevs; i++) { 448 for (i = 0; i < ntevs; i++) {
449 if (tevs[i].point.address) { 449 if (tevs[i].point.address && !tevs[i].point.retprobe) {
450 tmp = strdup(reloc_sym->name); 450 tmp = strdup(reloc_sym->name);
451 if (!tmp) 451 if (!tmp)
452 return -ENOMEM; 452 return -ENOMEM;
453 free(tevs[i].point.symbol); 453 free(tevs[i].point.symbol);
454 tevs[i].point.symbol = tmp; 454 tevs[i].point.symbol = tmp;
455 tevs[i].point.offset = tevs[i].point.address - 455 tevs[i].point.offset = tevs[i].point.address -
456 reloc_sym->unrelocated_addr; 456 reloc_sym->unrelocated_addr;
457 } 457 }
458 } 458 }
459 return 0; 459 return 0;
460 } 460 }
461 461
462 /* Try to find perf_probe_event with debuginfo */ 462 /* Try to find perf_probe_event with debuginfo */
463 static int try_to_find_probe_trace_events(struct perf_probe_event *pev, 463 static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
464 struct probe_trace_event **tevs, 464 struct probe_trace_event **tevs,
465 int max_tevs, const char *target) 465 int max_tevs, const char *target)
466 { 466 {
467 bool need_dwarf = perf_probe_event_need_dwarf(pev); 467 bool need_dwarf = perf_probe_event_need_dwarf(pev);
468 struct debuginfo *dinfo; 468 struct debuginfo *dinfo;
469 int ntevs, ret = 0; 469 int ntevs, ret = 0;
470 470
471 dinfo = open_debuginfo(target, !need_dwarf); 471 dinfo = open_debuginfo(target, !need_dwarf);
472 472
473 if (!dinfo) { 473 if (!dinfo) {
474 if (need_dwarf) 474 if (need_dwarf)
475 return -ENOENT; 475 return -ENOENT;
476 pr_debug("Could not open debuginfo. Try to use symbols.\n"); 476 pr_debug("Could not open debuginfo. Try to use symbols.\n");
477 return 0; 477 return 0;
478 } 478 }
479 479
480 pr_debug("Try to find probe point from debuginfo.\n"); 480 pr_debug("Try to find probe point from debuginfo.\n");
481 /* Searching trace events corresponding to a probe event */ 481 /* Searching trace events corresponding to a probe event */
482 ntevs = debuginfo__find_trace_events(dinfo, pev, tevs, max_tevs); 482 ntevs = debuginfo__find_trace_events(dinfo, pev, tevs, max_tevs);
483 483
484 debuginfo__delete(dinfo); 484 debuginfo__delete(dinfo);
485 485
486 if (ntevs > 0) { /* Succeeded to find trace events */ 486 if (ntevs > 0) { /* Succeeded to find trace events */
487 pr_debug("Found %d probe_trace_events.\n", ntevs); 487 pr_debug("Found %d probe_trace_events.\n", ntevs);
488 ret = post_process_probe_trace_events(*tevs, ntevs, 488 ret = post_process_probe_trace_events(*tevs, ntevs,
489 target, pev->uprobes); 489 target, pev->uprobes);
490 if (ret < 0) { 490 if (ret < 0) {
491 clear_probe_trace_events(*tevs, ntevs); 491 clear_probe_trace_events(*tevs, ntevs);
492 zfree(tevs); 492 zfree(tevs);
493 } 493 }
494 return ret < 0 ? ret : ntevs; 494 return ret < 0 ? ret : ntevs;
495 } 495 }
496 496
497 if (ntevs == 0) { /* No error but failed to find probe point. */ 497 if (ntevs == 0) { /* No error but failed to find probe point. */
498 pr_warning("Probe point '%s' not found in debuginfo.\n", 498 pr_warning("Probe point '%s' not found in debuginfo.\n",
499 synthesize_perf_probe_point(&pev->point)); 499 synthesize_perf_probe_point(&pev->point));
500 if (need_dwarf) 500 if (need_dwarf)
501 return -ENOENT; 501 return -ENOENT;
502 return 0; 502 return 0;
503 } 503 }
504 /* Error path : ntevs < 0 */ 504 /* Error path : ntevs < 0 */
505 pr_debug("An error occurred in debuginfo analysis (%d).\n", ntevs); 505 pr_debug("An error occurred in debuginfo analysis (%d).\n", ntevs);
506 if (ntevs == -EBADF) { 506 if (ntevs == -EBADF) {
507 pr_warning("Warning: No dwarf info found in the vmlinux - " 507 pr_warning("Warning: No dwarf info found in the vmlinux - "
508 "please rebuild kernel with CONFIG_DEBUG_INFO=y.\n"); 508 "please rebuild kernel with CONFIG_DEBUG_INFO=y.\n");
509 if (!need_dwarf) { 509 if (!need_dwarf) {
510 pr_debug("Trying to use symbols.\n"); 510 pr_debug("Trying to use symbols.\n");
511 return 0; 511 return 0;
512 } 512 }
513 } 513 }
514 return ntevs; 514 return ntevs;
515 } 515 }
516 516
517 /* 517 /*
518 * Find a src file from a DWARF tag path. Prepend optional source path prefix 518 * Find a src file from a DWARF tag path. Prepend optional source path prefix
519 * and chop off leading directories that do not exist. Result is passed back as 519 * and chop off leading directories that do not exist. Result is passed back as
520 * a newly allocated path on success. 520 * a newly allocated path on success.
521 * Return 0 if file was found and readable, -errno otherwise. 521 * Return 0 if file was found and readable, -errno otherwise.
522 */ 522 */
523 static int get_real_path(const char *raw_path, const char *comp_dir, 523 static int get_real_path(const char *raw_path, const char *comp_dir,
524 char **new_path) 524 char **new_path)
525 { 525 {
526 const char *prefix = symbol_conf.source_prefix; 526 const char *prefix = symbol_conf.source_prefix;
527 527
528 if (!prefix) { 528 if (!prefix) {
529 if (raw_path[0] != '/' && comp_dir) 529 if (raw_path[0] != '/' && comp_dir)
530 /* If not an absolute path, try to use comp_dir */ 530 /* If not an absolute path, try to use comp_dir */
531 prefix = comp_dir; 531 prefix = comp_dir;
532 else { 532 else {
533 if (access(raw_path, R_OK) == 0) { 533 if (access(raw_path, R_OK) == 0) {
534 *new_path = strdup(raw_path); 534 *new_path = strdup(raw_path);
535 return 0; 535 return 0;
536 } else 536 } else
537 return -errno; 537 return -errno;
538 } 538 }
539 } 539 }
540 540
541 *new_path = malloc((strlen(prefix) + strlen(raw_path) + 2)); 541 *new_path = malloc((strlen(prefix) + strlen(raw_path) + 2));
542 if (!*new_path) 542 if (!*new_path)
543 return -ENOMEM; 543 return -ENOMEM;
544 544
545 for (;;) { 545 for (;;) {
546 sprintf(*new_path, "%s/%s", prefix, raw_path); 546 sprintf(*new_path, "%s/%s", prefix, raw_path);
547 547
548 if (access(*new_path, R_OK) == 0) 548 if (access(*new_path, R_OK) == 0)
549 return 0; 549 return 0;
550 550
551 if (!symbol_conf.source_prefix) 551 if (!symbol_conf.source_prefix)
552 /* In case of searching comp_dir, don't retry */ 552 /* In case of searching comp_dir, don't retry */
553 return -errno; 553 return -errno;
554 554
555 switch (errno) { 555 switch (errno) {
556 case ENAMETOOLONG: 556 case ENAMETOOLONG:
557 case ENOENT: 557 case ENOENT:
558 case EROFS: 558 case EROFS:
559 case EFAULT: 559 case EFAULT:
560 raw_path = strchr(++raw_path, '/'); 560 raw_path = strchr(++raw_path, '/');
561 if (!raw_path) { 561 if (!raw_path) {
562 zfree(new_path); 562 zfree(new_path);
563 return -ENOENT; 563 return -ENOENT;
564 } 564 }
565 continue; 565 continue;
566 566
567 default: 567 default:
568 zfree(new_path); 568 zfree(new_path);
569 return -errno; 569 return -errno;
570 } 570 }
571 } 571 }
572 } 572 }
573 573
574 #define LINEBUF_SIZE 256 574 #define LINEBUF_SIZE 256
575 #define NR_ADDITIONAL_LINES 2 575 #define NR_ADDITIONAL_LINES 2
576 576
577 static int __show_one_line(FILE *fp, int l, bool skip, bool show_num) 577 static int __show_one_line(FILE *fp, int l, bool skip, bool show_num)
578 { 578 {
579 char buf[LINEBUF_SIZE], sbuf[STRERR_BUFSIZE]; 579 char buf[LINEBUF_SIZE], sbuf[STRERR_BUFSIZE];
580 const char *color = show_num ? "" : PERF_COLOR_BLUE; 580 const char *color = show_num ? "" : PERF_COLOR_BLUE;
581 const char *prefix = NULL; 581 const char *prefix = NULL;
582 582
583 do { 583 do {
584 if (fgets(buf, LINEBUF_SIZE, fp) == NULL) 584 if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
585 goto error; 585 goto error;
586 if (skip) 586 if (skip)
587 continue; 587 continue;
588 if (!prefix) { 588 if (!prefix) {
589 prefix = show_num ? "%7d " : " "; 589 prefix = show_num ? "%7d " : " ";
590 color_fprintf(stdout, color, prefix, l); 590 color_fprintf(stdout, color, prefix, l);
591 } 591 }
592 color_fprintf(stdout, color, "%s", buf); 592 color_fprintf(stdout, color, "%s", buf);
593 593
594 } while (strchr(buf, '\n') == NULL); 594 } while (strchr(buf, '\n') == NULL);
595 595
596 return 1; 596 return 1;
597 error: 597 error:
598 if (ferror(fp)) { 598 if (ferror(fp)) {
599 pr_warning("File read error: %s\n", 599 pr_warning("File read error: %s\n",
600 strerror_r(errno, sbuf, sizeof(sbuf))); 600 strerror_r(errno, sbuf, sizeof(sbuf)));
601 return -1; 601 return -1;
602 } 602 }
603 return 0; 603 return 0;
604 } 604 }
605 605
606 static int _show_one_line(FILE *fp, int l, bool skip, bool show_num) 606 static int _show_one_line(FILE *fp, int l, bool skip, bool show_num)
607 { 607 {
608 int rv = __show_one_line(fp, l, skip, show_num); 608 int rv = __show_one_line(fp, l, skip, show_num);
609 if (rv == 0) { 609 if (rv == 0) {
610 pr_warning("Source file is shorter than expected.\n"); 610 pr_warning("Source file is shorter than expected.\n");
611 rv = -1; 611 rv = -1;
612 } 612 }
613 return rv; 613 return rv;
614 } 614 }
615 615
616 #define show_one_line_with_num(f,l) _show_one_line(f,l,false,true) 616 #define show_one_line_with_num(f,l) _show_one_line(f,l,false,true)
617 #define show_one_line(f,l) _show_one_line(f,l,false,false) 617 #define show_one_line(f,l) _show_one_line(f,l,false,false)
618 #define skip_one_line(f,l) _show_one_line(f,l,true,false) 618 #define skip_one_line(f,l) _show_one_line(f,l,true,false)
619 #define show_one_line_or_eof(f,l) __show_one_line(f,l,false,false) 619 #define show_one_line_or_eof(f,l) __show_one_line(f,l,false,false)
620 620
621 /* 621 /*
622 * Show line-range always requires debuginfo to find source file and 622 * Show line-range always requires debuginfo to find source file and
623 * line number. 623 * line number.
624 */ 624 */
625 static int __show_line_range(struct line_range *lr, const char *module) 625 static int __show_line_range(struct line_range *lr, const char *module)
626 { 626 {
627 int l = 1; 627 int l = 1;
628 struct int_node *ln; 628 struct int_node *ln;
629 struct debuginfo *dinfo; 629 struct debuginfo *dinfo;
630 FILE *fp; 630 FILE *fp;
631 int ret; 631 int ret;
632 char *tmp; 632 char *tmp;
633 char sbuf[STRERR_BUFSIZE]; 633 char sbuf[STRERR_BUFSIZE];
634 634
635 /* Search a line range */ 635 /* Search a line range */
636 dinfo = open_debuginfo(module, false); 636 dinfo = open_debuginfo(module, false);
637 if (!dinfo) 637 if (!dinfo)
638 return -ENOENT; 638 return -ENOENT;
639 639
640 ret = debuginfo__find_line_range(dinfo, lr); 640 ret = debuginfo__find_line_range(dinfo, lr);
641 debuginfo__delete(dinfo); 641 debuginfo__delete(dinfo);
642 if (ret == 0 || ret == -ENOENT) { 642 if (ret == 0 || ret == -ENOENT) {
643 pr_warning("Specified source line is not found.\n"); 643 pr_warning("Specified source line is not found.\n");
644 return -ENOENT; 644 return -ENOENT;
645 } else if (ret < 0) { 645 } else if (ret < 0) {
646 pr_warning("Debuginfo analysis failed.\n"); 646 pr_warning("Debuginfo analysis failed.\n");
647 return ret; 647 return ret;
648 } 648 }
649 649
650 /* Convert source file path */ 650 /* Convert source file path */
651 tmp = lr->path; 651 tmp = lr->path;
652 ret = get_real_path(tmp, lr->comp_dir, &lr->path); 652 ret = get_real_path(tmp, lr->comp_dir, &lr->path);
653 free(tmp); /* Free old path */ 653 free(tmp); /* Free old path */
654 if (ret < 0) { 654 if (ret < 0) {
655 pr_warning("Failed to find source file path.\n"); 655 pr_warning("Failed to find source file path.\n");
656 return ret; 656 return ret;
657 } 657 }
658 658
659 setup_pager(); 659 setup_pager();
660 660
661 if (lr->function) 661 if (lr->function)
662 fprintf(stdout, "<%s@%s:%d>\n", lr->function, lr->path, 662 fprintf(stdout, "<%s@%s:%d>\n", lr->function, lr->path,
663 lr->start - lr->offset); 663 lr->start - lr->offset);
664 else 664 else
665 fprintf(stdout, "<%s:%d>\n", lr->path, lr->start); 665 fprintf(stdout, "<%s:%d>\n", lr->path, lr->start);
666 666
667 fp = fopen(lr->path, "r"); 667 fp = fopen(lr->path, "r");
668 if (fp == NULL) { 668 if (fp == NULL) {
669 pr_warning("Failed to open %s: %s\n", lr->path, 669 pr_warning("Failed to open %s: %s\n", lr->path,
670 strerror_r(errno, sbuf, sizeof(sbuf))); 670 strerror_r(errno, sbuf, sizeof(sbuf)));
671 return -errno; 671 return -errno;
672 } 672 }
673 /* Skip to starting line number */ 673 /* Skip to starting line number */
674 while (l < lr->start) { 674 while (l < lr->start) {
675 ret = skip_one_line(fp, l++); 675 ret = skip_one_line(fp, l++);
676 if (ret < 0) 676 if (ret < 0)
677 goto end; 677 goto end;
678 } 678 }
679 679
680 intlist__for_each(ln, lr->line_list) { 680 intlist__for_each(ln, lr->line_list) {
681 for (; ln->i > l; l++) { 681 for (; ln->i > l; l++) {
682 ret = show_one_line(fp, l - lr->offset); 682 ret = show_one_line(fp, l - lr->offset);
683 if (ret < 0) 683 if (ret < 0)
684 goto end; 684 goto end;
685 } 685 }
686 ret = show_one_line_with_num(fp, l++ - lr->offset); 686 ret = show_one_line_with_num(fp, l++ - lr->offset);
687 if (ret < 0) 687 if (ret < 0)
688 goto end; 688 goto end;
689 } 689 }
690 690
691 if (lr->end == INT_MAX) 691 if (lr->end == INT_MAX)
692 lr->end = l + NR_ADDITIONAL_LINES; 692 lr->end = l + NR_ADDITIONAL_LINES;
693 while (l <= lr->end) { 693 while (l <= lr->end) {
694 ret = show_one_line_or_eof(fp, l++ - lr->offset); 694 ret = show_one_line_or_eof(fp, l++ - lr->offset);
695 if (ret <= 0) 695 if (ret <= 0)
696 break; 696 break;
697 } 697 }
698 end: 698 end:
699 fclose(fp); 699 fclose(fp);
700 return ret; 700 return ret;
701 } 701 }
702 702
703 int show_line_range(struct line_range *lr, const char *module, bool user) 703 int show_line_range(struct line_range *lr, const char *module, bool user)
704 { 704 {
705 int ret; 705 int ret;
706 706
707 ret = init_symbol_maps(user); 707 ret = init_symbol_maps(user);
708 if (ret < 0) 708 if (ret < 0)
709 return ret; 709 return ret;
710 ret = __show_line_range(lr, module); 710 ret = __show_line_range(lr, module);
711 exit_symbol_maps(); 711 exit_symbol_maps();
712 712
713 return ret; 713 return ret;
714 } 714 }
715 715
716 static int show_available_vars_at(struct debuginfo *dinfo, 716 static int show_available_vars_at(struct debuginfo *dinfo,
717 struct perf_probe_event *pev, 717 struct perf_probe_event *pev,
718 int max_vls, struct strfilter *_filter, 718 int max_vls, struct strfilter *_filter,
719 bool externs) 719 bool externs)
720 { 720 {
721 char *buf; 721 char *buf;
722 int ret, i, nvars; 722 int ret, i, nvars;
723 struct str_node *node; 723 struct str_node *node;
724 struct variable_list *vls = NULL, *vl; 724 struct variable_list *vls = NULL, *vl;
725 const char *var; 725 const char *var;
726 726
727 buf = synthesize_perf_probe_point(&pev->point); 727 buf = synthesize_perf_probe_point(&pev->point);
728 if (!buf) 728 if (!buf)
729 return -EINVAL; 729 return -EINVAL;
730 pr_debug("Searching variables at %s\n", buf); 730 pr_debug("Searching variables at %s\n", buf);
731 731
732 ret = debuginfo__find_available_vars_at(dinfo, pev, &vls, 732 ret = debuginfo__find_available_vars_at(dinfo, pev, &vls,
733 max_vls, externs); 733 max_vls, externs);
734 if (ret <= 0) { 734 if (ret <= 0) {
735 if (ret == 0 || ret == -ENOENT) { 735 if (ret == 0 || ret == -ENOENT) {
736 pr_err("Failed to find the address of %s\n", buf); 736 pr_err("Failed to find the address of %s\n", buf);
737 ret = -ENOENT; 737 ret = -ENOENT;
738 } else 738 } else
739 pr_warning("Debuginfo analysis failed.\n"); 739 pr_warning("Debuginfo analysis failed.\n");
740 goto end; 740 goto end;
741 } 741 }
742 742
743 /* Some variables are found */ 743 /* Some variables are found */
744 fprintf(stdout, "Available variables at %s\n", buf); 744 fprintf(stdout, "Available variables at %s\n", buf);
745 for (i = 0; i < ret; i++) { 745 for (i = 0; i < ret; i++) {
746 vl = &vls[i]; 746 vl = &vls[i];
747 /* 747 /*
748 * A probe point might be converted to 748 * A probe point might be converted to
749 * several trace points. 749 * several trace points.
750 */ 750 */
751 fprintf(stdout, "\t@<%s+%lu>\n", vl->point.symbol, 751 fprintf(stdout, "\t@<%s+%lu>\n", vl->point.symbol,
752 vl->point.offset); 752 vl->point.offset);
753 zfree(&vl->point.symbol); 753 zfree(&vl->point.symbol);
754 nvars = 0; 754 nvars = 0;
755 if (vl->vars) { 755 if (vl->vars) {
756 strlist__for_each(node, vl->vars) { 756 strlist__for_each(node, vl->vars) {
757 var = strchr(node->s, '\t') + 1; 757 var = strchr(node->s, '\t') + 1;
758 if (strfilter__compare(_filter, var)) { 758 if (strfilter__compare(_filter, var)) {
759 fprintf(stdout, "\t\t%s\n", node->s); 759 fprintf(stdout, "\t\t%s\n", node->s);
760 nvars++; 760 nvars++;
761 } 761 }
762 } 762 }
763 strlist__delete(vl->vars); 763 strlist__delete(vl->vars);
764 } 764 }
765 if (nvars == 0) 765 if (nvars == 0)
766 fprintf(stdout, "\t\t(No matched variables)\n"); 766 fprintf(stdout, "\t\t(No matched variables)\n");
767 } 767 }
768 free(vls); 768 free(vls);
769 end: 769 end:
770 free(buf); 770 free(buf);
771 return ret; 771 return ret;
772 } 772 }
773 773
774 /* Show available variables on given probe point */ 774 /* Show available variables on given probe point */
775 int show_available_vars(struct perf_probe_event *pevs, int npevs, 775 int show_available_vars(struct perf_probe_event *pevs, int npevs,
776 int max_vls, const char *module, 776 int max_vls, const char *module,
777 struct strfilter *_filter, bool externs) 777 struct strfilter *_filter, bool externs)
778 { 778 {
779 int i, ret = 0; 779 int i, ret = 0;
780 struct debuginfo *dinfo; 780 struct debuginfo *dinfo;
781 781
782 ret = init_symbol_maps(pevs->uprobes); 782 ret = init_symbol_maps(pevs->uprobes);
783 if (ret < 0) 783 if (ret < 0)
784 return ret; 784 return ret;
785 785
786 dinfo = open_debuginfo(module, false); 786 dinfo = open_debuginfo(module, false);
787 if (!dinfo) { 787 if (!dinfo) {
788 ret = -ENOENT; 788 ret = -ENOENT;
789 goto out; 789 goto out;
790 } 790 }
791 791
792 setup_pager(); 792 setup_pager();
793 793
794 for (i = 0; i < npevs && ret >= 0; i++) 794 for (i = 0; i < npevs && ret >= 0; i++)
795 ret = show_available_vars_at(dinfo, &pevs[i], max_vls, _filter, 795 ret = show_available_vars_at(dinfo, &pevs[i], max_vls, _filter,
796 externs); 796 externs);
797 797
798 debuginfo__delete(dinfo); 798 debuginfo__delete(dinfo);
799 out: 799 out:
800 exit_symbol_maps(); 800 exit_symbol_maps();
801 return ret; 801 return ret;
802 } 802 }
803 803
804 #else /* !HAVE_DWARF_SUPPORT */ 804 #else /* !HAVE_DWARF_SUPPORT */
805 805
806 static int 806 static int
807 find_perf_probe_point_from_dwarf(struct probe_trace_point *tp __maybe_unused, 807 find_perf_probe_point_from_dwarf(struct probe_trace_point *tp __maybe_unused,
808 struct perf_probe_point *pp __maybe_unused, 808 struct perf_probe_point *pp __maybe_unused,
809 bool is_kprobe __maybe_unused) 809 bool is_kprobe __maybe_unused)
810 { 810 {
811 return -ENOSYS; 811 return -ENOSYS;
812 } 812 }
813 813
814 static int try_to_find_probe_trace_events(struct perf_probe_event *pev, 814 static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
815 struct probe_trace_event **tevs __maybe_unused, 815 struct probe_trace_event **tevs __maybe_unused,
816 int max_tevs __maybe_unused, 816 int max_tevs __maybe_unused,
817 const char *target __maybe_unused) 817 const char *target __maybe_unused)
818 { 818 {
819 if (perf_probe_event_need_dwarf(pev)) { 819 if (perf_probe_event_need_dwarf(pev)) {
820 pr_warning("Debuginfo-analysis is not supported.\n"); 820 pr_warning("Debuginfo-analysis is not supported.\n");
821 return -ENOSYS; 821 return -ENOSYS;
822 } 822 }
823 823
824 return 0; 824 return 0;
825 } 825 }
826 826
827 int show_line_range(struct line_range *lr __maybe_unused, 827 int show_line_range(struct line_range *lr __maybe_unused,
828 const char *module __maybe_unused, 828 const char *module __maybe_unused,
829 bool user __maybe_unused) 829 bool user __maybe_unused)
830 { 830 {
831 pr_warning("Debuginfo-analysis is not supported.\n"); 831 pr_warning("Debuginfo-analysis is not supported.\n");
832 return -ENOSYS; 832 return -ENOSYS;
833 } 833 }
834 834
835 int show_available_vars(struct perf_probe_event *pevs __maybe_unused, 835 int show_available_vars(struct perf_probe_event *pevs __maybe_unused,
836 int npevs __maybe_unused, int max_vls __maybe_unused, 836 int npevs __maybe_unused, int max_vls __maybe_unused,
837 const char *module __maybe_unused, 837 const char *module __maybe_unused,
838 struct strfilter *filter __maybe_unused, 838 struct strfilter *filter __maybe_unused,
839 bool externs __maybe_unused) 839 bool externs __maybe_unused)
840 { 840 {
841 pr_warning("Debuginfo-analysis is not supported.\n"); 841 pr_warning("Debuginfo-analysis is not supported.\n");
842 return -ENOSYS; 842 return -ENOSYS;
843 } 843 }
844 #endif 844 #endif
845 845
846 void line_range__clear(struct line_range *lr) 846 void line_range__clear(struct line_range *lr)
847 { 847 {
848 free(lr->function); 848 free(lr->function);
849 free(lr->file); 849 free(lr->file);
850 free(lr->path); 850 free(lr->path);
851 free(lr->comp_dir); 851 free(lr->comp_dir);
852 intlist__delete(lr->line_list); 852 intlist__delete(lr->line_list);
853 memset(lr, 0, sizeof(*lr)); 853 memset(lr, 0, sizeof(*lr));
854 } 854 }
855 855
856 int line_range__init(struct line_range *lr) 856 int line_range__init(struct line_range *lr)
857 { 857 {
858 memset(lr, 0, sizeof(*lr)); 858 memset(lr, 0, sizeof(*lr));
859 lr->line_list = intlist__new(NULL); 859 lr->line_list = intlist__new(NULL);
860 if (!lr->line_list) 860 if (!lr->line_list)
861 return -ENOMEM; 861 return -ENOMEM;
862 else 862 else
863 return 0; 863 return 0;
864 } 864 }
865 865
866 static int parse_line_num(char **ptr, int *val, const char *what) 866 static int parse_line_num(char **ptr, int *val, const char *what)
867 { 867 {
868 const char *start = *ptr; 868 const char *start = *ptr;
869 869
870 errno = 0; 870 errno = 0;
871 *val = strtol(*ptr, ptr, 0); 871 *val = strtol(*ptr, ptr, 0);
872 if (errno || *ptr == start) { 872 if (errno || *ptr == start) {
873 semantic_error("'%s' is not a valid number.\n", what); 873 semantic_error("'%s' is not a valid number.\n", what);
874 return -EINVAL; 874 return -EINVAL;
875 } 875 }
876 return 0; 876 return 0;
877 } 877 }
878 878
879 /* 879 /*
880 * Stuff 'lr' according to the line range described by 'arg'. 880 * Stuff 'lr' according to the line range described by 'arg'.
881 * The line range syntax is described by: 881 * The line range syntax is described by:
882 * 882 *
883 * SRC[:SLN[+NUM|-ELN]] 883 * SRC[:SLN[+NUM|-ELN]]
884 * FNC[@SRC][:SLN[+NUM|-ELN]] 884 * FNC[@SRC][:SLN[+NUM|-ELN]]
885 */ 885 */
886 int parse_line_range_desc(const char *arg, struct line_range *lr) 886 int parse_line_range_desc(const char *arg, struct line_range *lr)
887 { 887 {
888 char *range, *file, *name = strdup(arg); 888 char *range, *file, *name = strdup(arg);
889 int err; 889 int err;
890 890
891 if (!name) 891 if (!name)
892 return -ENOMEM; 892 return -ENOMEM;
893 893
894 lr->start = 0; 894 lr->start = 0;
895 lr->end = INT_MAX; 895 lr->end = INT_MAX;
896 896
897 range = strchr(name, ':'); 897 range = strchr(name, ':');
898 if (range) { 898 if (range) {
899 *range++ = '\0'; 899 *range++ = '\0';
900 900
901 err = parse_line_num(&range, &lr->start, "start line"); 901 err = parse_line_num(&range, &lr->start, "start line");
902 if (err) 902 if (err)
903 goto err; 903 goto err;
904 904
905 if (*range == '+' || *range == '-') { 905 if (*range == '+' || *range == '-') {
906 const char c = *range++; 906 const char c = *range++;
907 907
908 err = parse_line_num(&range, &lr->end, "end line"); 908 err = parse_line_num(&range, &lr->end, "end line");
909 if (err) 909 if (err)
910 goto err; 910 goto err;
911 911
912 if (c == '+') { 912 if (c == '+') {
913 lr->end += lr->start; 913 lr->end += lr->start;
914 /* 914 /*
915 * Adjust the number of lines here. 915 * Adjust the number of lines here.
916 * If the number of lines == 1, the 916 * If the number of lines == 1, the
917 * the end of line should be equal to 917 * the end of line should be equal to
918 * the start of line. 918 * the start of line.
919 */ 919 */
920 lr->end--; 920 lr->end--;
921 } 921 }
922 } 922 }
923 923
924 pr_debug("Line range is %d to %d\n", lr->start, lr->end); 924 pr_debug("Line range is %d to %d\n", lr->start, lr->end);
925 925
926 err = -EINVAL; 926 err = -EINVAL;
927 if (lr->start > lr->end) { 927 if (lr->start > lr->end) {
928 semantic_error("Start line must be smaller" 928 semantic_error("Start line must be smaller"
929 " than end line.\n"); 929 " than end line.\n");
930 goto err; 930 goto err;
931 } 931 }
932 if (*range != '\0') { 932 if (*range != '\0') {
933 semantic_error("Tailing with invalid str '%s'.\n", range); 933 semantic_error("Tailing with invalid str '%s'.\n", range);
934 goto err; 934 goto err;
935 } 935 }
936 } 936 }
937 937
938 file = strchr(name, '@'); 938 file = strchr(name, '@');
939 if (file) { 939 if (file) {
940 *file = '\0'; 940 *file = '\0';
941 lr->file = strdup(++file); 941 lr->file = strdup(++file);
942 if (lr->file == NULL) { 942 if (lr->file == NULL) {
943 err = -ENOMEM; 943 err = -ENOMEM;
944 goto err; 944 goto err;
945 } 945 }
946 lr->function = name; 946 lr->function = name;
947 } else if (strchr(name, '.')) 947 } else if (strchr(name, '.'))
948 lr->file = name; 948 lr->file = name;
949 else 949 else
950 lr->function = name; 950 lr->function = name;
951 951
952 return 0; 952 return 0;
953 err: 953 err:
954 free(name); 954 free(name);
955 return err; 955 return err;
956 } 956 }
957 957
958 /* Check the name is good for event/group */ 958 /* Check the name is good for event/group */
959 static bool check_event_name(const char *name) 959 static bool check_event_name(const char *name)
960 { 960 {
961 if (!isalpha(*name) && *name != '_') 961 if (!isalpha(*name) && *name != '_')
962 return false; 962 return false;
963 while (*++name != '\0') { 963 while (*++name != '\0') {
964 if (!isalpha(*name) && !isdigit(*name) && *name != '_') 964 if (!isalpha(*name) && !isdigit(*name) && *name != '_')
965 return false; 965 return false;
966 } 966 }
967 return true; 967 return true;
968 } 968 }
969 969
970 /* Parse probepoint definition. */ 970 /* Parse probepoint definition. */
971 static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev) 971 static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
972 { 972 {
973 struct perf_probe_point *pp = &pev->point; 973 struct perf_probe_point *pp = &pev->point;
974 char *ptr, *tmp; 974 char *ptr, *tmp;
975 char c, nc = 0; 975 char c, nc = 0;
976 /* 976 /*
977 * <Syntax> 977 * <Syntax>
978 * perf probe [EVENT=]SRC[:LN|;PTN] 978 * perf probe [EVENT=]SRC[:LN|;PTN]
979 * perf probe [EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT] 979 * perf probe [EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT]
980 * 980 *
981 * TODO:Group name support 981 * TODO:Group name support
982 */ 982 */
983 983
984 ptr = strpbrk(arg, ";=@+%"); 984 ptr = strpbrk(arg, ";=@+%");
985 if (ptr && *ptr == '=') { /* Event name */ 985 if (ptr && *ptr == '=') { /* Event name */
986 *ptr = '\0'; 986 *ptr = '\0';
987 tmp = ptr + 1; 987 tmp = ptr + 1;
988 if (strchr(arg, ':')) { 988 if (strchr(arg, ':')) {
989 semantic_error("Group name is not supported yet.\n"); 989 semantic_error("Group name is not supported yet.\n");
990 return -ENOTSUP; 990 return -ENOTSUP;
991 } 991 }
992 if (!check_event_name(arg)) { 992 if (!check_event_name(arg)) {
993 semantic_error("%s is bad for event name -it must " 993 semantic_error("%s is bad for event name -it must "
994 "follow C symbol-naming rule.\n", arg); 994 "follow C symbol-naming rule.\n", arg);
995 return -EINVAL; 995 return -EINVAL;
996 } 996 }
997 pev->event = strdup(arg); 997 pev->event = strdup(arg);
998 if (pev->event == NULL) 998 if (pev->event == NULL)
999 return -ENOMEM; 999 return -ENOMEM;
1000 pev->group = NULL; 1000 pev->group = NULL;
1001 arg = tmp; 1001 arg = tmp;
1002 } 1002 }
1003 1003
1004 ptr = strpbrk(arg, ";:+@%"); 1004 ptr = strpbrk(arg, ";:+@%");
1005 if (ptr) { 1005 if (ptr) {
1006 nc = *ptr; 1006 nc = *ptr;
1007 *ptr++ = '\0'; 1007 *ptr++ = '\0';
1008 } 1008 }
1009 1009
1010 tmp = strdup(arg); 1010 tmp = strdup(arg);
1011 if (tmp == NULL) 1011 if (tmp == NULL)
1012 return -ENOMEM; 1012 return -ENOMEM;
1013 1013
1014 /* Check arg is function or file and copy it */ 1014 /* Check arg is function or file and copy it */
1015 if (strchr(tmp, '.')) /* File */ 1015 if (strchr(tmp, '.')) /* File */
1016 pp->file = tmp; 1016 pp->file = tmp;
1017 else /* Function */ 1017 else /* Function */
1018 pp->function = tmp; 1018 pp->function = tmp;
1019 1019
1020 /* Parse other options */ 1020 /* Parse other options */
1021 while (ptr) { 1021 while (ptr) {
1022 arg = ptr; 1022 arg = ptr;
1023 c = nc; 1023 c = nc;
1024 if (c == ';') { /* Lazy pattern must be the last part */ 1024 if (c == ';') { /* Lazy pattern must be the last part */
1025 pp->lazy_line = strdup(arg); 1025 pp->lazy_line = strdup(arg);
1026 if (pp->lazy_line == NULL) 1026 if (pp->lazy_line == NULL)
1027 return -ENOMEM; 1027 return -ENOMEM;
1028 break; 1028 break;
1029 } 1029 }
1030 ptr = strpbrk(arg, ";:+@%"); 1030 ptr = strpbrk(arg, ";:+@%");
1031 if (ptr) { 1031 if (ptr) {
1032 nc = *ptr; 1032 nc = *ptr;
1033 *ptr++ = '\0'; 1033 *ptr++ = '\0';
1034 } 1034 }
1035 switch (c) { 1035 switch (c) {
1036 case ':': /* Line number */ 1036 case ':': /* Line number */
1037 pp->line = strtoul(arg, &tmp, 0); 1037 pp->line = strtoul(arg, &tmp, 0);
1038 if (*tmp != '\0') { 1038 if (*tmp != '\0') {
1039 semantic_error("There is non-digit char" 1039 semantic_error("There is non-digit char"
1040 " in line number.\n"); 1040 " in line number.\n");
1041 return -EINVAL; 1041 return -EINVAL;
1042 } 1042 }
1043 break; 1043 break;
1044 case '+': /* Byte offset from a symbol */ 1044 case '+': /* Byte offset from a symbol */
1045 pp->offset = strtoul(arg, &tmp, 0); 1045 pp->offset = strtoul(arg, &tmp, 0);
1046 if (*tmp != '\0') { 1046 if (*tmp != '\0') {
1047 semantic_error("There is non-digit character" 1047 semantic_error("There is non-digit character"
1048 " in offset.\n"); 1048 " in offset.\n");
1049 return -EINVAL; 1049 return -EINVAL;
1050 } 1050 }
1051 break; 1051 break;
1052 case '@': /* File name */ 1052 case '@': /* File name */
1053 if (pp->file) { 1053 if (pp->file) {
1054 semantic_error("SRC@SRC is not allowed.\n"); 1054 semantic_error("SRC@SRC is not allowed.\n");
1055 return -EINVAL; 1055 return -EINVAL;
1056 } 1056 }
1057 pp->file = strdup(arg); 1057 pp->file = strdup(arg);
1058 if (pp->file == NULL) 1058 if (pp->file == NULL)
1059 return -ENOMEM; 1059 return -ENOMEM;
1060 break; 1060 break;
1061 case '%': /* Probe places */ 1061 case '%': /* Probe places */
1062 if (strcmp(arg, "return") == 0) { 1062 if (strcmp(arg, "return") == 0) {
1063 pp->retprobe = 1; 1063 pp->retprobe = 1;
1064 } else { /* Others not supported yet */ 1064 } else { /* Others not supported yet */
1065 semantic_error("%%%s is not supported.\n", arg); 1065 semantic_error("%%%s is not supported.\n", arg);
1066 return -ENOTSUP; 1066 return -ENOTSUP;
1067 } 1067 }
1068 break; 1068 break;
1069 default: /* Buggy case */ 1069 default: /* Buggy case */
1070 pr_err("This program has a bug at %s:%d.\n", 1070 pr_err("This program has a bug at %s:%d.\n",
1071 __FILE__, __LINE__); 1071 __FILE__, __LINE__);
1072 return -ENOTSUP; 1072 return -ENOTSUP;
1073 break; 1073 break;
1074 } 1074 }
1075 } 1075 }
1076 1076
1077 /* Exclusion check */ 1077 /* Exclusion check */
1078 if (pp->lazy_line && pp->line) { 1078 if (pp->lazy_line && pp->line) {
1079 semantic_error("Lazy pattern can't be used with" 1079 semantic_error("Lazy pattern can't be used with"
1080 " line number.\n"); 1080 " line number.\n");
1081 return -EINVAL; 1081 return -EINVAL;
1082 } 1082 }
1083 1083
1084 if (pp->lazy_line && pp->offset) { 1084 if (pp->lazy_line && pp->offset) {
1085 semantic_error("Lazy pattern can't be used with offset.\n"); 1085 semantic_error("Lazy pattern can't be used with offset.\n");
1086 return -EINVAL; 1086 return -EINVAL;
1087 } 1087 }
1088 1088
1089 if (pp->line && pp->offset) { 1089 if (pp->line && pp->offset) {
1090 semantic_error("Offset can't be used with line number.\n"); 1090 semantic_error("Offset can't be used with line number.\n");
1091 return -EINVAL; 1091 return -EINVAL;
1092 } 1092 }
1093 1093
1094 if (!pp->line && !pp->lazy_line && pp->file && !pp->function) { 1094 if (!pp->line && !pp->lazy_line && pp->file && !pp->function) {
1095 semantic_error("File always requires line number or " 1095 semantic_error("File always requires line number or "
1096 "lazy pattern.\n"); 1096 "lazy pattern.\n");
1097 return -EINVAL; 1097 return -EINVAL;
1098 } 1098 }
1099 1099
1100 if (pp->offset && !pp->function) { 1100 if (pp->offset && !pp->function) {
1101 semantic_error("Offset requires an entry function.\n"); 1101 semantic_error("Offset requires an entry function.\n");
1102 return -EINVAL; 1102 return -EINVAL;
1103 } 1103 }
1104 1104
1105 if (pp->retprobe && !pp->function) { 1105 if (pp->retprobe && !pp->function) {
1106 semantic_error("Return probe requires an entry function.\n"); 1106 semantic_error("Return probe requires an entry function.\n");
1107 return -EINVAL; 1107 return -EINVAL;
1108 } 1108 }
1109 1109
1110 if ((pp->offset || pp->line || pp->lazy_line) && pp->retprobe) { 1110 if ((pp->offset || pp->line || pp->lazy_line) && pp->retprobe) {
1111 semantic_error("Offset/Line/Lazy pattern can't be used with " 1111 semantic_error("Offset/Line/Lazy pattern can't be used with "
1112 "return probe.\n"); 1112 "return probe.\n");
1113 return -EINVAL; 1113 return -EINVAL;
1114 } 1114 }
1115 1115
1116 pr_debug("symbol:%s file:%s line:%d offset:%lu return:%d lazy:%s\n", 1116 pr_debug("symbol:%s file:%s line:%d offset:%lu return:%d lazy:%s\n",
1117 pp->function, pp->file, pp->line, pp->offset, pp->retprobe, 1117 pp->function, pp->file, pp->line, pp->offset, pp->retprobe,
1118 pp->lazy_line); 1118 pp->lazy_line);
1119 return 0; 1119 return 0;
1120 } 1120 }
1121 1121
1122 /* Parse perf-probe event argument */ 1122 /* Parse perf-probe event argument */
1123 static int parse_perf_probe_arg(char *str, struct perf_probe_arg *arg) 1123 static int parse_perf_probe_arg(char *str, struct perf_probe_arg *arg)
1124 { 1124 {
1125 char *tmp, *goodname; 1125 char *tmp, *goodname;
1126 struct perf_probe_arg_field **fieldp; 1126 struct perf_probe_arg_field **fieldp;
1127 1127
1128 pr_debug("parsing arg: %s into ", str); 1128 pr_debug("parsing arg: %s into ", str);
1129 1129
1130 tmp = strchr(str, '='); 1130 tmp = strchr(str, '=');
1131 if (tmp) { 1131 if (tmp) {
1132 arg->name = strndup(str, tmp - str); 1132 arg->name = strndup(str, tmp - str);
1133 if (arg->name == NULL) 1133 if (arg->name == NULL)
1134 return -ENOMEM; 1134 return -ENOMEM;
1135 pr_debug("name:%s ", arg->name); 1135 pr_debug("name:%s ", arg->name);
1136 str = tmp + 1; 1136 str = tmp + 1;
1137 } 1137 }
1138 1138
1139 tmp = strchr(str, ':'); 1139 tmp = strchr(str, ':');
1140 if (tmp) { /* Type setting */ 1140 if (tmp) { /* Type setting */
1141 *tmp = '\0'; 1141 *tmp = '\0';
1142 arg->type = strdup(tmp + 1); 1142 arg->type = strdup(tmp + 1);
1143 if (arg->type == NULL) 1143 if (arg->type == NULL)
1144 return -ENOMEM; 1144 return -ENOMEM;
1145 pr_debug("type:%s ", arg->type); 1145 pr_debug("type:%s ", arg->type);
1146 } 1146 }
1147 1147
1148 tmp = strpbrk(str, "-.["); 1148 tmp = strpbrk(str, "-.[");
1149 if (!is_c_varname(str) || !tmp) { 1149 if (!is_c_varname(str) || !tmp) {
1150 /* A variable, register, symbol or special value */ 1150 /* A variable, register, symbol or special value */
1151 arg->var = strdup(str); 1151 arg->var = strdup(str);
1152 if (arg->var == NULL) 1152 if (arg->var == NULL)
1153 return -ENOMEM; 1153 return -ENOMEM;
1154 pr_debug("%s\n", arg->var); 1154 pr_debug("%s\n", arg->var);
1155 return 0; 1155 return 0;
1156 } 1156 }
1157 1157
1158 /* Structure fields or array element */ 1158 /* Structure fields or array element */
1159 arg->var = strndup(str, tmp - str); 1159 arg->var = strndup(str, tmp - str);
1160 if (arg->var == NULL) 1160 if (arg->var == NULL)
1161 return -ENOMEM; 1161 return -ENOMEM;
1162 goodname = arg->var; 1162 goodname = arg->var;
1163 pr_debug("%s, ", arg->var); 1163 pr_debug("%s, ", arg->var);
1164 fieldp = &arg->field; 1164 fieldp = &arg->field;
1165 1165
1166 do { 1166 do {
1167 *fieldp = zalloc(sizeof(struct perf_probe_arg_field)); 1167 *fieldp = zalloc(sizeof(struct perf_probe_arg_field));
1168 if (*fieldp == NULL) 1168 if (*fieldp == NULL)
1169 return -ENOMEM; 1169 return -ENOMEM;
1170 if (*tmp == '[') { /* Array */ 1170 if (*tmp == '[') { /* Array */
1171 str = tmp; 1171 str = tmp;
1172 (*fieldp)->index = strtol(str + 1, &tmp, 0); 1172 (*fieldp)->index = strtol(str + 1, &tmp, 0);
1173 (*fieldp)->ref = true; 1173 (*fieldp)->ref = true;
1174 if (*tmp != ']' || tmp == str + 1) { 1174 if (*tmp != ']' || tmp == str + 1) {
1175 semantic_error("Array index must be a" 1175 semantic_error("Array index must be a"
1176 " number.\n"); 1176 " number.\n");
1177 return -EINVAL; 1177 return -EINVAL;
1178 } 1178 }
1179 tmp++; 1179 tmp++;
1180 if (*tmp == '\0') 1180 if (*tmp == '\0')
1181 tmp = NULL; 1181 tmp = NULL;
1182 } else { /* Structure */ 1182 } else { /* Structure */
1183 if (*tmp == '.') { 1183 if (*tmp == '.') {
1184 str = tmp + 1; 1184 str = tmp + 1;
1185 (*fieldp)->ref = false; 1185 (*fieldp)->ref = false;
1186 } else if (tmp[1] == '>') { 1186 } else if (tmp[1] == '>') {
1187 str = tmp + 2; 1187 str = tmp + 2;
1188 (*fieldp)->ref = true; 1188 (*fieldp)->ref = true;
1189 } else { 1189 } else {
1190 semantic_error("Argument parse error: %s\n", 1190 semantic_error("Argument parse error: %s\n",
1191 str); 1191 str);
1192 return -EINVAL; 1192 return -EINVAL;
1193 } 1193 }
1194 tmp = strpbrk(str, "-.["); 1194 tmp = strpbrk(str, "-.[");
1195 } 1195 }
1196 if (tmp) { 1196 if (tmp) {
1197 (*fieldp)->name = strndup(str, tmp - str); 1197 (*fieldp)->name = strndup(str, tmp - str);
1198 if ((*fieldp)->name == NULL) 1198 if ((*fieldp)->name == NULL)
1199 return -ENOMEM; 1199 return -ENOMEM;
1200 if (*str != '[') 1200 if (*str != '[')
1201 goodname = (*fieldp)->name; 1201 goodname = (*fieldp)->name;
1202 pr_debug("%s(%d), ", (*fieldp)->name, (*fieldp)->ref); 1202 pr_debug("%s(%d), ", (*fieldp)->name, (*fieldp)->ref);
1203 fieldp = &(*fieldp)->next; 1203 fieldp = &(*fieldp)->next;
1204 } 1204 }
1205 } while (tmp); 1205 } while (tmp);
1206 (*fieldp)->name = strdup(str); 1206 (*fieldp)->name = strdup(str);
1207 if ((*fieldp)->name == NULL) 1207 if ((*fieldp)->name == NULL)
1208 return -ENOMEM; 1208 return -ENOMEM;
1209 if (*str != '[') 1209 if (*str != '[')
1210 goodname = (*fieldp)->name; 1210 goodname = (*fieldp)->name;
1211 pr_debug("%s(%d)\n", (*fieldp)->name, (*fieldp)->ref); 1211 pr_debug("%s(%d)\n", (*fieldp)->name, (*fieldp)->ref);
1212 1212
1213 /* If no name is specified, set the last field name (not array index)*/ 1213 /* If no name is specified, set the last field name (not array index)*/
1214 if (!arg->name) { 1214 if (!arg->name) {
1215 arg->name = strdup(goodname); 1215 arg->name = strdup(goodname);
1216 if (arg->name == NULL) 1216 if (arg->name == NULL)
1217 return -ENOMEM; 1217 return -ENOMEM;
1218 } 1218 }
1219 return 0; 1219 return 0;
1220 } 1220 }
1221 1221
1222 /* Parse perf-probe event command */ 1222 /* Parse perf-probe event command */
1223 int parse_perf_probe_command(const char *cmd, struct perf_probe_event *pev) 1223 int parse_perf_probe_command(const char *cmd, struct perf_probe_event *pev)
1224 { 1224 {
1225 char **argv; 1225 char **argv;
1226 int argc, i, ret = 0; 1226 int argc, i, ret = 0;
1227 1227
1228 argv = argv_split(cmd, &argc); 1228 argv = argv_split(cmd, &argc);
1229 if (!argv) { 1229 if (!argv) {
1230 pr_debug("Failed to split arguments.\n"); 1230 pr_debug("Failed to split arguments.\n");
1231 return -ENOMEM; 1231 return -ENOMEM;
1232 } 1232 }
1233 if (argc - 1 > MAX_PROBE_ARGS) { 1233 if (argc - 1 > MAX_PROBE_ARGS) {
1234 semantic_error("Too many probe arguments (%d).\n", argc - 1); 1234 semantic_error("Too many probe arguments (%d).\n", argc - 1);
1235 ret = -ERANGE; 1235 ret = -ERANGE;
1236 goto out; 1236 goto out;
1237 } 1237 }
1238 /* Parse probe point */ 1238 /* Parse probe point */
1239 ret = parse_perf_probe_point(argv[0], pev); 1239 ret = parse_perf_probe_point(argv[0], pev);
1240 if (ret < 0) 1240 if (ret < 0)
1241 goto out; 1241 goto out;
1242 1242
1243 /* Copy arguments and ensure return probe has no C argument */ 1243 /* Copy arguments and ensure return probe has no C argument */
1244 pev->nargs = argc - 1; 1244 pev->nargs = argc - 1;
1245 pev->args = zalloc(sizeof(struct perf_probe_arg) * pev->nargs); 1245 pev->args = zalloc(sizeof(struct perf_probe_arg) * pev->nargs);
1246 if (pev->args == NULL) { 1246 if (pev->args == NULL) {
1247 ret = -ENOMEM; 1247 ret = -ENOMEM;
1248 goto out; 1248 goto out;
1249 } 1249 }
1250 for (i = 0; i < pev->nargs && ret >= 0; i++) { 1250 for (i = 0; i < pev->nargs && ret >= 0; i++) {
1251 ret = parse_perf_probe_arg(argv[i + 1], &pev->args[i]); 1251 ret = parse_perf_probe_arg(argv[i + 1], &pev->args[i]);
1252 if (ret >= 0 && 1252 if (ret >= 0 &&
1253 is_c_varname(pev->args[i].var) && pev->point.retprobe) { 1253 is_c_varname(pev->args[i].var) && pev->point.retprobe) {
1254 semantic_error("You can't specify local variable for" 1254 semantic_error("You can't specify local variable for"
1255 " kretprobe.\n"); 1255 " kretprobe.\n");
1256 ret = -EINVAL; 1256 ret = -EINVAL;
1257 } 1257 }
1258 } 1258 }
1259 out: 1259 out:
1260 argv_free(argv); 1260 argv_free(argv);
1261 1261
1262 return ret; 1262 return ret;
1263 } 1263 }
1264 1264
1265 /* Return true if this perf_probe_event requires debuginfo */ 1265 /* Return true if this perf_probe_event requires debuginfo */
1266 bool perf_probe_event_need_dwarf(struct perf_probe_event *pev) 1266 bool perf_probe_event_need_dwarf(struct perf_probe_event *pev)
1267 { 1267 {
1268 int i; 1268 int i;
1269 1269
1270 if (pev->point.file || pev->point.line || pev->point.lazy_line) 1270 if (pev->point.file || pev->point.line || pev->point.lazy_line)
1271 return true; 1271 return true;
1272 1272
1273 for (i = 0; i < pev->nargs; i++) 1273 for (i = 0; i < pev->nargs; i++)
1274 if (is_c_varname(pev->args[i].var)) 1274 if (is_c_varname(pev->args[i].var))
1275 return true; 1275 return true;
1276 1276
1277 return false; 1277 return false;
1278 } 1278 }
1279 1279
1280 /* Parse probe_events event into struct probe_point */ 1280 /* Parse probe_events event into struct probe_point */
1281 static int parse_probe_trace_command(const char *cmd, 1281 static int parse_probe_trace_command(const char *cmd,
1282 struct probe_trace_event *tev) 1282 struct probe_trace_event *tev)
1283 { 1283 {
1284 struct probe_trace_point *tp = &tev->point; 1284 struct probe_trace_point *tp = &tev->point;
1285 char pr; 1285 char pr;
1286 char *p; 1286 char *p;
1287 char *argv0_str = NULL, *fmt, *fmt1_str, *fmt2_str, *fmt3_str; 1287 char *argv0_str = NULL, *fmt, *fmt1_str, *fmt2_str, *fmt3_str;
1288 int ret, i, argc; 1288 int ret, i, argc;
1289 char **argv; 1289 char **argv;
1290 1290
1291 pr_debug("Parsing probe_events: %s\n", cmd); 1291 pr_debug("Parsing probe_events: %s\n", cmd);
1292 argv = argv_split(cmd, &argc); 1292 argv = argv_split(cmd, &argc);
1293 if (!argv) { 1293 if (!argv) {
1294 pr_debug("Failed to split arguments.\n"); 1294 pr_debug("Failed to split arguments.\n");
1295 return -ENOMEM; 1295 return -ENOMEM;
1296 } 1296 }
1297 if (argc < 2) { 1297 if (argc < 2) {
1298 semantic_error("Too few probe arguments.\n"); 1298 semantic_error("Too few probe arguments.\n");
1299 ret = -ERANGE; 1299 ret = -ERANGE;
1300 goto out; 1300 goto out;
1301 } 1301 }
1302 1302
1303 /* Scan event and group name. */ 1303 /* Scan event and group name. */
1304 argv0_str = strdup(argv[0]); 1304 argv0_str = strdup(argv[0]);
1305 if (argv0_str == NULL) { 1305 if (argv0_str == NULL) {
1306 ret = -ENOMEM; 1306 ret = -ENOMEM;
1307 goto out; 1307 goto out;
1308 } 1308 }
1309 fmt1_str = strtok_r(argv0_str, ":", &fmt); 1309 fmt1_str = strtok_r(argv0_str, ":", &fmt);
1310 fmt2_str = strtok_r(NULL, "/", &fmt); 1310 fmt2_str = strtok_r(NULL, "/", &fmt);
1311 fmt3_str = strtok_r(NULL, " \t", &fmt); 1311 fmt3_str = strtok_r(NULL, " \t", &fmt);
1312 if (fmt1_str == NULL || strlen(fmt1_str) != 1 || fmt2_str == NULL 1312 if (fmt1_str == NULL || strlen(fmt1_str) != 1 || fmt2_str == NULL
1313 || fmt3_str == NULL) { 1313 || fmt3_str == NULL) {
1314 semantic_error("Failed to parse event name: %s\n", argv[0]); 1314 semantic_error("Failed to parse event name: %s\n", argv[0]);
1315 ret = -EINVAL; 1315 ret = -EINVAL;
1316 goto out; 1316 goto out;
1317 } 1317 }
1318 pr = fmt1_str[0]; 1318 pr = fmt1_str[0];
1319 tev->group = strdup(fmt2_str); 1319 tev->group = strdup(fmt2_str);
1320 tev->event = strdup(fmt3_str); 1320 tev->event = strdup(fmt3_str);
1321 if (tev->group == NULL || tev->event == NULL) { 1321 if (tev->group == NULL || tev->event == NULL) {
1322 ret = -ENOMEM; 1322 ret = -ENOMEM;
1323 goto out; 1323 goto out;
1324 } 1324 }
1325 pr_debug("Group:%s Event:%s probe:%c\n", tev->group, tev->event, pr); 1325 pr_debug("Group:%s Event:%s probe:%c\n", tev->group, tev->event, pr);
1326 1326
1327 tp->retprobe = (pr == 'r'); 1327 tp->retprobe = (pr == 'r');
1328 1328
1329 /* Scan module name(if there), function name and offset */ 1329 /* Scan module name(if there), function name and offset */
1330 p = strchr(argv[1], ':'); 1330 p = strchr(argv[1], ':');
1331 if (p) { 1331 if (p) {
1332 tp->module = strndup(argv[1], p - argv[1]); 1332 tp->module = strndup(argv[1], p - argv[1]);
1333 p++; 1333 p++;
1334 } else 1334 } else
1335 p = argv[1]; 1335 p = argv[1];
1336 fmt1_str = strtok_r(p, "+", &fmt); 1336 fmt1_str = strtok_r(p, "+", &fmt);
1337 if (fmt1_str[0] == '0') /* only the address started with 0x */ 1337 if (fmt1_str[0] == '0') /* only the address started with 0x */
1338 tp->address = strtoul(fmt1_str, NULL, 0); 1338 tp->address = strtoul(fmt1_str, NULL, 0);
1339 else { 1339 else {
1340 /* Only the symbol-based probe has offset */ 1340 /* Only the symbol-based probe has offset */
1341 tp->symbol = strdup(fmt1_str); 1341 tp->symbol = strdup(fmt1_str);
1342 if (tp->symbol == NULL) { 1342 if (tp->symbol == NULL) {
1343 ret = -ENOMEM; 1343 ret = -ENOMEM;
1344 goto out; 1344 goto out;
1345 } 1345 }
1346 fmt2_str = strtok_r(NULL, "", &fmt); 1346 fmt2_str = strtok_r(NULL, "", &fmt);
1347 if (fmt2_str == NULL) 1347 if (fmt2_str == NULL)
1348 tp->offset = 0; 1348 tp->offset = 0;
1349 else 1349 else
1350 tp->offset = strtoul(fmt2_str, NULL, 10); 1350 tp->offset = strtoul(fmt2_str, NULL, 10);
1351 } 1351 }
1352 1352
1353 tev->nargs = argc - 2; 1353 tev->nargs = argc - 2;
1354 tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs); 1354 tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs);
1355 if (tev->args == NULL) { 1355 if (tev->args == NULL) {
1356 ret = -ENOMEM; 1356 ret = -ENOMEM;
1357 goto out; 1357 goto out;
1358 } 1358 }
1359 for (i = 0; i < tev->nargs; i++) { 1359 for (i = 0; i < tev->nargs; i++) {
1360 p = strchr(argv[i + 2], '='); 1360 p = strchr(argv[i + 2], '=');
1361 if (p) /* We don't need which register is assigned. */ 1361 if (p) /* We don't need which register is assigned. */
1362 *p++ = '\0'; 1362 *p++ = '\0';
1363 else 1363 else
1364 p = argv[i + 2]; 1364 p = argv[i + 2];
1365 tev->args[i].name = strdup(argv[i + 2]); 1365 tev->args[i].name = strdup(argv[i + 2]);
1366 /* TODO: parse regs and offset */ 1366 /* TODO: parse regs and offset */
1367 tev->args[i].value = strdup(p); 1367 tev->args[i].value = strdup(p);
1368 if (tev->args[i].name == NULL || tev->args[i].value == NULL) { 1368 if (tev->args[i].name == NULL || tev->args[i].value == NULL) {
1369 ret = -ENOMEM; 1369 ret = -ENOMEM;
1370 goto out; 1370 goto out;
1371 } 1371 }
1372 } 1372 }
1373 ret = 0; 1373 ret = 0;
1374 out: 1374 out:
1375 free(argv0_str); 1375 free(argv0_str);
1376 argv_free(argv); 1376 argv_free(argv);
1377 return ret; 1377 return ret;
1378 } 1378 }
1379 1379
1380 /* Compose only probe arg */ 1380 /* Compose only probe arg */
1381 int synthesize_perf_probe_arg(struct perf_probe_arg *pa, char *buf, size_t len) 1381 int synthesize_perf_probe_arg(struct perf_probe_arg *pa, char *buf, size_t len)
1382 { 1382 {
1383 struct perf_probe_arg_field *field = pa->field; 1383 struct perf_probe_arg_field *field = pa->field;
1384 int ret; 1384 int ret;
1385 char *tmp = buf; 1385 char *tmp = buf;
1386 1386
1387 if (pa->name && pa->var) 1387 if (pa->name && pa->var)
1388 ret = e_snprintf(tmp, len, "%s=%s", pa->name, pa->var); 1388 ret = e_snprintf(tmp, len, "%s=%s", pa->name, pa->var);
1389 else 1389 else
1390 ret = e_snprintf(tmp, len, "%s", pa->name ? pa->name : pa->var); 1390 ret = e_snprintf(tmp, len, "%s", pa->name ? pa->name : pa->var);
1391 if (ret <= 0) 1391 if (ret <= 0)
1392 goto error; 1392 goto error;
1393 tmp += ret; 1393 tmp += ret;
1394 len -= ret; 1394 len -= ret;
1395 1395
1396 while (field) { 1396 while (field) {
1397 if (field->name[0] == '[') 1397 if (field->name[0] == '[')
1398 ret = e_snprintf(tmp, len, "%s", field->name); 1398 ret = e_snprintf(tmp, len, "%s", field->name);
1399 else 1399 else
1400 ret = e_snprintf(tmp, len, "%s%s", 1400 ret = e_snprintf(tmp, len, "%s%s",
1401 field->ref ? "->" : ".", field->name); 1401 field->ref ? "->" : ".", field->name);
1402 if (ret <= 0) 1402 if (ret <= 0)
1403 goto error; 1403 goto error;
1404 tmp += ret; 1404 tmp += ret;
1405 len -= ret; 1405 len -= ret;
1406 field = field->next; 1406 field = field->next;
1407 } 1407 }
1408 1408
1409 if (pa->type) { 1409 if (pa->type) {
1410 ret = e_snprintf(tmp, len, ":%s", pa->type); 1410 ret = e_snprintf(tmp, len, ":%s", pa->type);
1411 if (ret <= 0) 1411 if (ret <= 0)
1412 goto error; 1412 goto error;
1413 tmp += ret; 1413 tmp += ret;
1414 len -= ret; 1414 len -= ret;
1415 } 1415 }
1416 1416
1417 return tmp - buf; 1417 return tmp - buf;
1418 error: 1418 error:
1419 pr_debug("Failed to synthesize perf probe argument: %d\n", ret); 1419 pr_debug("Failed to synthesize perf probe argument: %d\n", ret);
1420 return ret; 1420 return ret;
1421 } 1421 }
1422 1422
1423 /* Compose only probe point (not argument) */ 1423 /* Compose only probe point (not argument) */
1424 static char *synthesize_perf_probe_point(struct perf_probe_point *pp) 1424 static char *synthesize_perf_probe_point(struct perf_probe_point *pp)
1425 { 1425 {
1426 char *buf, *tmp; 1426 char *buf, *tmp;
1427 char offs[32] = "", line[32] = "", file[32] = ""; 1427 char offs[32] = "", line[32] = "", file[32] = "";
1428 int ret, len; 1428 int ret, len;
1429 1429
1430 buf = zalloc(MAX_CMDLEN); 1430 buf = zalloc(MAX_CMDLEN);
1431 if (buf == NULL) { 1431 if (buf == NULL) {
1432 ret = -ENOMEM; 1432 ret = -ENOMEM;
1433 goto error; 1433 goto error;
1434 } 1434 }
1435 if (pp->offset) { 1435 if (pp->offset) {
1436 ret = e_snprintf(offs, 32, "+%lu", pp->offset); 1436 ret = e_snprintf(offs, 32, "+%lu", pp->offset);
1437 if (ret <= 0) 1437 if (ret <= 0)
1438 goto error; 1438 goto error;
1439 } 1439 }
1440 if (pp->line) { 1440 if (pp->line) {
1441 ret = e_snprintf(line, 32, ":%d", pp->line); 1441 ret = e_snprintf(line, 32, ":%d", pp->line);
1442 if (ret <= 0) 1442 if (ret <= 0)
1443 goto error; 1443 goto error;
1444 } 1444 }
1445 if (pp->file) { 1445 if (pp->file) {
1446 tmp = pp->file; 1446 tmp = pp->file;
1447 len = strlen(tmp); 1447 len = strlen(tmp);
1448 if (len > 30) { 1448 if (len > 30) {
1449 tmp = strchr(pp->file + len - 30, '/'); 1449 tmp = strchr(pp->file + len - 30, '/');
1450 tmp = tmp ? tmp + 1 : pp->file + len - 30; 1450 tmp = tmp ? tmp + 1 : pp->file + len - 30;
1451 } 1451 }
1452 ret = e_snprintf(file, 32, "@%s", tmp); 1452 ret = e_snprintf(file, 32, "@%s", tmp);
1453 if (ret <= 0) 1453 if (ret <= 0)
1454 goto error; 1454 goto error;
1455 } 1455 }
1456 1456
1457 if (pp->function) 1457 if (pp->function)
1458 ret = e_snprintf(buf, MAX_CMDLEN, "%s%s%s%s%s", pp->function, 1458 ret = e_snprintf(buf, MAX_CMDLEN, "%s%s%s%s%s", pp->function,
1459 offs, pp->retprobe ? "%return" : "", line, 1459 offs, pp->retprobe ? "%return" : "", line,
1460 file); 1460 file);
1461 else 1461 else
1462 ret = e_snprintf(buf, MAX_CMDLEN, "%s%s", file, line); 1462 ret = e_snprintf(buf, MAX_CMDLEN, "%s%s", file, line);
1463 if (ret <= 0) 1463 if (ret <= 0)
1464 goto error; 1464 goto error;
1465 1465
1466 return buf; 1466 return buf;
1467 error: 1467 error:
1468 pr_debug("Failed to synthesize perf probe point: %d\n", ret); 1468 pr_debug("Failed to synthesize perf probe point: %d\n", ret);
1469 free(buf); 1469 free(buf);
1470 return NULL; 1470 return NULL;
1471 } 1471 }
1472 1472
1473 #if 0 1473 #if 0
1474 char *synthesize_perf_probe_command(struct perf_probe_event *pev) 1474 char *synthesize_perf_probe_command(struct perf_probe_event *pev)
1475 { 1475 {
1476 char *buf; 1476 char *buf;
1477 int i, len, ret; 1477 int i, len, ret;
1478 1478
1479 buf = synthesize_perf_probe_point(&pev->point); 1479 buf = synthesize_perf_probe_point(&pev->point);
1480 if (!buf) 1480 if (!buf)
1481 return NULL; 1481 return NULL;
1482 1482
1483 len = strlen(buf); 1483 len = strlen(buf);
1484 for (i = 0; i < pev->nargs; i++) { 1484 for (i = 0; i < pev->nargs; i++) {
1485 ret = e_snprintf(&buf[len], MAX_CMDLEN - len, " %s", 1485 ret = e_snprintf(&buf[len], MAX_CMDLEN - len, " %s",
1486 pev->args[i].name); 1486 pev->args[i].name);
1487 if (ret <= 0) { 1487 if (ret <= 0) {
1488 free(buf); 1488 free(buf);
1489 return NULL; 1489 return NULL;
1490 } 1490 }
1491 len += ret; 1491 len += ret;
1492 } 1492 }
1493 1493
1494 return buf; 1494 return buf;
1495 } 1495 }
1496 #endif 1496 #endif
1497 1497
1498 static int __synthesize_probe_trace_arg_ref(struct probe_trace_arg_ref *ref, 1498 static int __synthesize_probe_trace_arg_ref(struct probe_trace_arg_ref *ref,
1499 char **buf, size_t *buflen, 1499 char **buf, size_t *buflen,
1500 int depth) 1500 int depth)
1501 { 1501 {
1502 int ret; 1502 int ret;
1503 if (ref->next) { 1503 if (ref->next) {
1504 depth = __synthesize_probe_trace_arg_ref(ref->next, buf, 1504 depth = __synthesize_probe_trace_arg_ref(ref->next, buf,
1505 buflen, depth + 1); 1505 buflen, depth + 1);
1506 if (depth < 0) 1506 if (depth < 0)
1507 goto out; 1507 goto out;
1508 } 1508 }
1509 1509
1510 ret = e_snprintf(*buf, *buflen, "%+ld(", ref->offset); 1510 ret = e_snprintf(*buf, *buflen, "%+ld(", ref->offset);
1511 if (ret < 0) 1511 if (ret < 0)
1512 depth = ret; 1512 depth = ret;
1513 else { 1513 else {
1514 *buf += ret; 1514 *buf += ret;
1515 *buflen -= ret; 1515 *buflen -= ret;
1516 } 1516 }
1517 out: 1517 out:
1518 return depth; 1518 return depth;
1519 1519
1520 } 1520 }
1521 1521
1522 static int synthesize_probe_trace_arg(struct probe_trace_arg *arg, 1522 static int synthesize_probe_trace_arg(struct probe_trace_arg *arg,
1523 char *buf, size_t buflen) 1523 char *buf, size_t buflen)
1524 { 1524 {
1525 struct probe_trace_arg_ref *ref = arg->ref; 1525 struct probe_trace_arg_ref *ref = arg->ref;
1526 int ret, depth = 0; 1526 int ret, depth = 0;
1527 char *tmp = buf; 1527 char *tmp = buf;
1528 1528
1529 /* Argument name or separator */ 1529 /* Argument name or separator */
1530 if (arg->name) 1530 if (arg->name)
1531 ret = e_snprintf(buf, buflen, " %s=", arg->name); 1531 ret = e_snprintf(buf, buflen, " %s=", arg->name);
1532 else 1532 else
1533 ret = e_snprintf(buf, buflen, " "); 1533 ret = e_snprintf(buf, buflen, " ");
1534 if (ret < 0) 1534 if (ret < 0)
1535 return ret; 1535 return ret;
1536 buf += ret; 1536 buf += ret;
1537 buflen -= ret; 1537 buflen -= ret;
1538 1538
1539 /* Special case: @XXX */ 1539 /* Special case: @XXX */
1540 if (arg->value[0] == '@' && arg->ref) 1540 if (arg->value[0] == '@' && arg->ref)
1541 ref = ref->next; 1541 ref = ref->next;
1542 1542
1543 /* Dereferencing arguments */ 1543 /* Dereferencing arguments */
1544 if (ref) { 1544 if (ref) {
1545 depth = __synthesize_probe_trace_arg_ref(ref, &buf, 1545 depth = __synthesize_probe_trace_arg_ref(ref, &buf,
1546 &buflen, 1); 1546 &buflen, 1);
1547 if (depth < 0) 1547 if (depth < 0)
1548 return depth; 1548 return depth;
1549 } 1549 }
1550 1550
1551 /* Print argument value */ 1551 /* Print argument value */
1552 if (arg->value[0] == '@' && arg->ref) 1552 if (arg->value[0] == '@' && arg->ref)
1553 ret = e_snprintf(buf, buflen, "%s%+ld", arg->value, 1553 ret = e_snprintf(buf, buflen, "%s%+ld", arg->value,
1554 arg->ref->offset); 1554 arg->ref->offset);
1555 else 1555 else
1556 ret = e_snprintf(buf, buflen, "%s", arg->value); 1556 ret = e_snprintf(buf, buflen, "%s", arg->value);
1557 if (ret < 0) 1557 if (ret < 0)
1558 return ret; 1558 return ret;
1559 buf += ret; 1559 buf += ret;
1560 buflen -= ret; 1560 buflen -= ret;
1561 1561
1562 /* Closing */ 1562 /* Closing */
1563 while (depth--) { 1563 while (depth--) {
1564 ret = e_snprintf(buf, buflen, ")"); 1564 ret = e_snprintf(buf, buflen, ")");
1565 if (ret < 0) 1565 if (ret < 0)
1566 return ret; 1566 return ret;
1567 buf += ret; 1567 buf += ret;
1568 buflen -= ret; 1568 buflen -= ret;
1569 } 1569 }
1570 /* Print argument type */ 1570 /* Print argument type */
1571 if (arg->type) { 1571 if (arg->type) {
1572 ret = e_snprintf(buf, buflen, ":%s", arg->type); 1572 ret = e_snprintf(buf, buflen, ":%s", arg->type);
1573 if (ret <= 0) 1573 if (ret <= 0)
1574 return ret; 1574 return ret;
1575 buf += ret; 1575 buf += ret;
1576 } 1576 }
1577 1577
1578 return buf - tmp; 1578 return buf - tmp;
1579 } 1579 }
1580 1580
1581 char *synthesize_probe_trace_command(struct probe_trace_event *tev) 1581 char *synthesize_probe_trace_command(struct probe_trace_event *tev)
1582 { 1582 {
1583 struct probe_trace_point *tp = &tev->point; 1583 struct probe_trace_point *tp = &tev->point;
1584 char *buf; 1584 char *buf;
1585 int i, len, ret; 1585 int i, len, ret;
1586 1586
1587 buf = zalloc(MAX_CMDLEN); 1587 buf = zalloc(MAX_CMDLEN);
1588 if (buf == NULL) 1588 if (buf == NULL)
1589 return NULL; 1589 return NULL;
1590 1590
1591 len = e_snprintf(buf, MAX_CMDLEN, "%c:%s/%s ", tp->retprobe ? 'r' : 'p', 1591 len = e_snprintf(buf, MAX_CMDLEN, "%c:%s/%s ", tp->retprobe ? 'r' : 'p',
1592 tev->group, tev->event); 1592 tev->group, tev->event);
1593 if (len <= 0) 1593 if (len <= 0)
1594 goto error; 1594 goto error;
1595 1595
1596 /* Uprobes must have tp->address and tp->module */ 1596 /* Uprobes must have tp->address and tp->module */
1597 if (tev->uprobes && (!tp->address || !tp->module)) 1597 if (tev->uprobes && (!tp->address || !tp->module))
1598 goto error; 1598 goto error;
1599 1599
1600 /* Use the tp->address for uprobes */ 1600 /* Use the tp->address for uprobes */
1601 if (tev->uprobes) 1601 if (tev->uprobes)
1602 ret = e_snprintf(buf + len, MAX_CMDLEN - len, "%s:0x%lx", 1602 ret = e_snprintf(buf + len, MAX_CMDLEN - len, "%s:0x%lx",
1603 tp->module, tp->address); 1603 tp->module, tp->address);
1604 else 1604 else
1605 ret = e_snprintf(buf + len, MAX_CMDLEN - len, "%s%s%s+%lu", 1605 ret = e_snprintf(buf + len, MAX_CMDLEN - len, "%s%s%s+%lu",
1606 tp->module ?: "", tp->module ? ":" : "", 1606 tp->module ?: "", tp->module ? ":" : "",
1607 tp->symbol, tp->offset); 1607 tp->symbol, tp->offset);
1608 1608
1609 if (ret <= 0) 1609 if (ret <= 0)
1610 goto error; 1610 goto error;
1611 len += ret; 1611 len += ret;
1612 1612
1613 for (i = 0; i < tev->nargs; i++) { 1613 for (i = 0; i < tev->nargs; i++) {
1614 ret = synthesize_probe_trace_arg(&tev->args[i], buf + len, 1614 ret = synthesize_probe_trace_arg(&tev->args[i], buf + len,
1615 MAX_CMDLEN - len); 1615 MAX_CMDLEN - len);
1616 if (ret <= 0) 1616 if (ret <= 0)
1617 goto error; 1617 goto error;
1618 len += ret; 1618 len += ret;
1619 } 1619 }
1620 1620
1621 return buf; 1621 return buf;
1622 error: 1622 error:
1623 free(buf); 1623 free(buf);
1624 return NULL; 1624 return NULL;
1625 } 1625 }
1626 1626
1627 static int find_perf_probe_point_from_map(struct probe_trace_point *tp, 1627 static int find_perf_probe_point_from_map(struct probe_trace_point *tp,
1628 struct perf_probe_point *pp, 1628 struct perf_probe_point *pp,
1629 bool is_kprobe) 1629 bool is_kprobe)
1630 { 1630 {
1631 struct symbol *sym = NULL; 1631 struct symbol *sym = NULL;
1632 struct map *map; 1632 struct map *map;
1633 u64 addr; 1633 u64 addr;
1634 int ret = -ENOENT; 1634 int ret = -ENOENT;
1635 1635
1636 if (!is_kprobe) { 1636 if (!is_kprobe) {
1637 map = dso__new_map(tp->module); 1637 map = dso__new_map(tp->module);
1638 if (!map) 1638 if (!map)
1639 goto out; 1639 goto out;
1640 addr = tp->address; 1640 addr = tp->address;
1641 sym = map__find_symbol(map, addr, NULL); 1641 sym = map__find_symbol(map, addr, NULL);
1642 } else { 1642 } else {
1643 addr = kernel_get_symbol_address_by_name(tp->symbol, true); 1643 addr = kernel_get_symbol_address_by_name(tp->symbol, true);
1644 if (addr) { 1644 if (addr) {
1645 addr += tp->offset; 1645 addr += tp->offset;
1646 sym = __find_kernel_function(addr, &map); 1646 sym = __find_kernel_function(addr, &map);
1647 } 1647 }
1648 } 1648 }
1649 if (!sym) 1649 if (!sym)
1650 goto out; 1650 goto out;
1651 1651
1652 pp->retprobe = tp->retprobe; 1652 pp->retprobe = tp->retprobe;
1653 pp->offset = addr - map->unmap_ip(map, sym->start); 1653 pp->offset = addr - map->unmap_ip(map, sym->start);
1654 pp->function = strdup(sym->name); 1654 pp->function = strdup(sym->name);
1655 ret = pp->function ? 0 : -ENOMEM; 1655 ret = pp->function ? 0 : -ENOMEM;
1656 1656
1657 out: 1657 out:
1658 if (map && !is_kprobe) { 1658 if (map && !is_kprobe) {
1659 dso__delete(map->dso); 1659 dso__delete(map->dso);
1660 map__delete(map); 1660 map__delete(map);
1661 } 1661 }
1662 1662
1663 return ret; 1663 return ret;
1664 } 1664 }
1665 1665
1666 static int convert_to_perf_probe_point(struct probe_trace_point *tp, 1666 static int convert_to_perf_probe_point(struct probe_trace_point *tp,
1667 struct perf_probe_point *pp, 1667 struct perf_probe_point *pp,
1668 bool is_kprobe) 1668 bool is_kprobe)
1669 { 1669 {
1670 char buf[128]; 1670 char buf[128];
1671 int ret; 1671 int ret;
1672 1672
1673 ret = find_perf_probe_point_from_dwarf(tp, pp, is_kprobe); 1673 ret = find_perf_probe_point_from_dwarf(tp, pp, is_kprobe);
1674 if (!ret) 1674 if (!ret)
1675 return 0; 1675 return 0;
1676 ret = find_perf_probe_point_from_map(tp, pp, is_kprobe); 1676 ret = find_perf_probe_point_from_map(tp, pp, is_kprobe);
1677 if (!ret) 1677 if (!ret)
1678 return 0; 1678 return 0;
1679 1679
1680 pr_debug("Failed to find probe point from both of dwarf and map.\n"); 1680 pr_debug("Failed to find probe point from both of dwarf and map.\n");
1681 1681
1682 if (tp->symbol) { 1682 if (tp->symbol) {
1683 pp->function = strdup(tp->symbol); 1683 pp->function = strdup(tp->symbol);
1684 pp->offset = tp->offset; 1684 pp->offset = tp->offset;
1685 } else if (!tp->module && !is_kprobe) { 1685 } else if (!tp->module && !is_kprobe) {
1686 ret = e_snprintf(buf, 128, "0x%" PRIx64, (u64)tp->address); 1686 ret = e_snprintf(buf, 128, "0x%" PRIx64, (u64)tp->address);
1687 if (ret < 0) 1687 if (ret < 0)
1688 return ret; 1688 return ret;
1689 pp->function = strdup(buf); 1689 pp->function = strdup(buf);
1690 pp->offset = 0; 1690 pp->offset = 0;
1691 } 1691 }
1692 if (pp->function == NULL) 1692 if (pp->function == NULL)
1693 return -ENOMEM; 1693 return -ENOMEM;
1694 1694
1695 pp->retprobe = tp->retprobe; 1695 pp->retprobe = tp->retprobe;
1696 1696
1697 return 0; 1697 return 0;
1698 } 1698 }
1699 1699
1700 static int convert_to_perf_probe_event(struct probe_trace_event *tev, 1700 static int convert_to_perf_probe_event(struct probe_trace_event *tev,
1701 struct perf_probe_event *pev, bool is_kprobe) 1701 struct perf_probe_event *pev, bool is_kprobe)
1702 { 1702 {
1703 char buf[64] = ""; 1703 char buf[64] = "";
1704 int i, ret; 1704 int i, ret;
1705 1705
1706 /* Convert event/group name */ 1706 /* Convert event/group name */
1707 pev->event = strdup(tev->event); 1707 pev->event = strdup(tev->event);
1708 pev->group = strdup(tev->group); 1708 pev->group = strdup(tev->group);
1709 if (pev->event == NULL || pev->group == NULL) 1709 if (pev->event == NULL || pev->group == NULL)
1710 return -ENOMEM; 1710 return -ENOMEM;
1711 1711
1712 /* Convert trace_point to probe_point */ 1712 /* Convert trace_point to probe_point */
1713 ret = convert_to_perf_probe_point(&tev->point, &pev->point, is_kprobe); 1713 ret = convert_to_perf_probe_point(&tev->point, &pev->point, is_kprobe);
1714 if (ret < 0) 1714 if (ret < 0)
1715 return ret; 1715 return ret;
1716 1716
1717 /* Convert trace_arg to probe_arg */ 1717 /* Convert trace_arg to probe_arg */
1718 pev->nargs = tev->nargs; 1718 pev->nargs = tev->nargs;
1719 pev->args = zalloc(sizeof(struct perf_probe_arg) * pev->nargs); 1719 pev->args = zalloc(sizeof(struct perf_probe_arg) * pev->nargs);
1720 if (pev->args == NULL) 1720 if (pev->args == NULL)
1721 return -ENOMEM; 1721 return -ENOMEM;
1722 for (i = 0; i < tev->nargs && ret >= 0; i++) { 1722 for (i = 0; i < tev->nargs && ret >= 0; i++) {
1723 if (tev->args[i].name) 1723 if (tev->args[i].name)
1724 pev->args[i].name = strdup(tev->args[i].name); 1724 pev->args[i].name = strdup(tev->args[i].name);
1725 else { 1725 else {
1726 ret = synthesize_probe_trace_arg(&tev->args[i], 1726 ret = synthesize_probe_trace_arg(&tev->args[i],
1727 buf, 64); 1727 buf, 64);
1728 pev->args[i].name = strdup(buf); 1728 pev->args[i].name = strdup(buf);
1729 } 1729 }
1730 if (pev->args[i].name == NULL && ret >= 0) 1730 if (pev->args[i].name == NULL && ret >= 0)
1731 ret = -ENOMEM; 1731 ret = -ENOMEM;
1732 } 1732 }
1733 1733
1734 if (ret < 0) 1734 if (ret < 0)
1735 clear_perf_probe_event(pev); 1735 clear_perf_probe_event(pev);
1736 1736
1737 return ret; 1737 return ret;
1738 } 1738 }
1739 1739
1740 void clear_perf_probe_event(struct perf_probe_event *pev) 1740 void clear_perf_probe_event(struct perf_probe_event *pev)
1741 { 1741 {
1742 struct perf_probe_point *pp = &pev->point; 1742 struct perf_probe_point *pp = &pev->point;
1743 struct perf_probe_arg_field *field, *next; 1743 struct perf_probe_arg_field *field, *next;
1744 int i; 1744 int i;
1745 1745
1746 free(pev->event); 1746 free(pev->event);
1747 free(pev->group); 1747 free(pev->group);
1748 free(pp->file); 1748 free(pp->file);
1749 free(pp->function); 1749 free(pp->function);
1750 free(pp->lazy_line); 1750 free(pp->lazy_line);
1751 1751
1752 for (i = 0; i < pev->nargs; i++) { 1752 for (i = 0; i < pev->nargs; i++) {
1753 free(pev->args[i].name); 1753 free(pev->args[i].name);
1754 free(pev->args[i].var); 1754 free(pev->args[i].var);
1755 free(pev->args[i].type); 1755 free(pev->args[i].type);
1756 field = pev->args[i].field; 1756 field = pev->args[i].field;
1757 while (field) { 1757 while (field) {
1758 next = field->next; 1758 next = field->next;
1759 zfree(&field->name); 1759 zfree(&field->name);
1760 free(field); 1760 free(field);
1761 field = next; 1761 field = next;
1762 } 1762 }
1763 } 1763 }
1764 free(pev->args); 1764 free(pev->args);
1765 memset(pev, 0, sizeof(*pev)); 1765 memset(pev, 0, sizeof(*pev));
1766 } 1766 }
1767 1767
1768 static void clear_probe_trace_event(struct probe_trace_event *tev) 1768 static void clear_probe_trace_event(struct probe_trace_event *tev)
1769 { 1769 {
1770 struct probe_trace_arg_ref *ref, *next; 1770 struct probe_trace_arg_ref *ref, *next;
1771 int i; 1771 int i;
1772 1772
1773 free(tev->event); 1773 free(tev->event);
1774 free(tev->group); 1774 free(tev->group);
1775 free(tev->point.symbol); 1775 free(tev->point.symbol);
1776 free(tev->point.module); 1776 free(tev->point.module);
1777 for (i = 0; i < tev->nargs; i++) { 1777 for (i = 0; i < tev->nargs; i++) {
1778 free(tev->args[i].name); 1778 free(tev->args[i].name);
1779 free(tev->args[i].value); 1779 free(tev->args[i].value);
1780 free(tev->args[i].type); 1780 free(tev->args[i].type);
1781 ref = tev->args[i].ref; 1781 ref = tev->args[i].ref;
1782 while (ref) { 1782 while (ref) {
1783 next = ref->next; 1783 next = ref->next;
1784 free(ref); 1784 free(ref);
1785 ref = next; 1785 ref = next;
1786 } 1786 }
1787 } 1787 }
1788 free(tev->args); 1788 free(tev->args);
1789 memset(tev, 0, sizeof(*tev)); 1789 memset(tev, 0, sizeof(*tev));
1790 } 1790 }
1791 1791
1792 static void print_open_warning(int err, bool is_kprobe) 1792 static void print_open_warning(int err, bool is_kprobe)
1793 { 1793 {
1794 char sbuf[STRERR_BUFSIZE]; 1794 char sbuf[STRERR_BUFSIZE];
1795 1795
1796 if (err == -ENOENT) { 1796 if (err == -ENOENT) {
1797 const char *config; 1797 const char *config;
1798 1798
1799 if (!is_kprobe) 1799 if (!is_kprobe)
1800 config = "CONFIG_UPROBE_EVENTS"; 1800 config = "CONFIG_UPROBE_EVENTS";
1801 else 1801 else
1802 config = "CONFIG_KPROBE_EVENTS"; 1802 config = "CONFIG_KPROBE_EVENTS";
1803 1803
1804 pr_warning("%cprobe_events file does not exist" 1804 pr_warning("%cprobe_events file does not exist"
1805 " - please rebuild kernel with %s.\n", 1805 " - please rebuild kernel with %s.\n",
1806 is_kprobe ? 'k' : 'u', config); 1806 is_kprobe ? 'k' : 'u', config);
1807 } else if (err == -ENOTSUP) 1807 } else if (err == -ENOTSUP)
1808 pr_warning("Debugfs is not mounted.\n"); 1808 pr_warning("Debugfs is not mounted.\n");
1809 else 1809 else
1810 pr_warning("Failed to open %cprobe_events: %s\n", 1810 pr_warning("Failed to open %cprobe_events: %s\n",
1811 is_kprobe ? 'k' : 'u', 1811 is_kprobe ? 'k' : 'u',
1812 strerror_r(-err, sbuf, sizeof(sbuf))); 1812 strerror_r(-err, sbuf, sizeof(sbuf)));
1813 } 1813 }
1814 1814
1815 static void print_both_open_warning(int kerr, int uerr) 1815 static void print_both_open_warning(int kerr, int uerr)
1816 { 1816 {
1817 /* Both kprobes and uprobes are disabled, warn it. */ 1817 /* Both kprobes and uprobes are disabled, warn it. */
1818 if (kerr == -ENOTSUP && uerr == -ENOTSUP) 1818 if (kerr == -ENOTSUP && uerr == -ENOTSUP)
1819 pr_warning("Debugfs is not mounted.\n"); 1819 pr_warning("Debugfs is not mounted.\n");
1820 else if (kerr == -ENOENT && uerr == -ENOENT) 1820 else if (kerr == -ENOENT && uerr == -ENOENT)
1821 pr_warning("Please rebuild kernel with CONFIG_KPROBE_EVENTS " 1821 pr_warning("Please rebuild kernel with CONFIG_KPROBE_EVENTS "
1822 "or/and CONFIG_UPROBE_EVENTS.\n"); 1822 "or/and CONFIG_UPROBE_EVENTS.\n");
1823 else { 1823 else {
1824 char sbuf[STRERR_BUFSIZE]; 1824 char sbuf[STRERR_BUFSIZE];
1825 pr_warning("Failed to open kprobe events: %s.\n", 1825 pr_warning("Failed to open kprobe events: %s.\n",
1826 strerror_r(-kerr, sbuf, sizeof(sbuf))); 1826 strerror_r(-kerr, sbuf, sizeof(sbuf)));
1827 pr_warning("Failed to open uprobe events: %s.\n", 1827 pr_warning("Failed to open uprobe events: %s.\n",
1828 strerror_r(-uerr, sbuf, sizeof(sbuf))); 1828 strerror_r(-uerr, sbuf, sizeof(sbuf)));
1829 } 1829 }
1830 } 1830 }
1831 1831
1832 static int open_probe_events(const char *trace_file, bool readwrite) 1832 static int open_probe_events(const char *trace_file, bool readwrite)
1833 { 1833 {
1834 char buf[PATH_MAX]; 1834 char buf[PATH_MAX];
1835 const char *__debugfs; 1835 const char *__debugfs;
1836 int ret; 1836 int ret;
1837 1837
1838 __debugfs = debugfs_find_mountpoint(); 1838 __debugfs = debugfs_find_mountpoint();
1839 if (__debugfs == NULL) 1839 if (__debugfs == NULL)
1840 return -ENOTSUP; 1840 return -ENOTSUP;
1841 1841
1842 ret = e_snprintf(buf, PATH_MAX, "%s/%s", __debugfs, trace_file); 1842 ret = e_snprintf(buf, PATH_MAX, "%s/%s", __debugfs, trace_file);
1843 if (ret >= 0) { 1843 if (ret >= 0) {
1844 pr_debug("Opening %s write=%d\n", buf, readwrite); 1844 pr_debug("Opening %s write=%d\n", buf, readwrite);
1845 if (readwrite && !probe_event_dry_run) 1845 if (readwrite && !probe_event_dry_run)
1846 ret = open(buf, O_RDWR, O_APPEND); 1846 ret = open(buf, O_RDWR, O_APPEND);
1847 else 1847 else
1848 ret = open(buf, O_RDONLY, 0); 1848 ret = open(buf, O_RDONLY, 0);
1849 1849
1850 if (ret < 0) 1850 if (ret < 0)
1851 ret = -errno; 1851 ret = -errno;
1852 } 1852 }
1853 return ret; 1853 return ret;
1854 } 1854 }
1855 1855
1856 static int open_kprobe_events(bool readwrite) 1856 static int open_kprobe_events(bool readwrite)
1857 { 1857 {
1858 return open_probe_events("tracing/kprobe_events", readwrite); 1858 return open_probe_events("tracing/kprobe_events", readwrite);
1859 } 1859 }
1860 1860
1861 static int open_uprobe_events(bool readwrite) 1861 static int open_uprobe_events(bool readwrite)
1862 { 1862 {
1863 return open_probe_events("tracing/uprobe_events", readwrite); 1863 return open_probe_events("tracing/uprobe_events", readwrite);
1864 } 1864 }
1865 1865
1866 /* Get raw string list of current kprobe_events or uprobe_events */ 1866 /* Get raw string list of current kprobe_events or uprobe_events */
1867 static struct strlist *get_probe_trace_command_rawlist(int fd) 1867 static struct strlist *get_probe_trace_command_rawlist(int fd)
1868 { 1868 {
1869 int ret, idx; 1869 int ret, idx;
1870 FILE *fp; 1870 FILE *fp;
1871 char buf[MAX_CMDLEN]; 1871 char buf[MAX_CMDLEN];
1872 char *p; 1872 char *p;
1873 struct strlist *sl; 1873 struct strlist *sl;
1874 1874
1875 sl = strlist__new(true, NULL); 1875 sl = strlist__new(true, NULL);
1876 1876
1877 fp = fdopen(dup(fd), "r"); 1877 fp = fdopen(dup(fd), "r");
1878 while (!feof(fp)) { 1878 while (!feof(fp)) {
1879 p = fgets(buf, MAX_CMDLEN, fp); 1879 p = fgets(buf, MAX_CMDLEN, fp);
1880 if (!p) 1880 if (!p)
1881 break; 1881 break;
1882 1882
1883 idx = strlen(p) - 1; 1883 idx = strlen(p) - 1;
1884 if (p[idx] == '\n') 1884 if (p[idx] == '\n')
1885 p[idx] = '\0'; 1885 p[idx] = '\0';
1886 ret = strlist__add(sl, buf); 1886 ret = strlist__add(sl, buf);
1887 if (ret < 0) { 1887 if (ret < 0) {
1888 pr_debug("strlist__add failed (%d)\n", ret); 1888 pr_debug("strlist__add failed (%d)\n", ret);
1889 strlist__delete(sl); 1889 strlist__delete(sl);
1890 return NULL; 1890 return NULL;
1891 } 1891 }
1892 } 1892 }
1893 fclose(fp); 1893 fclose(fp);
1894 1894
1895 return sl; 1895 return sl;
1896 } 1896 }
1897 1897
1898 /* Show an event */ 1898 /* Show an event */
1899 static int show_perf_probe_event(struct perf_probe_event *pev, 1899 static int show_perf_probe_event(struct perf_probe_event *pev,
1900 const char *module) 1900 const char *module)
1901 { 1901 {
1902 int i, ret; 1902 int i, ret;
1903 char buf[128]; 1903 char buf[128];
1904 char *place; 1904 char *place;
1905 1905
1906 /* Synthesize only event probe point */ 1906 /* Synthesize only event probe point */
1907 place = synthesize_perf_probe_point(&pev->point); 1907 place = synthesize_perf_probe_point(&pev->point);
1908 if (!place) 1908 if (!place)
1909 return -EINVAL; 1909 return -EINVAL;
1910 1910
1911 ret = e_snprintf(buf, 128, "%s:%s", pev->group, pev->event); 1911 ret = e_snprintf(buf, 128, "%s:%s", pev->group, pev->event);
1912 if (ret < 0) 1912 if (ret < 0)
1913 return ret; 1913 return ret;
1914 1914
1915 pr_info(" %-20s (on %s", buf, place); 1915 pr_info(" %-20s (on %s", buf, place);
1916 if (module) 1916 if (module)
1917 pr_info(" in %s", module); 1917 pr_info(" in %s", module);
1918 1918
1919 if (pev->nargs > 0) { 1919 if (pev->nargs > 0) {
1920 pr_info(" with"); 1920 pr_info(" with");
1921 for (i = 0; i < pev->nargs; i++) { 1921 for (i = 0; i < pev->nargs; i++) {
1922 ret = synthesize_perf_probe_arg(&pev->args[i], 1922 ret = synthesize_perf_probe_arg(&pev->args[i],
1923 buf, 128); 1923 buf, 128);
1924 if (ret < 0) 1924 if (ret < 0)
1925 break; 1925 break;
1926 pr_info(" %s", buf); 1926 pr_info(" %s", buf);
1927 } 1927 }
1928 } 1928 }
1929 pr_info(")\n"); 1929 pr_info(")\n");
1930 free(place); 1930 free(place);
1931 return ret; 1931 return ret;
1932 } 1932 }
1933 1933
1934 static int __show_perf_probe_events(int fd, bool is_kprobe) 1934 static int __show_perf_probe_events(int fd, bool is_kprobe)
1935 { 1935 {
1936 int ret = 0; 1936 int ret = 0;
1937 struct probe_trace_event tev; 1937 struct probe_trace_event tev;
1938 struct perf_probe_event pev; 1938 struct perf_probe_event pev;
1939 struct strlist *rawlist; 1939 struct strlist *rawlist;
1940 struct str_node *ent; 1940 struct str_node *ent;
1941 1941
1942 memset(&tev, 0, sizeof(tev)); 1942 memset(&tev, 0, sizeof(tev));
1943 memset(&pev, 0, sizeof(pev)); 1943 memset(&pev, 0, sizeof(pev));
1944 1944
1945 rawlist = get_probe_trace_command_rawlist(fd); 1945 rawlist = get_probe_trace_command_rawlist(fd);
1946 if (!rawlist) 1946 if (!rawlist)
1947 return -ENOMEM; 1947 return -ENOMEM;
1948 1948
1949 strlist__for_each(ent, rawlist) { 1949 strlist__for_each(ent, rawlist) {
1950 ret = parse_probe_trace_command(ent->s, &tev); 1950 ret = parse_probe_trace_command(ent->s, &tev);
1951 if (ret >= 0) { 1951 if (ret >= 0) {
1952 ret = convert_to_perf_probe_event(&tev, &pev, 1952 ret = convert_to_perf_probe_event(&tev, &pev,
1953 is_kprobe); 1953 is_kprobe);
1954 if (ret >= 0) 1954 if (ret >= 0)
1955 ret = show_perf_probe_event(&pev, 1955 ret = show_perf_probe_event(&pev,
1956 tev.point.module); 1956 tev.point.module);
1957 } 1957 }
1958 clear_perf_probe_event(&pev); 1958 clear_perf_probe_event(&pev);
1959 clear_probe_trace_event(&tev); 1959 clear_probe_trace_event(&tev);
1960 if (ret < 0) 1960 if (ret < 0)
1961 break; 1961 break;
1962 } 1962 }
1963 strlist__delete(rawlist); 1963 strlist__delete(rawlist);
1964 1964
1965 return ret; 1965 return ret;
1966 } 1966 }
1967 1967
1968 /* List up current perf-probe events */ 1968 /* List up current perf-probe events */
1969 int show_perf_probe_events(void) 1969 int show_perf_probe_events(void)
1970 { 1970 {
1971 int kp_fd, up_fd, ret; 1971 int kp_fd, up_fd, ret;
1972 1972
1973 setup_pager(); 1973 setup_pager();
1974 1974
1975 ret = init_symbol_maps(false); 1975 ret = init_symbol_maps(false);
1976 if (ret < 0) 1976 if (ret < 0)
1977 return ret; 1977 return ret;
1978 1978
1979 kp_fd = open_kprobe_events(false); 1979 kp_fd = open_kprobe_events(false);
1980 if (kp_fd >= 0) { 1980 if (kp_fd >= 0) {
1981 ret = __show_perf_probe_events(kp_fd, true); 1981 ret = __show_perf_probe_events(kp_fd, true);
1982 close(kp_fd); 1982 close(kp_fd);
1983 if (ret < 0) 1983 if (ret < 0)
1984 goto out; 1984 goto out;
1985 } 1985 }
1986 1986
1987 up_fd = open_uprobe_events(false); 1987 up_fd = open_uprobe_events(false);
1988 if (kp_fd < 0 && up_fd < 0) { 1988 if (kp_fd < 0 && up_fd < 0) {
1989 print_both_open_warning(kp_fd, up_fd); 1989 print_both_open_warning(kp_fd, up_fd);
1990 ret = kp_fd; 1990 ret = kp_fd;
1991 goto out; 1991 goto out;
1992 } 1992 }
1993 1993
1994 if (up_fd >= 0) { 1994 if (up_fd >= 0) {
1995 ret = __show_perf_probe_events(up_fd, false); 1995 ret = __show_perf_probe_events(up_fd, false);
1996 close(up_fd); 1996 close(up_fd);
1997 } 1997 }
1998 out: 1998 out:
1999 exit_symbol_maps(); 1999 exit_symbol_maps();
2000 return ret; 2000 return ret;
2001 } 2001 }
2002 2002
2003 /* Get current perf-probe event names */ 2003 /* Get current perf-probe event names */
2004 static struct strlist *get_probe_trace_event_names(int fd, bool include_group) 2004 static struct strlist *get_probe_trace_event_names(int fd, bool include_group)
2005 { 2005 {
2006 char buf[128]; 2006 char buf[128];
2007 struct strlist *sl, *rawlist; 2007 struct strlist *sl, *rawlist;
2008 struct str_node *ent; 2008 struct str_node *ent;
2009 struct probe_trace_event tev; 2009 struct probe_trace_event tev;
2010 int ret = 0; 2010 int ret = 0;
2011 2011
2012 memset(&tev, 0, sizeof(tev)); 2012 memset(&tev, 0, sizeof(tev));
2013 rawlist = get_probe_trace_command_rawlist(fd); 2013 rawlist = get_probe_trace_command_rawlist(fd);
2014 if (!rawlist) 2014 if (!rawlist)
2015 return NULL; 2015 return NULL;
2016 sl = strlist__new(true, NULL); 2016 sl = strlist__new(true, NULL);
2017 strlist__for_each(ent, rawlist) { 2017 strlist__for_each(ent, rawlist) {
2018 ret = parse_probe_trace_command(ent->s, &tev); 2018 ret = parse_probe_trace_command(ent->s, &tev);
2019 if (ret < 0) 2019 if (ret < 0)
2020 break; 2020 break;
2021 if (include_group) { 2021 if (include_group) {
2022 ret = e_snprintf(buf, 128, "%s:%s", tev.group, 2022 ret = e_snprintf(buf, 128, "%s:%s", tev.group,
2023 tev.event); 2023 tev.event);
2024 if (ret >= 0) 2024 if (ret >= 0)
2025 ret = strlist__add(sl, buf); 2025 ret = strlist__add(sl, buf);
2026 } else 2026 } else
2027 ret = strlist__add(sl, tev.event); 2027 ret = strlist__add(sl, tev.event);
2028 clear_probe_trace_event(&tev); 2028 clear_probe_trace_event(&tev);
2029 if (ret < 0) 2029 if (ret < 0)
2030 break; 2030 break;
2031 } 2031 }
2032 strlist__delete(rawlist); 2032 strlist__delete(rawlist);
2033 2033
2034 if (ret < 0) { 2034 if (ret < 0) {
2035 strlist__delete(sl); 2035 strlist__delete(sl);
2036 return NULL; 2036 return NULL;
2037 } 2037 }
2038 return sl; 2038 return sl;
2039 } 2039 }
2040 2040
2041 static int write_probe_trace_event(int fd, struct probe_trace_event *tev) 2041 static int write_probe_trace_event(int fd, struct probe_trace_event *tev)
2042 { 2042 {
2043 int ret = 0; 2043 int ret = 0;
2044 char *buf = synthesize_probe_trace_command(tev); 2044 char *buf = synthesize_probe_trace_command(tev);
2045 char sbuf[STRERR_BUFSIZE]; 2045 char sbuf[STRERR_BUFSIZE];
2046 2046
2047 if (!buf) { 2047 if (!buf) {
2048 pr_debug("Failed to synthesize probe trace event.\n"); 2048 pr_debug("Failed to synthesize probe trace event.\n");
2049 return -EINVAL; 2049 return -EINVAL;
2050 } 2050 }
2051 2051
2052 pr_debug("Writing event: %s\n", buf); 2052 pr_debug("Writing event: %s\n", buf);
2053 if (!probe_event_dry_run) { 2053 if (!probe_event_dry_run) {
2054 ret = write(fd, buf, strlen(buf)); 2054 ret = write(fd, buf, strlen(buf));
2055 if (ret <= 0) { 2055 if (ret <= 0) {
2056 ret = -errno; 2056 ret = -errno;
2057 pr_warning("Failed to write event: %s\n", 2057 pr_warning("Failed to write event: %s\n",
2058 strerror_r(errno, sbuf, sizeof(sbuf))); 2058 strerror_r(errno, sbuf, sizeof(sbuf)));
2059 } 2059 }
2060 } 2060 }
2061 free(buf); 2061 free(buf);
2062 return ret; 2062 return ret;
2063 } 2063 }
2064 2064
2065 static int get_new_event_name(char *buf, size_t len, const char *base, 2065 static int get_new_event_name(char *buf, size_t len, const char *base,
2066 struct strlist *namelist, bool allow_suffix) 2066 struct strlist *namelist, bool allow_suffix)
2067 { 2067 {
2068 int i, ret; 2068 int i, ret;
2069 2069
2070 /* Try no suffix */ 2070 /* Try no suffix */
2071 ret = e_snprintf(buf, len, "%s", base); 2071 ret = e_snprintf(buf, len, "%s", base);
2072 if (ret < 0) { 2072 if (ret < 0) {
2073 pr_debug("snprintf() failed: %d\n", ret); 2073 pr_debug("snprintf() failed: %d\n", ret);
2074 return ret; 2074 return ret;
2075 } 2075 }
2076 if (!strlist__has_entry(namelist, buf)) 2076 if (!strlist__has_entry(namelist, buf))
2077 return 0; 2077 return 0;
2078 2078
2079 if (!allow_suffix) { 2079 if (!allow_suffix) {
2080 pr_warning("Error: event \"%s\" already exists. " 2080 pr_warning("Error: event \"%s\" already exists. "
2081 "(Use -f to force duplicates.)\n", base); 2081 "(Use -f to force duplicates.)\n", base);
2082 return -EEXIST; 2082 return -EEXIST;
2083 } 2083 }
2084 2084
2085 /* Try to add suffix */ 2085 /* Try to add suffix */
2086 for (i = 1; i < MAX_EVENT_INDEX; i++) { 2086 for (i = 1; i < MAX_EVENT_INDEX; i++) {
2087 ret = e_snprintf(buf, len, "%s_%d", base, i); 2087 ret = e_snprintf(buf, len, "%s_%d", base, i);
2088 if (ret < 0) { 2088 if (ret < 0) {
2089 pr_debug("snprintf() failed: %d\n", ret); 2089 pr_debug("snprintf() failed: %d\n", ret);
2090 return ret; 2090 return ret;
2091 } 2091 }
2092 if (!strlist__has_entry(namelist, buf)) 2092 if (!strlist__has_entry(namelist, buf))
2093 break; 2093 break;
2094 } 2094 }
2095 if (i == MAX_EVENT_INDEX) { 2095 if (i == MAX_EVENT_INDEX) {
2096 pr_warning("Too many events are on the same function.\n"); 2096 pr_warning("Too many events are on the same function.\n");
2097 ret = -ERANGE; 2097 ret = -ERANGE;
2098 } 2098 }
2099 2099
2100 return ret; 2100 return ret;
2101 } 2101 }
2102 2102
2103 static int __add_probe_trace_events(struct perf_probe_event *pev, 2103 static int __add_probe_trace_events(struct perf_probe_event *pev,
2104 struct probe_trace_event *tevs, 2104 struct probe_trace_event *tevs,
2105 int ntevs, bool allow_suffix) 2105 int ntevs, bool allow_suffix)
2106 { 2106 {
2107 int i, fd, ret; 2107 int i, fd, ret;
2108 struct probe_trace_event *tev = NULL; 2108 struct probe_trace_event *tev = NULL;
2109 char buf[64]; 2109 char buf[64];
2110 const char *event, *group; 2110 const char *event, *group;
2111 struct strlist *namelist; 2111 struct strlist *namelist;
2112 2112
2113 if (pev->uprobes) 2113 if (pev->uprobes)
2114 fd = open_uprobe_events(true); 2114 fd = open_uprobe_events(true);
2115 else 2115 else
2116 fd = open_kprobe_events(true); 2116 fd = open_kprobe_events(true);
2117 2117
2118 if (fd < 0) { 2118 if (fd < 0) {
2119 print_open_warning(fd, !pev->uprobes); 2119 print_open_warning(fd, !pev->uprobes);
2120 return fd; 2120 return fd;
2121 } 2121 }
2122 2122
2123 /* Get current event names */ 2123 /* Get current event names */
2124 namelist = get_probe_trace_event_names(fd, false); 2124 namelist = get_probe_trace_event_names(fd, false);
2125 if (!namelist) { 2125 if (!namelist) {
2126 pr_debug("Failed to get current event list.\n"); 2126 pr_debug("Failed to get current event list.\n");
2127 return -EIO; 2127 return -EIO;
2128 } 2128 }
2129 2129
2130 ret = 0; 2130 ret = 0;
2131 pr_info("Added new event%s\n", (ntevs > 1) ? "s:" : ":"); 2131 pr_info("Added new event%s\n", (ntevs > 1) ? "s:" : ":");
2132 for (i = 0; i < ntevs; i++) { 2132 for (i = 0; i < ntevs; i++) {
2133 tev = &tevs[i]; 2133 tev = &tevs[i];
2134 if (pev->event) 2134 if (pev->event)
2135 event = pev->event; 2135 event = pev->event;
2136 else 2136 else
2137 if (pev->point.function) 2137 if (pev->point.function)
2138 event = pev->point.function; 2138 event = pev->point.function;
2139 else 2139 else
2140 event = tev->point.symbol; 2140 event = tev->point.symbol;
2141 if (pev->group) 2141 if (pev->group)
2142 group = pev->group; 2142 group = pev->group;
2143 else 2143 else
2144 group = PERFPROBE_GROUP; 2144 group = PERFPROBE_GROUP;
2145 2145
2146 /* Get an unused new event name */ 2146 /* Get an unused new event name */
2147 ret = get_new_event_name(buf, 64, event, 2147 ret = get_new_event_name(buf, 64, event,
2148 namelist, allow_suffix); 2148 namelist, allow_suffix);
2149 if (ret < 0) 2149 if (ret < 0)
2150 break; 2150 break;
2151 event = buf; 2151 event = buf;
2152 2152
2153 tev->event = strdup(event); 2153 tev->event = strdup(event);
2154 tev->group = strdup(group); 2154 tev->group = strdup(group);
2155 if (tev->event == NULL || tev->group == NULL) { 2155 if (tev->event == NULL || tev->group == NULL) {
2156 ret = -ENOMEM; 2156 ret = -ENOMEM;
2157 break; 2157 break;
2158 } 2158 }
2159 ret = write_probe_trace_event(fd, tev); 2159 ret = write_probe_trace_event(fd, tev);
2160 if (ret < 0) 2160 if (ret < 0)
2161 break; 2161 break;
2162 /* Add added event name to namelist */ 2162 /* Add added event name to namelist */
2163 strlist__add(namelist, event); 2163 strlist__add(namelist, event);
2164 2164
2165 /* Trick here - save current event/group */ 2165 /* Trick here - save current event/group */
2166 event = pev->event; 2166 event = pev->event;
2167 group = pev->group; 2167 group = pev->group;
2168 pev->event = tev->event; 2168 pev->event = tev->event;
2169 pev->group = tev->group; 2169 pev->group = tev->group;
2170 show_perf_probe_event(pev, tev->point.module); 2170 show_perf_probe_event(pev, tev->point.module);
2171 /* Trick here - restore current event/group */ 2171 /* Trick here - restore current event/group */
2172 pev->event = (char *)event; 2172 pev->event = (char *)event;
2173 pev->group = (char *)group; 2173 pev->group = (char *)group;
2174 2174
2175 /* 2175 /*
2176 * Probes after the first probe which comes from same 2176 * Probes after the first probe which comes from same
2177 * user input are always allowed to add suffix, because 2177 * user input are always allowed to add suffix, because
2178 * there might be several addresses corresponding to 2178 * there might be several addresses corresponding to
2179 * one code line. 2179 * one code line.
2180 */ 2180 */
2181 allow_suffix = true; 2181 allow_suffix = true;
2182 } 2182 }
2183 2183
2184 if (ret >= 0) { 2184 if (ret >= 0) {
2185 /* Show how to use the event. */ 2185 /* Show how to use the event. */
2186 pr_info("\nYou can now use it in all perf tools, such as:\n\n"); 2186 pr_info("\nYou can now use it in all perf tools, such as:\n\n");
2187 pr_info("\tperf record -e %s:%s -aR sleep 1\n\n", tev->group, 2187 pr_info("\tperf record -e %s:%s -aR sleep 1\n\n", tev->group,
2188 tev->event); 2188 tev->event);
2189 } 2189 }
2190 2190
2191 strlist__delete(namelist); 2191 strlist__delete(namelist);
2192 close(fd); 2192 close(fd);
2193 return ret; 2193 return ret;
2194 } 2194 }
2195 2195
2196 static char *looking_function_name; 2196 static int find_probe_functions(struct map *map, char *name)
2197 static int num_matched_functions;
2198
2199 static int probe_function_filter(struct map *map __maybe_unused,
2200 struct symbol *sym)
2201 { 2197 {
2202 if ((sym->binding == STB_GLOBAL || sym->binding == STB_LOCAL) && 2198 int found = 0;
2203 strcmp(looking_function_name, sym->name) == 0) { 2199 struct symbol *sym;
2204 num_matched_functions++; 2200
2205 return 0; 2201 map__for_each_symbol_by_name(map, name, sym) {
2202 if (sym->binding == STB_GLOBAL || sym->binding == STB_LOCAL)
2203 found++;
2206 } 2204 }
2207 return 1; 2205
2206 return found;
2208 } 2207 }
2209 2208
2210 #define strdup_or_goto(str, label) \ 2209 #define strdup_or_goto(str, label) \
2211 ({ char *__p = strdup(str); if (!__p) goto label; __p; }) 2210 ({ char *__p = strdup(str); if (!__p) goto label; __p; })
2212 2211
2213 /* 2212 /*
2214 * Find probe function addresses from map. 2213 * Find probe function addresses from map.
2215 * Return an error or the number of found probe_trace_event 2214 * Return an error or the number of found probe_trace_event
2216 */ 2215 */
2217 static int find_probe_trace_events_from_map(struct perf_probe_event *pev, 2216 static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
2218 struct probe_trace_event **tevs, 2217 struct probe_trace_event **tevs,
2219 int max_tevs, const char *target) 2218 int max_tevs, const char *target)
2220 { 2219 {
2221 struct map *map = NULL; 2220 struct map *map = NULL;
2222 struct kmap *kmap = NULL; 2221 struct kmap *kmap = NULL;
2223 struct ref_reloc_sym *reloc_sym = NULL; 2222 struct ref_reloc_sym *reloc_sym = NULL;
2224 struct symbol *sym; 2223 struct symbol *sym;
2225 struct rb_node *nd;
2226 struct probe_trace_event *tev; 2224 struct probe_trace_event *tev;
2227 struct perf_probe_point *pp = &pev->point; 2225 struct perf_probe_point *pp = &pev->point;
2228 struct probe_trace_point *tp; 2226 struct probe_trace_point *tp;
2227 int num_matched_functions;
2229 int ret, i; 2228 int ret, i;
2230 2229
2231 /* Init maps of given executable or kernel */ 2230 /* Init maps of given executable or kernel */
2232 if (pev->uprobes) 2231 if (pev->uprobes)
2233 map = dso__new_map(target); 2232 map = dso__new_map(target);
2234 else 2233 else
2235 map = kernel_get_module_map(target); 2234 map = kernel_get_module_map(target);
2236 if (!map) { 2235 if (!map) {
2237 ret = -EINVAL; 2236 ret = -EINVAL;
2238 goto out; 2237 goto out;
2239 } 2238 }
2240 2239
2241 /* 2240 /*
2242 * Load matched symbols: Since the different local symbols may have 2241 * Load matched symbols: Since the different local symbols may have
2243 * same name but different addresses, this lists all the symbols. 2242 * same name but different addresses, this lists all the symbols.
2244 */ 2243 */
2245 num_matched_functions = 0; 2244 num_matched_functions = find_probe_functions(map, pp->function);
2246 looking_function_name = pp->function; 2245 if (num_matched_functions == 0) {
2247 ret = map__load(map, probe_function_filter);
2248 if (ret || num_matched_functions == 0) {
2249 pr_err("Failed to find symbol %s in %s\n", pp->function, 2246 pr_err("Failed to find symbol %s in %s\n", pp->function,
2250 target ? : "kernel"); 2247 target ? : "kernel");
2251 ret = -ENOENT; 2248 ret = -ENOENT;
2252 goto out; 2249 goto out;
2253 } else if (num_matched_functions > max_tevs) { 2250 } else if (num_matched_functions > max_tevs) {
2254 pr_err("Too many functions matched in %s\n", 2251 pr_err("Too many functions matched in %s\n",
2255 target ? : "kernel"); 2252 target ? : "kernel");
2256 ret = -E2BIG; 2253 ret = -E2BIG;
2257 goto out; 2254 goto out;
2258 } 2255 }
2259 2256
2260 if (!pev->uprobes) { 2257 if (!pev->uprobes && !pp->retprobe) {
2261 kmap = map__kmap(map); 2258 kmap = map__kmap(map);
2262 reloc_sym = kmap->ref_reloc_sym; 2259 reloc_sym = kmap->ref_reloc_sym;
2263 if (!reloc_sym) { 2260 if (!reloc_sym) {
2264 pr_warning("Relocated base symbol is not found!\n"); 2261 pr_warning("Relocated base symbol is not found!\n");
2265 ret = -EINVAL; 2262 ret = -EINVAL;
2266 goto out; 2263 goto out;
2267 } 2264 }
2268 } 2265 }
2269 2266
2270 /* Setup result trace-probe-events */ 2267 /* Setup result trace-probe-events */
2271 *tevs = zalloc(sizeof(*tev) * num_matched_functions); 2268 *tevs = zalloc(sizeof(*tev) * num_matched_functions);
2272 if (!*tevs) { 2269 if (!*tevs) {
2273 ret = -ENOMEM; 2270 ret = -ENOMEM;
2274 goto out; 2271 goto out;
2275 } 2272 }
2276 2273
2277 ret = 0; 2274 ret = 0;
2278 map__for_each_symbol(map, sym, nd) { 2275
2276 map__for_each_symbol_by_name(map, pp->function, sym) {
2279 tev = (*tevs) + ret; 2277 tev = (*tevs) + ret;
2280 tp = &tev->point; 2278 tp = &tev->point;
2281 if (ret == num_matched_functions) { 2279 if (ret == num_matched_functions) {
2282 pr_warning("Too many symbols are listed. Skip it.\n"); 2280 pr_warning("Too many symbols are listed. Skip it.\n");
2283 break; 2281 break;
2284 } 2282 }
2285 ret++; 2283 ret++;
2286 2284
2287 if (pp->offset > sym->end - sym->start) { 2285 if (pp->offset > sym->end - sym->start) {
2288 pr_warning("Offset %ld is bigger than the size of %s\n", 2286 pr_warning("Offset %ld is bigger than the size of %s\n",
2289 pp->offset, sym->name); 2287 pp->offset, sym->name);
2290 ret = -ENOENT; 2288 ret = -ENOENT;
2291 goto err_out; 2289 goto err_out;
2292 } 2290 }
2293 /* Add one probe point */ 2291 /* Add one probe point */
2294 tp->address = map->unmap_ip(map, sym->start) + pp->offset; 2292 tp->address = map->unmap_ip(map, sym->start) + pp->offset;
2295 if (reloc_sym) { 2293 if (reloc_sym) {
2296 tp->symbol = strdup_or_goto(reloc_sym->name, nomem_out); 2294 tp->symbol = strdup_or_goto(reloc_sym->name, nomem_out);
2297 tp->offset = tp->address - reloc_sym->addr; 2295 tp->offset = tp->address - reloc_sym->addr;
2298 } else { 2296 } else {
2299 tp->symbol = strdup_or_goto(sym->name, nomem_out); 2297 tp->symbol = strdup_or_goto(sym->name, nomem_out);
2300 tp->offset = pp->offset; 2298 tp->offset = pp->offset;
2301 } 2299 }
2302 tp->retprobe = pp->retprobe; 2300 tp->retprobe = pp->retprobe;
2303 if (target) 2301 if (target)
2304 tev->point.module = strdup_or_goto(target, nomem_out); 2302 tev->point.module = strdup_or_goto(target, nomem_out);
2305 tev->uprobes = pev->uprobes; 2303 tev->uprobes = pev->uprobes;
2306 tev->nargs = pev->nargs; 2304 tev->nargs = pev->nargs;
2307 if (tev->nargs) { 2305 if (tev->nargs) {
2308 tev->args = zalloc(sizeof(struct probe_trace_arg) * 2306 tev->args = zalloc(sizeof(struct probe_trace_arg) *
2309 tev->nargs); 2307 tev->nargs);
2310 if (tev->args == NULL) 2308 if (tev->args == NULL)
2311 goto nomem_out; 2309 goto nomem_out;
2312 } 2310 }
2313 for (i = 0; i < tev->nargs; i++) { 2311 for (i = 0; i < tev->nargs; i++) {
2314 if (pev->args[i].name) 2312 if (pev->args[i].name)
2315 tev->args[i].name = 2313 tev->args[i].name =
2316 strdup_or_goto(pev->args[i].name, 2314 strdup_or_goto(pev->args[i].name,
2317 nomem_out); 2315 nomem_out);
2318 2316
2319 tev->args[i].value = strdup_or_goto(pev->args[i].var, 2317 tev->args[i].value = strdup_or_goto(pev->args[i].var,
2320 nomem_out); 2318 nomem_out);
2321 if (pev->args[i].type) 2319 if (pev->args[i].type)
2322 tev->args[i].type = 2320 tev->args[i].type =
2323 strdup_or_goto(pev->args[i].type, 2321 strdup_or_goto(pev->args[i].type,
2324 nomem_out); 2322 nomem_out);
2325 } 2323 }
2326 } 2324 }
2327 2325
2328 out: 2326 out:
2329 if (map && pev->uprobes) { 2327 if (map && pev->uprobes) {
2330 /* Only when using uprobe(exec) map needs to be released */ 2328 /* Only when using uprobe(exec) map needs to be released */
2331 dso__delete(map->dso); 2329 dso__delete(map->dso);
2332 map__delete(map); 2330 map__delete(map);
2333 } 2331 }
2334 return ret; 2332 return ret;
2335 2333
2336 nomem_out: 2334 nomem_out:
2337 ret = -ENOMEM; 2335 ret = -ENOMEM;
2338 err_out: 2336 err_out:
2339 clear_probe_trace_events(*tevs, num_matched_functions); 2337 clear_probe_trace_events(*tevs, num_matched_functions);
2340 zfree(tevs); 2338 zfree(tevs);
2341 goto out; 2339 goto out;
2342 } 2340 }
2343 2341
2344 static int convert_to_probe_trace_events(struct perf_probe_event *pev, 2342 static int convert_to_probe_trace_events(struct perf_probe_event *pev,
2345 struct probe_trace_event **tevs, 2343 struct probe_trace_event **tevs,
2346 int max_tevs, const char *target) 2344 int max_tevs, const char *target)
2347 { 2345 {
2348 int ret; 2346 int ret;
2349 2347
2350 if (pev->uprobes && !pev->group) { 2348 if (pev->uprobes && !pev->group) {
2351 /* Replace group name if not given */ 2349 /* Replace group name if not given */
2352 ret = convert_exec_to_group(target, &pev->group); 2350 ret = convert_exec_to_group(target, &pev->group);
2353 if (ret != 0) { 2351 if (ret != 0) {
2354 pr_warning("Failed to make a group name.\n"); 2352 pr_warning("Failed to make a group name.\n");
2355 return ret; 2353 return ret;
2356 } 2354 }
2357 } 2355 }
2358 2356
2359 /* Convert perf_probe_event with debuginfo */ 2357 /* Convert perf_probe_event with debuginfo */
2360 ret = try_to_find_probe_trace_events(pev, tevs, max_tevs, target); 2358 ret = try_to_find_probe_trace_events(pev, tevs, max_tevs, target);
2361 if (ret != 0) 2359 if (ret != 0)
2362 return ret; /* Found in debuginfo or got an error */ 2360 return ret; /* Found in debuginfo or got an error */
2363 2361
2364 return find_probe_trace_events_from_map(pev, tevs, max_tevs, target); 2362 return find_probe_trace_events_from_map(pev, tevs, max_tevs, target);
2365 } 2363 }
2366 2364
2367 struct __event_package { 2365 struct __event_package {
2368 struct perf_probe_event *pev; 2366 struct perf_probe_event *pev;
2369 struct probe_trace_event *tevs; 2367 struct probe_trace_event *tevs;
2370 int ntevs; 2368 int ntevs;
2371 }; 2369 };
2372 2370
2373 int add_perf_probe_events(struct perf_probe_event *pevs, int npevs, 2371 int add_perf_probe_events(struct perf_probe_event *pevs, int npevs,
2374 int max_tevs, const char *target, bool force_add) 2372 int max_tevs, const char *target, bool force_add)
2375 { 2373 {
2376 int i, j, ret; 2374 int i, j, ret;
2377 struct __event_package *pkgs; 2375 struct __event_package *pkgs;
2378 2376
2379 ret = 0; 2377 ret = 0;
2380 pkgs = zalloc(sizeof(struct __event_package) * npevs); 2378 pkgs = zalloc(sizeof(struct __event_package) * npevs);
2381 2379
2382 if (pkgs == NULL) 2380 if (pkgs == NULL)
2383 return -ENOMEM; 2381 return -ENOMEM;
2384 2382
2385 ret = init_symbol_maps(pevs->uprobes); 2383 ret = init_symbol_maps(pevs->uprobes);
2386 if (ret < 0) { 2384 if (ret < 0) {
2387 free(pkgs); 2385 free(pkgs);
2388 return ret; 2386 return ret;
2389 } 2387 }
2390 2388
2391 /* Loop 1: convert all events */ 2389 /* Loop 1: convert all events */
2392 for (i = 0; i < npevs; i++) { 2390 for (i = 0; i < npevs; i++) {
2393 pkgs[i].pev = &pevs[i]; 2391 pkgs[i].pev = &pevs[i];
2394 /* Convert with or without debuginfo */ 2392 /* Convert with or without debuginfo */
2395 ret = convert_to_probe_trace_events(pkgs[i].pev, 2393 ret = convert_to_probe_trace_events(pkgs[i].pev,
2396 &pkgs[i].tevs, 2394 &pkgs[i].tevs,
2397 max_tevs, 2395 max_tevs,
2398 target); 2396 target);
2399 if (ret < 0) 2397 if (ret < 0)
2400 goto end; 2398 goto end;
2401 pkgs[i].ntevs = ret; 2399 pkgs[i].ntevs = ret;
2402 } 2400 }
2403 2401
2404 /* Loop 2: add all events */ 2402 /* Loop 2: add all events */
2405 for (i = 0; i < npevs; i++) { 2403 for (i = 0; i < npevs; i++) {
2406 ret = __add_probe_trace_events(pkgs[i].pev, pkgs[i].tevs, 2404 ret = __add_probe_trace_events(pkgs[i].pev, pkgs[i].tevs,
2407 pkgs[i].ntevs, force_add); 2405 pkgs[i].ntevs, force_add);
2408 if (ret < 0) 2406 if (ret < 0)
2409 break; 2407 break;
2410 } 2408 }
2411 end: 2409 end:
2412 /* Loop 3: cleanup and free trace events */ 2410 /* Loop 3: cleanup and free trace events */
2413 for (i = 0; i < npevs; i++) { 2411 for (i = 0; i < npevs; i++) {
2414 for (j = 0; j < pkgs[i].ntevs; j++) 2412 for (j = 0; j < pkgs[i].ntevs; j++)
2415 clear_probe_trace_event(&pkgs[i].tevs[j]); 2413 clear_probe_trace_event(&pkgs[i].tevs[j]);
2416 zfree(&pkgs[i].tevs); 2414 zfree(&pkgs[i].tevs);
2417 } 2415 }
2418 free(pkgs); 2416 free(pkgs);
2419 exit_symbol_maps(); 2417 exit_symbol_maps();
2420 2418
2421 return ret; 2419 return ret;
2422 } 2420 }
2423 2421
2424 static int __del_trace_probe_event(int fd, struct str_node *ent) 2422 static int __del_trace_probe_event(int fd, struct str_node *ent)
2425 { 2423 {
2426 char *p; 2424 char *p;
2427 char buf[128]; 2425 char buf[128];
2428 int ret; 2426 int ret;
2429 2427
2430 /* Convert from perf-probe event to trace-probe event */ 2428 /* Convert from perf-probe event to trace-probe event */
2431 ret = e_snprintf(buf, 128, "-:%s", ent->s); 2429 ret = e_snprintf(buf, 128, "-:%s", ent->s);
2432 if (ret < 0) 2430 if (ret < 0)
2433 goto error; 2431 goto error;
2434 2432
2435 p = strchr(buf + 2, ':'); 2433 p = strchr(buf + 2, ':');
2436 if (!p) { 2434 if (!p) {
2437 pr_debug("Internal error: %s should have ':' but not.\n", 2435 pr_debug("Internal error: %s should have ':' but not.\n",
2438 ent->s); 2436 ent->s);
2439 ret = -ENOTSUP; 2437 ret = -ENOTSUP;
2440 goto error; 2438 goto error;
2441 } 2439 }
2442 *p = '/'; 2440 *p = '/';
2443 2441
2444 pr_debug("Writing event: %s\n", buf); 2442 pr_debug("Writing event: %s\n", buf);
2445 ret = write(fd, buf, strlen(buf)); 2443 ret = write(fd, buf, strlen(buf));
2446 if (ret < 0) { 2444 if (ret < 0) {
2447 ret = -errno; 2445 ret = -errno;
2448 goto error; 2446 goto error;
2449 } 2447 }
2450 2448
2451 pr_info("Removed event: %s\n", ent->s); 2449 pr_info("Removed event: %s\n", ent->s);
2452 return 0; 2450 return 0;
2453 error: 2451 error:
2454 pr_warning("Failed to delete event: %s\n", 2452 pr_warning("Failed to delete event: %s\n",
2455 strerror_r(-ret, buf, sizeof(buf))); 2453 strerror_r(-ret, buf, sizeof(buf)));
2456 return ret; 2454 return ret;
2457 } 2455 }
2458 2456
2459 static int del_trace_probe_event(int fd, const char *buf, 2457 static int del_trace_probe_event(int fd, const char *buf,
2460 struct strlist *namelist) 2458 struct strlist *namelist)
2461 { 2459 {
2462 struct str_node *ent, *n; 2460 struct str_node *ent, *n;
2463 int ret = -1; 2461 int ret = -1;
2464 2462
2465 if (strpbrk(buf, "*?")) { /* Glob-exp */ 2463 if (strpbrk(buf, "*?")) { /* Glob-exp */
2466 strlist__for_each_safe(ent, n, namelist) 2464 strlist__for_each_safe(ent, n, namelist)
2467 if (strglobmatch(ent->s, buf)) { 2465 if (strglobmatch(ent->s, buf)) {
2468 ret = __del_trace_probe_event(fd, ent); 2466 ret = __del_trace_probe_event(fd, ent);
2469 if (ret < 0) 2467 if (ret < 0)
2470 break; 2468 break;
2471 strlist__remove(namelist, ent); 2469 strlist__remove(namelist, ent);
2472 } 2470 }
2473 } else { 2471 } else {
2474 ent = strlist__find(namelist, buf); 2472 ent = strlist__find(namelist, buf);
2475 if (ent) { 2473 if (ent) {
2476 ret = __del_trace_probe_event(fd, ent); 2474 ret = __del_trace_probe_event(fd, ent);
2477 if (ret >= 0) 2475 if (ret >= 0)
2478 strlist__remove(namelist, ent); 2476 strlist__remove(namelist, ent);
2479 } 2477 }
2480 } 2478 }
2481 2479
2482 return ret; 2480 return ret;
2483 } 2481 }
2484 2482
2485 int del_perf_probe_events(struct strlist *dellist) 2483 int del_perf_probe_events(struct strlist *dellist)
2486 { 2484 {
2487 int ret = -1, ufd = -1, kfd = -1; 2485 int ret = -1, ufd = -1, kfd = -1;
2488 char buf[128]; 2486 char buf[128];
2489 const char *group, *event; 2487 const char *group, *event;
2490 char *p, *str; 2488 char *p, *str;
2491 struct str_node *ent; 2489 struct str_node *ent;
2492 struct strlist *namelist = NULL, *unamelist = NULL; 2490 struct strlist *namelist = NULL, *unamelist = NULL;
2493 2491
2494 /* Get current event names */ 2492 /* Get current event names */
2495 kfd = open_kprobe_events(true); 2493 kfd = open_kprobe_events(true);
2496 if (kfd >= 0) 2494 if (kfd >= 0)
2497 namelist = get_probe_trace_event_names(kfd, true); 2495 namelist = get_probe_trace_event_names(kfd, true);
2498 2496
2499 ufd = open_uprobe_events(true); 2497 ufd = open_uprobe_events(true);
2500 if (ufd >= 0) 2498 if (ufd >= 0)
2501 unamelist = get_probe_trace_event_names(ufd, true); 2499 unamelist = get_probe_trace_event_names(ufd, true);
2502 2500
2503 if (kfd < 0 && ufd < 0) { 2501 if (kfd < 0 && ufd < 0) {
2504 print_both_open_warning(kfd, ufd); 2502 print_both_open_warning(kfd, ufd);
2505 goto error; 2503 goto error;
2506 } 2504 }
2507 2505
2508 if (namelist == NULL && unamelist == NULL) 2506 if (namelist == NULL && unamelist == NULL)
2509 goto error; 2507 goto error;
2510 2508
2511 strlist__for_each(ent, dellist) { 2509 strlist__for_each(ent, dellist) {
2512 str = strdup(ent->s); 2510 str = strdup(ent->s);
2513 if (str == NULL) { 2511 if (str == NULL) {
2514 ret = -ENOMEM; 2512 ret = -ENOMEM;
2515 goto error; 2513 goto error;
2516 } 2514 }
2517 pr_debug("Parsing: %s\n", str); 2515 pr_debug("Parsing: %s\n", str);
2518 p = strchr(str, ':'); 2516 p = strchr(str, ':');
2519 if (p) { 2517 if (p) {
2520 group = str; 2518 group = str;
2521 *p = '\0'; 2519 *p = '\0';
2522 event = p + 1; 2520 event = p + 1;
2523 } else { 2521 } else {
2524 group = "*"; 2522 group = "*";
2525 event = str; 2523 event = str;
2526 } 2524 }
2527 2525
2528 ret = e_snprintf(buf, 128, "%s:%s", group, event); 2526 ret = e_snprintf(buf, 128, "%s:%s", group, event);
2529 if (ret < 0) { 2527 if (ret < 0) {
2530 pr_err("Failed to copy event."); 2528 pr_err("Failed to copy event.");
2531 free(str); 2529 free(str);
2532 goto error; 2530 goto error;
2533 } 2531 }
2534 2532
2535 pr_debug("Group: %s, Event: %s\n", group, event); 2533 pr_debug("Group: %s, Event: %s\n", group, event);
2536 2534
2537 if (namelist) 2535 if (namelist)
2538 ret = del_trace_probe_event(kfd, buf, namelist); 2536 ret = del_trace_probe_event(kfd, buf, namelist);
2539 2537
2540 if (unamelist && ret != 0) 2538 if (unamelist && ret != 0)
2541 ret = del_trace_probe_event(ufd, buf, unamelist); 2539 ret = del_trace_probe_event(ufd, buf, unamelist);
2542 2540
2543 if (ret != 0) 2541 if (ret != 0)
2544 pr_info("Info: Event \"%s\" does not exist.\n", buf); 2542 pr_info("Info: Event \"%s\" does not exist.\n", buf);
2545 2543
2546 free(str); 2544 free(str);
2547 } 2545 }
2548 2546
2549 error: 2547 error:
2550 if (kfd >= 0) { 2548 if (kfd >= 0) {
2551 strlist__delete(namelist); 2549 strlist__delete(namelist);
2552 close(kfd); 2550 close(kfd);
2553 } 2551 }
2554 2552
2555 if (ufd >= 0) { 2553 if (ufd >= 0) {
2556 strlist__delete(unamelist); 2554 strlist__delete(unamelist);
2557 close(ufd); 2555 close(ufd);
2558 } 2556 }
2559 2557
2560 return ret; 2558 return ret;
2561 } 2559 }
2562 2560
2563 /* TODO: don't use a global variable for filter ... */ 2561 /* TODO: don't use a global variable for filter ... */
2564 static struct strfilter *available_func_filter; 2562 static struct strfilter *available_func_filter;
2565 2563
2566 /* 2564 /*
2567 * If a symbol corresponds to a function with global binding and 2565 * If a symbol corresponds to a function with global binding and
2568 * matches filter return 0. For all others return 1. 2566 * matches filter return 0. For all others return 1.
2569 */ 2567 */
2570 static int filter_available_functions(struct map *map __maybe_unused, 2568 static int filter_available_functions(struct map *map __maybe_unused,
2571 struct symbol *sym) 2569 struct symbol *sym)
2572 { 2570 {
2573 if ((sym->binding == STB_GLOBAL || sym->binding == STB_LOCAL) && 2571 if ((sym->binding == STB_GLOBAL || sym->binding == STB_LOCAL) &&
2574 strfilter__compare(available_func_filter, sym->name)) 2572 strfilter__compare(available_func_filter, sym->name))
2575 return 0; 2573 return 0;
2576 return 1; 2574 return 1;
2577 } 2575 }
2578 2576
2579 int show_available_funcs(const char *target, struct strfilter *_filter, 2577 int show_available_funcs(const char *target, struct strfilter *_filter,
2580 bool user) 2578 bool user)
2581 { 2579 {
2582 struct map *map; 2580 struct map *map;
2583 int ret; 2581 int ret;
2584 2582
2585 ret = init_symbol_maps(user); 2583 ret = init_symbol_maps(user);
2586 if (ret < 0) 2584 if (ret < 0)
2587 return ret; 2585 return ret;
2588 2586
2589 /* Get a symbol map */ 2587 /* Get a symbol map */
2590 if (user) 2588 if (user)
2591 map = dso__new_map(target); 2589 map = dso__new_map(target);
2592 else 2590 else
2593 map = kernel_get_module_map(target); 2591 map = kernel_get_module_map(target);
2594 if (!map) { 2592 if (!map) {
2595 pr_err("Failed to get a map for %s\n", (target) ? : "kernel"); 2593 pr_err("Failed to get a map for %s\n", (target) ? : "kernel");
2596 return -EINVAL; 2594 return -EINVAL;
2597 } 2595 }
2598 2596
2599 /* Load symbols with given filter */ 2597 /* Load symbols with given filter */
2600 available_func_filter = _filter; 2598 available_func_filter = _filter;
2601 if (map__load(map, filter_available_functions)) { 2599 if (map__load(map, filter_available_functions)) {
2602 pr_err("Failed to load symbols in %s\n", (target) ? : "kernel"); 2600 pr_err("Failed to load symbols in %s\n", (target) ? : "kernel");
2603 goto end; 2601 goto end;
2604 } 2602 }
2605 if (!dso__sorted_by_name(map->dso, map->type)) 2603 if (!dso__sorted_by_name(map->dso, map->type))
2606 dso__sort_by_name(map->dso, map->type); 2604 dso__sort_by_name(map->dso, map->type);
2607 2605
2608 /* Show all (filtered) symbols */ 2606 /* Show all (filtered) symbols */
2609 setup_pager(); 2607 setup_pager();
2610 dso__fprintf_symbols_by_name(map->dso, map->type, stdout); 2608 dso__fprintf_symbols_by_name(map->dso, map->type, stdout);
2611 end: 2609 end:
2612 if (user) { 2610 if (user) {
2613 dso__delete(map->dso); 2611 dso__delete(map->dso);
2614 map__delete(map); 2612 map__delete(map);
2615 } 2613 }
2616 exit_symbol_maps(); 2614 exit_symbol_maps();
tools/perf/util/symbol.c
1 #include <dirent.h> 1 #include <dirent.h>
2 #include <errno.h> 2 #include <errno.h>
3 #include <stdlib.h> 3 #include <stdlib.h>
4 #include <stdio.h> 4 #include <stdio.h>
5 #include <string.h> 5 #include <string.h>
6 #include <sys/types.h> 6 #include <sys/types.h>
7 #include <sys/stat.h> 7 #include <sys/stat.h>
8 #include <sys/param.h> 8 #include <sys/param.h>
9 #include <fcntl.h> 9 #include <fcntl.h>
10 #include <unistd.h> 10 #include <unistd.h>
11 #include <inttypes.h> 11 #include <inttypes.h>
12 #include "build-id.h" 12 #include "build-id.h"
13 #include "util.h" 13 #include "util.h"
14 #include "debug.h" 14 #include "debug.h"
15 #include "machine.h" 15 #include "machine.h"
16 #include "symbol.h" 16 #include "symbol.h"
17 #include "strlist.h" 17 #include "strlist.h"
18 #include "header.h" 18 #include "header.h"
19 19
20 #include <elf.h> 20 #include <elf.h>
21 #include <limits.h> 21 #include <limits.h>
22 #include <symbol/kallsyms.h> 22 #include <symbol/kallsyms.h>
23 #include <sys/utsname.h> 23 #include <sys/utsname.h>
24 24
25 static int dso__load_kernel_sym(struct dso *dso, struct map *map, 25 static int dso__load_kernel_sym(struct dso *dso, struct map *map,
26 symbol_filter_t filter); 26 symbol_filter_t filter);
27 static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map, 27 static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map,
28 symbol_filter_t filter); 28 symbol_filter_t filter);
29 int vmlinux_path__nr_entries; 29 int vmlinux_path__nr_entries;
30 char **vmlinux_path; 30 char **vmlinux_path;
31 31
32 struct symbol_conf symbol_conf = { 32 struct symbol_conf symbol_conf = {
33 .use_modules = true, 33 .use_modules = true,
34 .try_vmlinux_path = true, 34 .try_vmlinux_path = true,
35 .annotate_src = true, 35 .annotate_src = true,
36 .demangle = true, 36 .demangle = true,
37 .demangle_kernel = false, 37 .demangle_kernel = false,
38 .cumulate_callchain = true, 38 .cumulate_callchain = true,
39 .show_hist_headers = true, 39 .show_hist_headers = true,
40 .symfs = "", 40 .symfs = "",
41 }; 41 };
42 42
43 static enum dso_binary_type binary_type_symtab[] = { 43 static enum dso_binary_type binary_type_symtab[] = {
44 DSO_BINARY_TYPE__KALLSYMS, 44 DSO_BINARY_TYPE__KALLSYMS,
45 DSO_BINARY_TYPE__GUEST_KALLSYMS, 45 DSO_BINARY_TYPE__GUEST_KALLSYMS,
46 DSO_BINARY_TYPE__JAVA_JIT, 46 DSO_BINARY_TYPE__JAVA_JIT,
47 DSO_BINARY_TYPE__DEBUGLINK, 47 DSO_BINARY_TYPE__DEBUGLINK,
48 DSO_BINARY_TYPE__BUILD_ID_CACHE, 48 DSO_BINARY_TYPE__BUILD_ID_CACHE,
49 DSO_BINARY_TYPE__FEDORA_DEBUGINFO, 49 DSO_BINARY_TYPE__FEDORA_DEBUGINFO,
50 DSO_BINARY_TYPE__UBUNTU_DEBUGINFO, 50 DSO_BINARY_TYPE__UBUNTU_DEBUGINFO,
51 DSO_BINARY_TYPE__BUILDID_DEBUGINFO, 51 DSO_BINARY_TYPE__BUILDID_DEBUGINFO,
52 DSO_BINARY_TYPE__SYSTEM_PATH_DSO, 52 DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
53 DSO_BINARY_TYPE__GUEST_KMODULE, 53 DSO_BINARY_TYPE__GUEST_KMODULE,
54 DSO_BINARY_TYPE__GUEST_KMODULE_COMP, 54 DSO_BINARY_TYPE__GUEST_KMODULE_COMP,
55 DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE, 55 DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE,
56 DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP, 56 DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP,
57 DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO, 57 DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO,
58 DSO_BINARY_TYPE__NOT_FOUND, 58 DSO_BINARY_TYPE__NOT_FOUND,
59 }; 59 };
60 60
61 #define DSO_BINARY_TYPE__SYMTAB_CNT ARRAY_SIZE(binary_type_symtab) 61 #define DSO_BINARY_TYPE__SYMTAB_CNT ARRAY_SIZE(binary_type_symtab)
62 62
63 bool symbol_type__is_a(char symbol_type, enum map_type map_type) 63 bool symbol_type__is_a(char symbol_type, enum map_type map_type)
64 { 64 {
65 symbol_type = toupper(symbol_type); 65 symbol_type = toupper(symbol_type);
66 66
67 switch (map_type) { 67 switch (map_type) {
68 case MAP__FUNCTION: 68 case MAP__FUNCTION:
69 return symbol_type == 'T' || symbol_type == 'W'; 69 return symbol_type == 'T' || symbol_type == 'W';
70 case MAP__VARIABLE: 70 case MAP__VARIABLE:
71 return symbol_type == 'D'; 71 return symbol_type == 'D';
72 default: 72 default:
73 return false; 73 return false;
74 } 74 }
75 } 75 }
76 76
77 static int prefix_underscores_count(const char *str) 77 static int prefix_underscores_count(const char *str)
78 { 78 {
79 const char *tail = str; 79 const char *tail = str;
80 80
81 while (*tail == '_') 81 while (*tail == '_')
82 tail++; 82 tail++;
83 83
84 return tail - str; 84 return tail - str;
85 } 85 }
86 86
87 #define SYMBOL_A 0 87 #define SYMBOL_A 0
88 #define SYMBOL_B 1 88 #define SYMBOL_B 1
89 89
90 static int choose_best_symbol(struct symbol *syma, struct symbol *symb) 90 static int choose_best_symbol(struct symbol *syma, struct symbol *symb)
91 { 91 {
92 s64 a; 92 s64 a;
93 s64 b; 93 s64 b;
94 size_t na, nb; 94 size_t na, nb;
95 95
96 /* Prefer a symbol with non zero length */ 96 /* Prefer a symbol with non zero length */
97 a = syma->end - syma->start; 97 a = syma->end - syma->start;
98 b = symb->end - symb->start; 98 b = symb->end - symb->start;
99 if ((b == 0) && (a > 0)) 99 if ((b == 0) && (a > 0))
100 return SYMBOL_A; 100 return SYMBOL_A;
101 else if ((a == 0) && (b > 0)) 101 else if ((a == 0) && (b > 0))
102 return SYMBOL_B; 102 return SYMBOL_B;
103 103
104 /* Prefer a non weak symbol over a weak one */ 104 /* Prefer a non weak symbol over a weak one */
105 a = syma->binding == STB_WEAK; 105 a = syma->binding == STB_WEAK;
106 b = symb->binding == STB_WEAK; 106 b = symb->binding == STB_WEAK;
107 if (b && !a) 107 if (b && !a)
108 return SYMBOL_A; 108 return SYMBOL_A;
109 if (a && !b) 109 if (a && !b)
110 return SYMBOL_B; 110 return SYMBOL_B;
111 111
112 /* Prefer a global symbol over a non global one */ 112 /* Prefer a global symbol over a non global one */
113 a = syma->binding == STB_GLOBAL; 113 a = syma->binding == STB_GLOBAL;
114 b = symb->binding == STB_GLOBAL; 114 b = symb->binding == STB_GLOBAL;
115 if (a && !b) 115 if (a && !b)
116 return SYMBOL_A; 116 return SYMBOL_A;
117 if (b && !a) 117 if (b && !a)
118 return SYMBOL_B; 118 return SYMBOL_B;
119 119
120 /* Prefer a symbol with less underscores */ 120 /* Prefer a symbol with less underscores */
121 a = prefix_underscores_count(syma->name); 121 a = prefix_underscores_count(syma->name);
122 b = prefix_underscores_count(symb->name); 122 b = prefix_underscores_count(symb->name);
123 if (b > a) 123 if (b > a)
124 return SYMBOL_A; 124 return SYMBOL_A;
125 else if (a > b) 125 else if (a > b)
126 return SYMBOL_B; 126 return SYMBOL_B;
127 127
128 /* Choose the symbol with the longest name */ 128 /* Choose the symbol with the longest name */
129 na = strlen(syma->name); 129 na = strlen(syma->name);
130 nb = strlen(symb->name); 130 nb = strlen(symb->name);
131 if (na > nb) 131 if (na > nb)
132 return SYMBOL_A; 132 return SYMBOL_A;
133 else if (na < nb) 133 else if (na < nb)
134 return SYMBOL_B; 134 return SYMBOL_B;
135 135
136 /* Avoid "SyS" kernel syscall aliases */ 136 /* Avoid "SyS" kernel syscall aliases */
137 if (na >= 3 && !strncmp(syma->name, "SyS", 3)) 137 if (na >= 3 && !strncmp(syma->name, "SyS", 3))
138 return SYMBOL_B; 138 return SYMBOL_B;
139 if (na >= 10 && !strncmp(syma->name, "compat_SyS", 10)) 139 if (na >= 10 && !strncmp(syma->name, "compat_SyS", 10))
140 return SYMBOL_B; 140 return SYMBOL_B;
141 141
142 return SYMBOL_A; 142 return SYMBOL_A;
143 } 143 }
144 144
145 void symbols__fixup_duplicate(struct rb_root *symbols) 145 void symbols__fixup_duplicate(struct rb_root *symbols)
146 { 146 {
147 struct rb_node *nd; 147 struct rb_node *nd;
148 struct symbol *curr, *next; 148 struct symbol *curr, *next;
149 149
150 nd = rb_first(symbols); 150 nd = rb_first(symbols);
151 151
152 while (nd) { 152 while (nd) {
153 curr = rb_entry(nd, struct symbol, rb_node); 153 curr = rb_entry(nd, struct symbol, rb_node);
154 again: 154 again:
155 nd = rb_next(&curr->rb_node); 155 nd = rb_next(&curr->rb_node);
156 next = rb_entry(nd, struct symbol, rb_node); 156 next = rb_entry(nd, struct symbol, rb_node);
157 157
158 if (!nd) 158 if (!nd)
159 break; 159 break;
160 160
161 if (curr->start != next->start) 161 if (curr->start != next->start)
162 continue; 162 continue;
163 163
164 if (choose_best_symbol(curr, next) == SYMBOL_A) { 164 if (choose_best_symbol(curr, next) == SYMBOL_A) {
165 rb_erase(&next->rb_node, symbols); 165 rb_erase(&next->rb_node, symbols);
166 symbol__delete(next); 166 symbol__delete(next);
167 goto again; 167 goto again;
168 } else { 168 } else {
169 nd = rb_next(&curr->rb_node); 169 nd = rb_next(&curr->rb_node);
170 rb_erase(&curr->rb_node, symbols); 170 rb_erase(&curr->rb_node, symbols);
171 symbol__delete(curr); 171 symbol__delete(curr);
172 } 172 }
173 } 173 }
174 } 174 }
175 175
176 void symbols__fixup_end(struct rb_root *symbols) 176 void symbols__fixup_end(struct rb_root *symbols)
177 { 177 {
178 struct rb_node *nd, *prevnd = rb_first(symbols); 178 struct rb_node *nd, *prevnd = rb_first(symbols);
179 struct symbol *curr, *prev; 179 struct symbol *curr, *prev;
180 180
181 if (prevnd == NULL) 181 if (prevnd == NULL)
182 return; 182 return;
183 183
184 curr = rb_entry(prevnd, struct symbol, rb_node); 184 curr = rb_entry(prevnd, struct symbol, rb_node);
185 185
186 for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) { 186 for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
187 prev = curr; 187 prev = curr;
188 curr = rb_entry(nd, struct symbol, rb_node); 188 curr = rb_entry(nd, struct symbol, rb_node);
189 189
190 if (prev->end == prev->start && prev->end != curr->start) 190 if (prev->end == prev->start && prev->end != curr->start)
191 prev->end = curr->start; 191 prev->end = curr->start;
192 } 192 }
193 193
194 /* Last entry */ 194 /* Last entry */
195 if (curr->end == curr->start) 195 if (curr->end == curr->start)
196 curr->end = roundup(curr->start, 4096); 196 curr->end = roundup(curr->start, 4096);
197 } 197 }
198 198
199 void __map_groups__fixup_end(struct map_groups *mg, enum map_type type) 199 void __map_groups__fixup_end(struct map_groups *mg, enum map_type type)
200 { 200 {
201 struct map *prev, *curr; 201 struct map *prev, *curr;
202 struct rb_node *nd, *prevnd = rb_first(&mg->maps[type]); 202 struct rb_node *nd, *prevnd = rb_first(&mg->maps[type]);
203 203
204 if (prevnd == NULL) 204 if (prevnd == NULL)
205 return; 205 return;
206 206
207 curr = rb_entry(prevnd, struct map, rb_node); 207 curr = rb_entry(prevnd, struct map, rb_node);
208 208
209 for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) { 209 for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
210 prev = curr; 210 prev = curr;
211 curr = rb_entry(nd, struct map, rb_node); 211 curr = rb_entry(nd, struct map, rb_node);
212 prev->end = curr->start; 212 prev->end = curr->start;
213 } 213 }
214 214
215 /* 215 /*
216 * We still haven't the actual symbols, so guess the 216 * We still haven't the actual symbols, so guess the
217 * last map final address. 217 * last map final address.
218 */ 218 */
219 curr->end = ~0ULL; 219 curr->end = ~0ULL;
220 } 220 }
221 221
222 struct symbol *symbol__new(u64 start, u64 len, u8 binding, const char *name) 222 struct symbol *symbol__new(u64 start, u64 len, u8 binding, const char *name)
223 { 223 {
224 size_t namelen = strlen(name) + 1; 224 size_t namelen = strlen(name) + 1;
225 struct symbol *sym = calloc(1, (symbol_conf.priv_size + 225 struct symbol *sym = calloc(1, (symbol_conf.priv_size +
226 sizeof(*sym) + namelen)); 226 sizeof(*sym) + namelen));
227 if (sym == NULL) 227 if (sym == NULL)
228 return NULL; 228 return NULL;
229 229
230 if (symbol_conf.priv_size) 230 if (symbol_conf.priv_size)
231 sym = ((void *)sym) + symbol_conf.priv_size; 231 sym = ((void *)sym) + symbol_conf.priv_size;
232 232
233 sym->start = start; 233 sym->start = start;
234 sym->end = len ? start + len : start; 234 sym->end = len ? start + len : start;
235 sym->binding = binding; 235 sym->binding = binding;
236 sym->namelen = namelen - 1; 236 sym->namelen = namelen - 1;
237 237
238 pr_debug4("%s: %s %#" PRIx64 "-%#" PRIx64 "\n", 238 pr_debug4("%s: %s %#" PRIx64 "-%#" PRIx64 "\n",
239 __func__, name, start, sym->end); 239 __func__, name, start, sym->end);
240 memcpy(sym->name, name, namelen); 240 memcpy(sym->name, name, namelen);
241 241
242 return sym; 242 return sym;
243 } 243 }
244 244
245 void symbol__delete(struct symbol *sym) 245 void symbol__delete(struct symbol *sym)
246 { 246 {
247 free(((void *)sym) - symbol_conf.priv_size); 247 free(((void *)sym) - symbol_conf.priv_size);
248 } 248 }
249 249
250 size_t symbol__fprintf(struct symbol *sym, FILE *fp) 250 size_t symbol__fprintf(struct symbol *sym, FILE *fp)
251 { 251 {
252 return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %c %s\n", 252 return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %c %s\n",
253 sym->start, sym->end, 253 sym->start, sym->end,
254 sym->binding == STB_GLOBAL ? 'g' : 254 sym->binding == STB_GLOBAL ? 'g' :
255 sym->binding == STB_LOCAL ? 'l' : 'w', 255 sym->binding == STB_LOCAL ? 'l' : 'w',
256 sym->name); 256 sym->name);
257 } 257 }
258 258
259 size_t symbol__fprintf_symname_offs(const struct symbol *sym, 259 size_t symbol__fprintf_symname_offs(const struct symbol *sym,
260 const struct addr_location *al, FILE *fp) 260 const struct addr_location *al, FILE *fp)
261 { 261 {
262 unsigned long offset; 262 unsigned long offset;
263 size_t length; 263 size_t length;
264 264
265 if (sym && sym->name) { 265 if (sym && sym->name) {
266 length = fprintf(fp, "%s", sym->name); 266 length = fprintf(fp, "%s", sym->name);
267 if (al) { 267 if (al) {
268 if (al->addr < sym->end) 268 if (al->addr < sym->end)
269 offset = al->addr - sym->start; 269 offset = al->addr - sym->start;
270 else 270 else
271 offset = al->addr - al->map->start - sym->start; 271 offset = al->addr - al->map->start - sym->start;
272 length += fprintf(fp, "+0x%lx", offset); 272 length += fprintf(fp, "+0x%lx", offset);
273 } 273 }
274 return length; 274 return length;
275 } else 275 } else
276 return fprintf(fp, "[unknown]"); 276 return fprintf(fp, "[unknown]");
277 } 277 }
278 278
279 size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp) 279 size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp)
280 { 280 {
281 return symbol__fprintf_symname_offs(sym, NULL, fp); 281 return symbol__fprintf_symname_offs(sym, NULL, fp);
282 } 282 }
283 283
284 void symbols__delete(struct rb_root *symbols) 284 void symbols__delete(struct rb_root *symbols)
285 { 285 {
286 struct symbol *pos; 286 struct symbol *pos;
287 struct rb_node *next = rb_first(symbols); 287 struct rb_node *next = rb_first(symbols);
288 288
289 while (next) { 289 while (next) {
290 pos = rb_entry(next, struct symbol, rb_node); 290 pos = rb_entry(next, struct symbol, rb_node);
291 next = rb_next(&pos->rb_node); 291 next = rb_next(&pos->rb_node);
292 rb_erase(&pos->rb_node, symbols); 292 rb_erase(&pos->rb_node, symbols);
293 symbol__delete(pos); 293 symbol__delete(pos);
294 } 294 }
295 } 295 }
296 296
297 void symbols__insert(struct rb_root *symbols, struct symbol *sym) 297 void symbols__insert(struct rb_root *symbols, struct symbol *sym)
298 { 298 {
299 struct rb_node **p = &symbols->rb_node; 299 struct rb_node **p = &symbols->rb_node;
300 struct rb_node *parent = NULL; 300 struct rb_node *parent = NULL;
301 const u64 ip = sym->start; 301 const u64 ip = sym->start;
302 struct symbol *s; 302 struct symbol *s;
303 303
304 while (*p != NULL) { 304 while (*p != NULL) {
305 parent = *p; 305 parent = *p;
306 s = rb_entry(parent, struct symbol, rb_node); 306 s = rb_entry(parent, struct symbol, rb_node);
307 if (ip < s->start) 307 if (ip < s->start)
308 p = &(*p)->rb_left; 308 p = &(*p)->rb_left;
309 else 309 else
310 p = &(*p)->rb_right; 310 p = &(*p)->rb_right;
311 } 311 }
312 rb_link_node(&sym->rb_node, parent, p); 312 rb_link_node(&sym->rb_node, parent, p);
313 rb_insert_color(&sym->rb_node, symbols); 313 rb_insert_color(&sym->rb_node, symbols);
314 } 314 }
315 315
316 static struct symbol *symbols__find(struct rb_root *symbols, u64 ip) 316 static struct symbol *symbols__find(struct rb_root *symbols, u64 ip)
317 { 317 {
318 struct rb_node *n; 318 struct rb_node *n;
319 319
320 if (symbols == NULL) 320 if (symbols == NULL)
321 return NULL; 321 return NULL;
322 322
323 n = symbols->rb_node; 323 n = symbols->rb_node;
324 324
325 while (n) { 325 while (n) {
326 struct symbol *s = rb_entry(n, struct symbol, rb_node); 326 struct symbol *s = rb_entry(n, struct symbol, rb_node);
327 327
328 if (ip < s->start) 328 if (ip < s->start)
329 n = n->rb_left; 329 n = n->rb_left;
330 else if (ip >= s->end) 330 else if (ip >= s->end)
331 n = n->rb_right; 331 n = n->rb_right;
332 else 332 else
333 return s; 333 return s;
334 } 334 }
335 335
336 return NULL; 336 return NULL;
337 } 337 }
338 338
339 static struct symbol *symbols__first(struct rb_root *symbols) 339 static struct symbol *symbols__first(struct rb_root *symbols)
340 { 340 {
341 struct rb_node *n = rb_first(symbols); 341 struct rb_node *n = rb_first(symbols);
342 342
343 if (n) 343 if (n)
344 return rb_entry(n, struct symbol, rb_node); 344 return rb_entry(n, struct symbol, rb_node);
345 345
346 return NULL; 346 return NULL;
347 } 347 }
348 348
349 static struct symbol *symbols__next(struct symbol *sym) 349 static struct symbol *symbols__next(struct symbol *sym)
350 { 350 {
351 struct rb_node *n = rb_next(&sym->rb_node); 351 struct rb_node *n = rb_next(&sym->rb_node);
352 352
353 if (n) 353 if (n)
354 return rb_entry(n, struct symbol, rb_node); 354 return rb_entry(n, struct symbol, rb_node);
355 355
356 return NULL; 356 return NULL;
357 } 357 }
358 358
359 struct symbol_name_rb_node { 359 struct symbol_name_rb_node {
360 struct rb_node rb_node; 360 struct rb_node rb_node;
361 struct symbol sym; 361 struct symbol sym;
362 }; 362 };
363 363
364 static void symbols__insert_by_name(struct rb_root *symbols, struct symbol *sym) 364 static void symbols__insert_by_name(struct rb_root *symbols, struct symbol *sym)
365 { 365 {
366 struct rb_node **p = &symbols->rb_node; 366 struct rb_node **p = &symbols->rb_node;
367 struct rb_node *parent = NULL; 367 struct rb_node *parent = NULL;
368 struct symbol_name_rb_node *symn, *s; 368 struct symbol_name_rb_node *symn, *s;
369 369
370 symn = container_of(sym, struct symbol_name_rb_node, sym); 370 symn = container_of(sym, struct symbol_name_rb_node, sym);
371 371
372 while (*p != NULL) { 372 while (*p != NULL) {
373 parent = *p; 373 parent = *p;
374 s = rb_entry(parent, struct symbol_name_rb_node, rb_node); 374 s = rb_entry(parent, struct symbol_name_rb_node, rb_node);
375 if (strcmp(sym->name, s->sym.name) < 0) 375 if (strcmp(sym->name, s->sym.name) < 0)
376 p = &(*p)->rb_left; 376 p = &(*p)->rb_left;
377 else 377 else
378 p = &(*p)->rb_right; 378 p = &(*p)->rb_right;
379 } 379 }
380 rb_link_node(&symn->rb_node, parent, p); 380 rb_link_node(&symn->rb_node, parent, p);
381 rb_insert_color(&symn->rb_node, symbols); 381 rb_insert_color(&symn->rb_node, symbols);
382 } 382 }
383 383
384 static void symbols__sort_by_name(struct rb_root *symbols, 384 static void symbols__sort_by_name(struct rb_root *symbols,
385 struct rb_root *source) 385 struct rb_root *source)
386 { 386 {
387 struct rb_node *nd; 387 struct rb_node *nd;
388 388
389 for (nd = rb_first(source); nd; nd = rb_next(nd)) { 389 for (nd = rb_first(source); nd; nd = rb_next(nd)) {
390 struct symbol *pos = rb_entry(nd, struct symbol, rb_node); 390 struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
391 symbols__insert_by_name(symbols, pos); 391 symbols__insert_by_name(symbols, pos);
392 } 392 }
393 } 393 }
394 394
395 static struct symbol *symbols__find_by_name(struct rb_root *symbols, 395 static struct symbol *symbols__find_by_name(struct rb_root *symbols,
396 const char *name) 396 const char *name)
397 { 397 {
398 struct rb_node *n; 398 struct rb_node *n;
399 struct symbol_name_rb_node *s;
399 400
400 if (symbols == NULL) 401 if (symbols == NULL)
401 return NULL; 402 return NULL;
402 403
403 n = symbols->rb_node; 404 n = symbols->rb_node;
404 405
405 while (n) { 406 while (n) {
406 struct symbol_name_rb_node *s;
407 int cmp; 407 int cmp;
408 408
409 s = rb_entry(n, struct symbol_name_rb_node, rb_node); 409 s = rb_entry(n, struct symbol_name_rb_node, rb_node);
410 cmp = strcmp(name, s->sym.name); 410 cmp = strcmp(name, s->sym.name);
411 411
412 if (cmp < 0) 412 if (cmp < 0)
413 n = n->rb_left; 413 n = n->rb_left;
414 else if (cmp > 0) 414 else if (cmp > 0)
415 n = n->rb_right; 415 n = n->rb_right;
416 else 416 else
417 return &s->sym; 417 break;
418 } 418 }
419 419
420 return NULL; 420 if (n == NULL)
421 return NULL;
422
423 /* return first symbol that has same name (if any) */
424 for (n = rb_prev(n); n; n = rb_prev(n)) {
425 struct symbol_name_rb_node *tmp;
426
427 tmp = rb_entry(n, struct symbol_name_rb_node, rb_node);
428 if (strcmp(tmp->sym.name, s->sym.name))
429 break;
430
431 s = tmp;
432 }
433
434 return &s->sym;
421 } 435 }
422 436
423 struct symbol *dso__find_symbol(struct dso *dso, 437 struct symbol *dso__find_symbol(struct dso *dso,
424 enum map_type type, u64 addr) 438 enum map_type type, u64 addr)
425 { 439 {
426 return symbols__find(&dso->symbols[type], addr); 440 return symbols__find(&dso->symbols[type], addr);
427 } 441 }
428 442
429 struct symbol *dso__first_symbol(struct dso *dso, enum map_type type) 443 struct symbol *dso__first_symbol(struct dso *dso, enum map_type type)
430 { 444 {
431 return symbols__first(&dso->symbols[type]); 445 return symbols__first(&dso->symbols[type]);
432 } 446 }
433 447
434 struct symbol *dso__next_symbol(struct symbol *sym) 448 struct symbol *dso__next_symbol(struct symbol *sym)
435 { 449 {
436 return symbols__next(sym); 450 return symbols__next(sym);
437 } 451 }
438 452
453 struct symbol *symbol__next_by_name(struct symbol *sym)
454 {
455 struct symbol_name_rb_node *s = container_of(sym, struct symbol_name_rb_node, sym);
456 struct rb_node *n = rb_next(&s->rb_node);
457
458 return n ? &rb_entry(n, struct symbol_name_rb_node, rb_node)->sym : NULL;
459 }
460
461 /*
462 * Teturns first symbol that matched with @name.
463 */
439 struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type, 464 struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type,
440 const char *name) 465 const char *name)
441 { 466 {
442 return symbols__find_by_name(&dso->symbol_names[type], name); 467 return symbols__find_by_name(&dso->symbol_names[type], name);
443 } 468 }
444 469
445 void dso__sort_by_name(struct dso *dso, enum map_type type) 470 void dso__sort_by_name(struct dso *dso, enum map_type type)
446 { 471 {
447 dso__set_sorted_by_name(dso, type); 472 dso__set_sorted_by_name(dso, type);
448 return symbols__sort_by_name(&dso->symbol_names[type], 473 return symbols__sort_by_name(&dso->symbol_names[type],
449 &dso->symbols[type]); 474 &dso->symbols[type]);
450 } 475 }
451 476
452 size_t dso__fprintf_symbols_by_name(struct dso *dso, 477 size_t dso__fprintf_symbols_by_name(struct dso *dso,
453 enum map_type type, FILE *fp) 478 enum map_type type, FILE *fp)
454 { 479 {
455 size_t ret = 0; 480 size_t ret = 0;
456 struct rb_node *nd; 481 struct rb_node *nd;
457 struct symbol_name_rb_node *pos; 482 struct symbol_name_rb_node *pos;
458 483
459 for (nd = rb_first(&dso->symbol_names[type]); nd; nd = rb_next(nd)) { 484 for (nd = rb_first(&dso->symbol_names[type]); nd; nd = rb_next(nd)) {
460 pos = rb_entry(nd, struct symbol_name_rb_node, rb_node); 485 pos = rb_entry(nd, struct symbol_name_rb_node, rb_node);
461 fprintf(fp, "%s\n", pos->sym.name); 486 fprintf(fp, "%s\n", pos->sym.name);
462 } 487 }
463 488
464 return ret; 489 return ret;
465 } 490 }
466 491
467 int modules__parse(const char *filename, void *arg, 492 int modules__parse(const char *filename, void *arg,
468 int (*process_module)(void *arg, const char *name, 493 int (*process_module)(void *arg, const char *name,
469 u64 start)) 494 u64 start))
470 { 495 {
471 char *line = NULL; 496 char *line = NULL;
472 size_t n; 497 size_t n;
473 FILE *file; 498 FILE *file;
474 int err = 0; 499 int err = 0;
475 500
476 file = fopen(filename, "r"); 501 file = fopen(filename, "r");
477 if (file == NULL) 502 if (file == NULL)
478 return -1; 503 return -1;
479 504
480 while (1) { 505 while (1) {
481 char name[PATH_MAX]; 506 char name[PATH_MAX];
482 u64 start; 507 u64 start;
483 char *sep; 508 char *sep;
484 ssize_t line_len; 509 ssize_t line_len;
485 510
486 line_len = getline(&line, &n, file); 511 line_len = getline(&line, &n, file);
487 if (line_len < 0) { 512 if (line_len < 0) {
488 if (feof(file)) 513 if (feof(file))
489 break; 514 break;
490 err = -1; 515 err = -1;
491 goto out; 516 goto out;
492 } 517 }
493 518
494 if (!line) { 519 if (!line) {
495 err = -1; 520 err = -1;
496 goto out; 521 goto out;
497 } 522 }
498 523
499 line[--line_len] = '\0'; /* \n */ 524 line[--line_len] = '\0'; /* \n */
500 525
501 sep = strrchr(line, 'x'); 526 sep = strrchr(line, 'x');
502 if (sep == NULL) 527 if (sep == NULL)
503 continue; 528 continue;
504 529
505 hex2u64(sep + 1, &start); 530 hex2u64(sep + 1, &start);
506 531
507 sep = strchr(line, ' '); 532 sep = strchr(line, ' ');
508 if (sep == NULL) 533 if (sep == NULL)
509 continue; 534 continue;
510 535
511 *sep = '\0'; 536 *sep = '\0';
512 537
513 scnprintf(name, sizeof(name), "[%s]", line); 538 scnprintf(name, sizeof(name), "[%s]", line);
514 539
515 err = process_module(arg, name, start); 540 err = process_module(arg, name, start);
516 if (err) 541 if (err)
517 break; 542 break;
518 } 543 }
519 out: 544 out:
520 free(line); 545 free(line);
521 fclose(file); 546 fclose(file);
522 return err; 547 return err;
523 } 548 }
524 549
525 struct process_kallsyms_args { 550 struct process_kallsyms_args {
526 struct map *map; 551 struct map *map;
527 struct dso *dso; 552 struct dso *dso;
528 }; 553 };
529 554
530 /* 555 /*
531 * These are symbols in the kernel image, so make sure that 556 * These are symbols in the kernel image, so make sure that
532 * sym is from a kernel DSO. 557 * sym is from a kernel DSO.
533 */ 558 */
534 bool symbol__is_idle(struct symbol *sym) 559 bool symbol__is_idle(struct symbol *sym)
535 { 560 {
536 const char * const idle_symbols[] = { 561 const char * const idle_symbols[] = {
537 "cpu_idle", 562 "cpu_idle",
538 "cpu_startup_entry", 563 "cpu_startup_entry",
539 "intel_idle", 564 "intel_idle",
540 "default_idle", 565 "default_idle",
541 "native_safe_halt", 566 "native_safe_halt",
542 "enter_idle", 567 "enter_idle",
543 "exit_idle", 568 "exit_idle",
544 "mwait_idle", 569 "mwait_idle",
545 "mwait_idle_with_hints", 570 "mwait_idle_with_hints",
546 "poll_idle", 571 "poll_idle",
547 "ppc64_runlatch_off", 572 "ppc64_runlatch_off",
548 "pseries_dedicated_idle_sleep", 573 "pseries_dedicated_idle_sleep",
549 NULL 574 NULL
550 }; 575 };
551 576
552 int i; 577 int i;
553 578
554 if (!sym) 579 if (!sym)
555 return false; 580 return false;
556 581
557 for (i = 0; idle_symbols[i]; i++) { 582 for (i = 0; idle_symbols[i]; i++) {
558 if (!strcmp(idle_symbols[i], sym->name)) 583 if (!strcmp(idle_symbols[i], sym->name))
559 return true; 584 return true;
560 } 585 }
561 586
562 return false; 587 return false;
563 } 588 }
564 589
565 static int map__process_kallsym_symbol(void *arg, const char *name, 590 static int map__process_kallsym_symbol(void *arg, const char *name,
566 char type, u64 start) 591 char type, u64 start)
567 { 592 {
568 struct symbol *sym; 593 struct symbol *sym;
569 struct process_kallsyms_args *a = arg; 594 struct process_kallsyms_args *a = arg;
570 struct rb_root *root = &a->dso->symbols[a->map->type]; 595 struct rb_root *root = &a->dso->symbols[a->map->type];
571 596
572 if (!symbol_type__is_a(type, a->map->type)) 597 if (!symbol_type__is_a(type, a->map->type))
573 return 0; 598 return 0;
574 599
575 /* 600 /*
576 * module symbols are not sorted so we add all 601 * module symbols are not sorted so we add all
577 * symbols, setting length to 0, and rely on 602 * symbols, setting length to 0, and rely on
578 * symbols__fixup_end() to fix it up. 603 * symbols__fixup_end() to fix it up.
579 */ 604 */
580 sym = symbol__new(start, 0, kallsyms2elf_type(type), name); 605 sym = symbol__new(start, 0, kallsyms2elf_type(type), name);
581 if (sym == NULL) 606 if (sym == NULL)
582 return -ENOMEM; 607 return -ENOMEM;
583 /* 608 /*
584 * We will pass the symbols to the filter later, in 609 * We will pass the symbols to the filter later, in
585 * map__split_kallsyms, when we have split the maps per module 610 * map__split_kallsyms, when we have split the maps per module
586 */ 611 */
587 symbols__insert(root, sym); 612 symbols__insert(root, sym);
588 613
589 return 0; 614 return 0;
590 } 615 }
591 616
592 /* 617 /*
593 * Loads the function entries in /proc/kallsyms into kernel_map->dso, 618 * Loads the function entries in /proc/kallsyms into kernel_map->dso,
594 * so that we can in the next step set the symbol ->end address and then 619 * so that we can in the next step set the symbol ->end address and then
595 * call kernel_maps__split_kallsyms. 620 * call kernel_maps__split_kallsyms.
596 */ 621 */
597 static int dso__load_all_kallsyms(struct dso *dso, const char *filename, 622 static int dso__load_all_kallsyms(struct dso *dso, const char *filename,
598 struct map *map) 623 struct map *map)
599 { 624 {
600 struct process_kallsyms_args args = { .map = map, .dso = dso, }; 625 struct process_kallsyms_args args = { .map = map, .dso = dso, };
601 return kallsyms__parse(filename, &args, map__process_kallsym_symbol); 626 return kallsyms__parse(filename, &args, map__process_kallsym_symbol);
602 } 627 }
603 628
604 static int dso__split_kallsyms_for_kcore(struct dso *dso, struct map *map, 629 static int dso__split_kallsyms_for_kcore(struct dso *dso, struct map *map,
605 symbol_filter_t filter) 630 symbol_filter_t filter)
606 { 631 {
607 struct map_groups *kmaps = map__kmap(map)->kmaps; 632 struct map_groups *kmaps = map__kmap(map)->kmaps;
608 struct map *curr_map; 633 struct map *curr_map;
609 struct symbol *pos; 634 struct symbol *pos;
610 int count = 0, moved = 0; 635 int count = 0, moved = 0;
611 struct rb_root *root = &dso->symbols[map->type]; 636 struct rb_root *root = &dso->symbols[map->type];
612 struct rb_node *next = rb_first(root); 637 struct rb_node *next = rb_first(root);
613 638
614 while (next) { 639 while (next) {
615 char *module; 640 char *module;
616 641
617 pos = rb_entry(next, struct symbol, rb_node); 642 pos = rb_entry(next, struct symbol, rb_node);
618 next = rb_next(&pos->rb_node); 643 next = rb_next(&pos->rb_node);
619 644
620 module = strchr(pos->name, '\t'); 645 module = strchr(pos->name, '\t');
621 if (module) 646 if (module)
622 *module = '\0'; 647 *module = '\0';
623 648
624 curr_map = map_groups__find(kmaps, map->type, pos->start); 649 curr_map = map_groups__find(kmaps, map->type, pos->start);
625 650
626 if (!curr_map || (filter && filter(curr_map, pos))) { 651 if (!curr_map || (filter && filter(curr_map, pos))) {
627 rb_erase(&pos->rb_node, root); 652 rb_erase(&pos->rb_node, root);
628 symbol__delete(pos); 653 symbol__delete(pos);
629 } else { 654 } else {
630 pos->start -= curr_map->start - curr_map->pgoff; 655 pos->start -= curr_map->start - curr_map->pgoff;
631 if (pos->end) 656 if (pos->end)
632 pos->end -= curr_map->start - curr_map->pgoff; 657 pos->end -= curr_map->start - curr_map->pgoff;
633 if (curr_map != map) { 658 if (curr_map != map) {
634 rb_erase(&pos->rb_node, root); 659 rb_erase(&pos->rb_node, root);
635 symbols__insert( 660 symbols__insert(
636 &curr_map->dso->symbols[curr_map->type], 661 &curr_map->dso->symbols[curr_map->type],
637 pos); 662 pos);
638 ++moved; 663 ++moved;
639 } else { 664 } else {
640 ++count; 665 ++count;
641 } 666 }
642 } 667 }
643 } 668 }
644 669
645 /* Symbols have been adjusted */ 670 /* Symbols have been adjusted */
646 dso->adjust_symbols = 1; 671 dso->adjust_symbols = 1;
647 672
648 return count + moved; 673 return count + moved;
649 } 674 }
650 675
651 /* 676 /*
652 * Split the symbols into maps, making sure there are no overlaps, i.e. the 677 * Split the symbols into maps, making sure there are no overlaps, i.e. the
653 * kernel range is broken in several maps, named [kernel].N, as we don't have 678 * kernel range is broken in several maps, named [kernel].N, as we don't have
654 * the original ELF section names vmlinux have. 679 * the original ELF section names vmlinux have.
655 */ 680 */
656 static int dso__split_kallsyms(struct dso *dso, struct map *map, u64 delta, 681 static int dso__split_kallsyms(struct dso *dso, struct map *map, u64 delta,
657 symbol_filter_t filter) 682 symbol_filter_t filter)
658 { 683 {
659 struct map_groups *kmaps = map__kmap(map)->kmaps; 684 struct map_groups *kmaps = map__kmap(map)->kmaps;
660 struct machine *machine = kmaps->machine; 685 struct machine *machine = kmaps->machine;
661 struct map *curr_map = map; 686 struct map *curr_map = map;
662 struct symbol *pos; 687 struct symbol *pos;
663 int count = 0, moved = 0; 688 int count = 0, moved = 0;
664 struct rb_root *root = &dso->symbols[map->type]; 689 struct rb_root *root = &dso->symbols[map->type];
665 struct rb_node *next = rb_first(root); 690 struct rb_node *next = rb_first(root);
666 int kernel_range = 0; 691 int kernel_range = 0;
667 692
668 while (next) { 693 while (next) {
669 char *module; 694 char *module;
670 695
671 pos = rb_entry(next, struct symbol, rb_node); 696 pos = rb_entry(next, struct symbol, rb_node);
672 next = rb_next(&pos->rb_node); 697 next = rb_next(&pos->rb_node);
673 698
674 module = strchr(pos->name, '\t'); 699 module = strchr(pos->name, '\t');
675 if (module) { 700 if (module) {
676 if (!symbol_conf.use_modules) 701 if (!symbol_conf.use_modules)
677 goto discard_symbol; 702 goto discard_symbol;
678 703
679 *module++ = '\0'; 704 *module++ = '\0';
680 705
681 if (strcmp(curr_map->dso->short_name, module)) { 706 if (strcmp(curr_map->dso->short_name, module)) {
682 if (curr_map != map && 707 if (curr_map != map &&
683 dso->kernel == DSO_TYPE_GUEST_KERNEL && 708 dso->kernel == DSO_TYPE_GUEST_KERNEL &&
684 machine__is_default_guest(machine)) { 709 machine__is_default_guest(machine)) {
685 /* 710 /*
686 * We assume all symbols of a module are 711 * We assume all symbols of a module are
687 * continuous in * kallsyms, so curr_map 712 * continuous in * kallsyms, so curr_map
688 * points to a module and all its 713 * points to a module and all its
689 * symbols are in its kmap. Mark it as 714 * symbols are in its kmap. Mark it as
690 * loaded. 715 * loaded.
691 */ 716 */
692 dso__set_loaded(curr_map->dso, 717 dso__set_loaded(curr_map->dso,
693 curr_map->type); 718 curr_map->type);
694 } 719 }
695 720
696 curr_map = map_groups__find_by_name(kmaps, 721 curr_map = map_groups__find_by_name(kmaps,
697 map->type, module); 722 map->type, module);
698 if (curr_map == NULL) { 723 if (curr_map == NULL) {
699 pr_debug("%s/proc/{kallsyms,modules} " 724 pr_debug("%s/proc/{kallsyms,modules} "
700 "inconsistency while looking " 725 "inconsistency while looking "
701 "for \"%s\" module!\n", 726 "for \"%s\" module!\n",
702 machine->root_dir, module); 727 machine->root_dir, module);
703 curr_map = map; 728 curr_map = map;
704 goto discard_symbol; 729 goto discard_symbol;
705 } 730 }
706 731
707 if (curr_map->dso->loaded && 732 if (curr_map->dso->loaded &&
708 !machine__is_default_guest(machine)) 733 !machine__is_default_guest(machine))
709 goto discard_symbol; 734 goto discard_symbol;
710 } 735 }
711 /* 736 /*
712 * So that we look just like we get from .ko files, 737 * So that we look just like we get from .ko files,
713 * i.e. not prelinked, relative to map->start. 738 * i.e. not prelinked, relative to map->start.
714 */ 739 */
715 pos->start = curr_map->map_ip(curr_map, pos->start); 740 pos->start = curr_map->map_ip(curr_map, pos->start);
716 pos->end = curr_map->map_ip(curr_map, pos->end); 741 pos->end = curr_map->map_ip(curr_map, pos->end);
717 } else if (curr_map != map) { 742 } else if (curr_map != map) {
718 char dso_name[PATH_MAX]; 743 char dso_name[PATH_MAX];
719 struct dso *ndso; 744 struct dso *ndso;
720 745
721 if (delta) { 746 if (delta) {
722 /* Kernel was relocated at boot time */ 747 /* Kernel was relocated at boot time */
723 pos->start -= delta; 748 pos->start -= delta;
724 pos->end -= delta; 749 pos->end -= delta;
725 } 750 }
726 751
727 if (count == 0) { 752 if (count == 0) {
728 curr_map = map; 753 curr_map = map;
729 goto filter_symbol; 754 goto filter_symbol;
730 } 755 }
731 756
732 if (dso->kernel == DSO_TYPE_GUEST_KERNEL) 757 if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
733 snprintf(dso_name, sizeof(dso_name), 758 snprintf(dso_name, sizeof(dso_name),
734 "[guest.kernel].%d", 759 "[guest.kernel].%d",
735 kernel_range++); 760 kernel_range++);
736 else 761 else
737 snprintf(dso_name, sizeof(dso_name), 762 snprintf(dso_name, sizeof(dso_name),
738 "[kernel].%d", 763 "[kernel].%d",
739 kernel_range++); 764 kernel_range++);
740 765
741 ndso = dso__new(dso_name); 766 ndso = dso__new(dso_name);
742 if (ndso == NULL) 767 if (ndso == NULL)
743 return -1; 768 return -1;
744 769
745 ndso->kernel = dso->kernel; 770 ndso->kernel = dso->kernel;
746 771
747 curr_map = map__new2(pos->start, ndso, map->type); 772 curr_map = map__new2(pos->start, ndso, map->type);
748 if (curr_map == NULL) { 773 if (curr_map == NULL) {
749 dso__delete(ndso); 774 dso__delete(ndso);
750 return -1; 775 return -1;
751 } 776 }
752 777
753 curr_map->map_ip = curr_map->unmap_ip = identity__map_ip; 778 curr_map->map_ip = curr_map->unmap_ip = identity__map_ip;
754 map_groups__insert(kmaps, curr_map); 779 map_groups__insert(kmaps, curr_map);
755 ++kernel_range; 780 ++kernel_range;
756 } else if (delta) { 781 } else if (delta) {
757 /* Kernel was relocated at boot time */ 782 /* Kernel was relocated at boot time */
758 pos->start -= delta; 783 pos->start -= delta;
759 pos->end -= delta; 784 pos->end -= delta;
760 } 785 }
761 filter_symbol: 786 filter_symbol:
762 if (filter && filter(curr_map, pos)) { 787 if (filter && filter(curr_map, pos)) {
763 discard_symbol: rb_erase(&pos->rb_node, root); 788 discard_symbol: rb_erase(&pos->rb_node, root);
764 symbol__delete(pos); 789 symbol__delete(pos);
765 } else { 790 } else {
766 if (curr_map != map) { 791 if (curr_map != map) {
767 rb_erase(&pos->rb_node, root); 792 rb_erase(&pos->rb_node, root);
768 symbols__insert(&curr_map->dso->symbols[curr_map->type], pos); 793 symbols__insert(&curr_map->dso->symbols[curr_map->type], pos);
769 ++moved; 794 ++moved;
770 } else 795 } else
771 ++count; 796 ++count;
772 } 797 }
773 } 798 }
774 799
775 if (curr_map != map && 800 if (curr_map != map &&
776 dso->kernel == DSO_TYPE_GUEST_KERNEL && 801 dso->kernel == DSO_TYPE_GUEST_KERNEL &&
777 machine__is_default_guest(kmaps->machine)) { 802 machine__is_default_guest(kmaps->machine)) {
778 dso__set_loaded(curr_map->dso, curr_map->type); 803 dso__set_loaded(curr_map->dso, curr_map->type);
779 } 804 }
780 805
781 return count + moved; 806 return count + moved;
782 } 807 }
783 808
784 bool symbol__restricted_filename(const char *filename, 809 bool symbol__restricted_filename(const char *filename,
785 const char *restricted_filename) 810 const char *restricted_filename)
786 { 811 {
787 bool restricted = false; 812 bool restricted = false;
788 813
789 if (symbol_conf.kptr_restrict) { 814 if (symbol_conf.kptr_restrict) {
790 char *r = realpath(filename, NULL); 815 char *r = realpath(filename, NULL);
791 816
792 if (r != NULL) { 817 if (r != NULL) {
793 restricted = strcmp(r, restricted_filename) == 0; 818 restricted = strcmp(r, restricted_filename) == 0;
794 free(r); 819 free(r);
795 return restricted; 820 return restricted;
796 } 821 }
797 } 822 }
798 823
799 return restricted; 824 return restricted;
800 } 825 }
801 826
802 struct module_info { 827 struct module_info {
803 struct rb_node rb_node; 828 struct rb_node rb_node;
804 char *name; 829 char *name;
805 u64 start; 830 u64 start;
806 }; 831 };
807 832
808 static void add_module(struct module_info *mi, struct rb_root *modules) 833 static void add_module(struct module_info *mi, struct rb_root *modules)
809 { 834 {
810 struct rb_node **p = &modules->rb_node; 835 struct rb_node **p = &modules->rb_node;
811 struct rb_node *parent = NULL; 836 struct rb_node *parent = NULL;
812 struct module_info *m; 837 struct module_info *m;
813 838
814 while (*p != NULL) { 839 while (*p != NULL) {
815 parent = *p; 840 parent = *p;
816 m = rb_entry(parent, struct module_info, rb_node); 841 m = rb_entry(parent, struct module_info, rb_node);
817 if (strcmp(mi->name, m->name) < 0) 842 if (strcmp(mi->name, m->name) < 0)
818 p = &(*p)->rb_left; 843 p = &(*p)->rb_left;
819 else 844 else
820 p = &(*p)->rb_right; 845 p = &(*p)->rb_right;
821 } 846 }
822 rb_link_node(&mi->rb_node, parent, p); 847 rb_link_node(&mi->rb_node, parent, p);
823 rb_insert_color(&mi->rb_node, modules); 848 rb_insert_color(&mi->rb_node, modules);
824 } 849 }
825 850
826 static void delete_modules(struct rb_root *modules) 851 static void delete_modules(struct rb_root *modules)
827 { 852 {
828 struct module_info *mi; 853 struct module_info *mi;
829 struct rb_node *next = rb_first(modules); 854 struct rb_node *next = rb_first(modules);
830 855
831 while (next) { 856 while (next) {
832 mi = rb_entry(next, struct module_info, rb_node); 857 mi = rb_entry(next, struct module_info, rb_node);
833 next = rb_next(&mi->rb_node); 858 next = rb_next(&mi->rb_node);
834 rb_erase(&mi->rb_node, modules); 859 rb_erase(&mi->rb_node, modules);
835 zfree(&mi->name); 860 zfree(&mi->name);
836 free(mi); 861 free(mi);
837 } 862 }
838 } 863 }
839 864
840 static struct module_info *find_module(const char *name, 865 static struct module_info *find_module(const char *name,
841 struct rb_root *modules) 866 struct rb_root *modules)
842 { 867 {
843 struct rb_node *n = modules->rb_node; 868 struct rb_node *n = modules->rb_node;
844 869
845 while (n) { 870 while (n) {
846 struct module_info *m; 871 struct module_info *m;
847 int cmp; 872 int cmp;
848 873
849 m = rb_entry(n, struct module_info, rb_node); 874 m = rb_entry(n, struct module_info, rb_node);
850 cmp = strcmp(name, m->name); 875 cmp = strcmp(name, m->name);
851 if (cmp < 0) 876 if (cmp < 0)
852 n = n->rb_left; 877 n = n->rb_left;
853 else if (cmp > 0) 878 else if (cmp > 0)
854 n = n->rb_right; 879 n = n->rb_right;
855 else 880 else
856 return m; 881 return m;
857 } 882 }
858 883
859 return NULL; 884 return NULL;
860 } 885 }
861 886
862 static int __read_proc_modules(void *arg, const char *name, u64 start) 887 static int __read_proc_modules(void *arg, const char *name, u64 start)
863 { 888 {
864 struct rb_root *modules = arg; 889 struct rb_root *modules = arg;
865 struct module_info *mi; 890 struct module_info *mi;
866 891
867 mi = zalloc(sizeof(struct module_info)); 892 mi = zalloc(sizeof(struct module_info));
868 if (!mi) 893 if (!mi)
869 return -ENOMEM; 894 return -ENOMEM;
870 895
871 mi->name = strdup(name); 896 mi->name = strdup(name);
872 mi->start = start; 897 mi->start = start;
873 898
874 if (!mi->name) { 899 if (!mi->name) {
875 free(mi); 900 free(mi);
876 return -ENOMEM; 901 return -ENOMEM;
877 } 902 }
878 903
879 add_module(mi, modules); 904 add_module(mi, modules);
880 905
881 return 0; 906 return 0;
882 } 907 }
883 908
884 static int read_proc_modules(const char *filename, struct rb_root *modules) 909 static int read_proc_modules(const char *filename, struct rb_root *modules)
885 { 910 {
886 if (symbol__restricted_filename(filename, "/proc/modules")) 911 if (symbol__restricted_filename(filename, "/proc/modules"))
887 return -1; 912 return -1;
888 913
889 if (modules__parse(filename, modules, __read_proc_modules)) { 914 if (modules__parse(filename, modules, __read_proc_modules)) {
890 delete_modules(modules); 915 delete_modules(modules);
891 return -1; 916 return -1;
892 } 917 }
893 918
894 return 0; 919 return 0;
895 } 920 }
896 921
897 int compare_proc_modules(const char *from, const char *to) 922 int compare_proc_modules(const char *from, const char *to)
898 { 923 {
899 struct rb_root from_modules = RB_ROOT; 924 struct rb_root from_modules = RB_ROOT;
900 struct rb_root to_modules = RB_ROOT; 925 struct rb_root to_modules = RB_ROOT;
901 struct rb_node *from_node, *to_node; 926 struct rb_node *from_node, *to_node;
902 struct module_info *from_m, *to_m; 927 struct module_info *from_m, *to_m;
903 int ret = -1; 928 int ret = -1;
904 929
905 if (read_proc_modules(from, &from_modules)) 930 if (read_proc_modules(from, &from_modules))
906 return -1; 931 return -1;
907 932
908 if (read_proc_modules(to, &to_modules)) 933 if (read_proc_modules(to, &to_modules))
909 goto out_delete_from; 934 goto out_delete_from;
910 935
911 from_node = rb_first(&from_modules); 936 from_node = rb_first(&from_modules);
912 to_node = rb_first(&to_modules); 937 to_node = rb_first(&to_modules);
913 while (from_node) { 938 while (from_node) {
914 if (!to_node) 939 if (!to_node)
915 break; 940 break;
916 941
917 from_m = rb_entry(from_node, struct module_info, rb_node); 942 from_m = rb_entry(from_node, struct module_info, rb_node);
918 to_m = rb_entry(to_node, struct module_info, rb_node); 943 to_m = rb_entry(to_node, struct module_info, rb_node);
919 944
920 if (from_m->start != to_m->start || 945 if (from_m->start != to_m->start ||
921 strcmp(from_m->name, to_m->name)) 946 strcmp(from_m->name, to_m->name))
922 break; 947 break;
923 948
924 from_node = rb_next(from_node); 949 from_node = rb_next(from_node);
925 to_node = rb_next(to_node); 950 to_node = rb_next(to_node);
926 } 951 }
927 952
928 if (!from_node && !to_node) 953 if (!from_node && !to_node)
929 ret = 0; 954 ret = 0;
930 955
931 delete_modules(&to_modules); 956 delete_modules(&to_modules);
932 out_delete_from: 957 out_delete_from:
933 delete_modules(&from_modules); 958 delete_modules(&from_modules);
934 959
935 return ret; 960 return ret;
936 } 961 }
937 962
938 static int do_validate_kcore_modules(const char *filename, struct map *map, 963 static int do_validate_kcore_modules(const char *filename, struct map *map,
939 struct map_groups *kmaps) 964 struct map_groups *kmaps)
940 { 965 {
941 struct rb_root modules = RB_ROOT; 966 struct rb_root modules = RB_ROOT;
942 struct map *old_map; 967 struct map *old_map;
943 int err; 968 int err;
944 969
945 err = read_proc_modules(filename, &modules); 970 err = read_proc_modules(filename, &modules);
946 if (err) 971 if (err)
947 return err; 972 return err;
948 973
949 old_map = map_groups__first(kmaps, map->type); 974 old_map = map_groups__first(kmaps, map->type);
950 while (old_map) { 975 while (old_map) {
951 struct map *next = map_groups__next(old_map); 976 struct map *next = map_groups__next(old_map);
952 struct module_info *mi; 977 struct module_info *mi;
953 978
954 if (old_map == map || old_map->start == map->start) { 979 if (old_map == map || old_map->start == map->start) {
955 /* The kernel map */ 980 /* The kernel map */
956 old_map = next; 981 old_map = next;
957 continue; 982 continue;
958 } 983 }
959 984
960 /* Module must be in memory at the same address */ 985 /* Module must be in memory at the same address */
961 mi = find_module(old_map->dso->short_name, &modules); 986 mi = find_module(old_map->dso->short_name, &modules);
962 if (!mi || mi->start != old_map->start) { 987 if (!mi || mi->start != old_map->start) {
963 err = -EINVAL; 988 err = -EINVAL;
964 goto out; 989 goto out;
965 } 990 }
966 991
967 old_map = next; 992 old_map = next;
968 } 993 }
969 out: 994 out:
970 delete_modules(&modules); 995 delete_modules(&modules);
971 return err; 996 return err;
972 } 997 }
973 998
974 /* 999 /*
975 * If kallsyms is referenced by name then we look for filename in the same 1000 * If kallsyms is referenced by name then we look for filename in the same
976 * directory. 1001 * directory.
977 */ 1002 */
978 static bool filename_from_kallsyms_filename(char *filename, 1003 static bool filename_from_kallsyms_filename(char *filename,
979 const char *base_name, 1004 const char *base_name,
980 const char *kallsyms_filename) 1005 const char *kallsyms_filename)
981 { 1006 {
982 char *name; 1007 char *name;
983 1008
984 strcpy(filename, kallsyms_filename); 1009 strcpy(filename, kallsyms_filename);
985 name = strrchr(filename, '/'); 1010 name = strrchr(filename, '/');
986 if (!name) 1011 if (!name)
987 return false; 1012 return false;
988 1013
989 name += 1; 1014 name += 1;
990 1015
991 if (!strcmp(name, "kallsyms")) { 1016 if (!strcmp(name, "kallsyms")) {
992 strcpy(name, base_name); 1017 strcpy(name, base_name);
993 return true; 1018 return true;
994 } 1019 }
995 1020
996 return false; 1021 return false;
997 } 1022 }
998 1023
999 static int validate_kcore_modules(const char *kallsyms_filename, 1024 static int validate_kcore_modules(const char *kallsyms_filename,
1000 struct map *map) 1025 struct map *map)
1001 { 1026 {
1002 struct map_groups *kmaps = map__kmap(map)->kmaps; 1027 struct map_groups *kmaps = map__kmap(map)->kmaps;
1003 char modules_filename[PATH_MAX]; 1028 char modules_filename[PATH_MAX];
1004 1029
1005 if (!filename_from_kallsyms_filename(modules_filename, "modules", 1030 if (!filename_from_kallsyms_filename(modules_filename, "modules",
1006 kallsyms_filename)) 1031 kallsyms_filename))
1007 return -EINVAL; 1032 return -EINVAL;
1008 1033
1009 if (do_validate_kcore_modules(modules_filename, map, kmaps)) 1034 if (do_validate_kcore_modules(modules_filename, map, kmaps))
1010 return -EINVAL; 1035 return -EINVAL;
1011 1036
1012 return 0; 1037 return 0;
1013 } 1038 }
1014 1039
1015 static int validate_kcore_addresses(const char *kallsyms_filename, 1040 static int validate_kcore_addresses(const char *kallsyms_filename,
1016 struct map *map) 1041 struct map *map)
1017 { 1042 {
1018 struct kmap *kmap = map__kmap(map); 1043 struct kmap *kmap = map__kmap(map);
1019 1044
1020 if (kmap->ref_reloc_sym && kmap->ref_reloc_sym->name) { 1045 if (kmap->ref_reloc_sym && kmap->ref_reloc_sym->name) {
1021 u64 start; 1046 u64 start;
1022 1047
1023 start = kallsyms__get_function_start(kallsyms_filename, 1048 start = kallsyms__get_function_start(kallsyms_filename,
1024 kmap->ref_reloc_sym->name); 1049 kmap->ref_reloc_sym->name);
1025 if (start != kmap->ref_reloc_sym->addr) 1050 if (start != kmap->ref_reloc_sym->addr)
1026 return -EINVAL; 1051 return -EINVAL;
1027 } 1052 }
1028 1053
1029 return validate_kcore_modules(kallsyms_filename, map); 1054 return validate_kcore_modules(kallsyms_filename, map);
1030 } 1055 }
1031 1056
1032 struct kcore_mapfn_data { 1057 struct kcore_mapfn_data {
1033 struct dso *dso; 1058 struct dso *dso;
1034 enum map_type type; 1059 enum map_type type;
1035 struct list_head maps; 1060 struct list_head maps;
1036 }; 1061 };
1037 1062
1038 static int kcore_mapfn(u64 start, u64 len, u64 pgoff, void *data) 1063 static int kcore_mapfn(u64 start, u64 len, u64 pgoff, void *data)
1039 { 1064 {
1040 struct kcore_mapfn_data *md = data; 1065 struct kcore_mapfn_data *md = data;
1041 struct map *map; 1066 struct map *map;
1042 1067
1043 map = map__new2(start, md->dso, md->type); 1068 map = map__new2(start, md->dso, md->type);
1044 if (map == NULL) 1069 if (map == NULL)
1045 return -ENOMEM; 1070 return -ENOMEM;
1046 1071
1047 map->end = map->start + len; 1072 map->end = map->start + len;
1048 map->pgoff = pgoff; 1073 map->pgoff = pgoff;
1049 1074
1050 list_add(&map->node, &md->maps); 1075 list_add(&map->node, &md->maps);
1051 1076
1052 return 0; 1077 return 0;
1053 } 1078 }
1054 1079
1055 static int dso__load_kcore(struct dso *dso, struct map *map, 1080 static int dso__load_kcore(struct dso *dso, struct map *map,
1056 const char *kallsyms_filename) 1081 const char *kallsyms_filename)
1057 { 1082 {
1058 struct map_groups *kmaps = map__kmap(map)->kmaps; 1083 struct map_groups *kmaps = map__kmap(map)->kmaps;
1059 struct machine *machine = kmaps->machine; 1084 struct machine *machine = kmaps->machine;
1060 struct kcore_mapfn_data md; 1085 struct kcore_mapfn_data md;
1061 struct map *old_map, *new_map, *replacement_map = NULL; 1086 struct map *old_map, *new_map, *replacement_map = NULL;
1062 bool is_64_bit; 1087 bool is_64_bit;
1063 int err, fd; 1088 int err, fd;
1064 char kcore_filename[PATH_MAX]; 1089 char kcore_filename[PATH_MAX];
1065 struct symbol *sym; 1090 struct symbol *sym;
1066 1091
1067 /* This function requires that the map is the kernel map */ 1092 /* This function requires that the map is the kernel map */
1068 if (map != machine->vmlinux_maps[map->type]) 1093 if (map != machine->vmlinux_maps[map->type])
1069 return -EINVAL; 1094 return -EINVAL;
1070 1095
1071 if (!filename_from_kallsyms_filename(kcore_filename, "kcore", 1096 if (!filename_from_kallsyms_filename(kcore_filename, "kcore",
1072 kallsyms_filename)) 1097 kallsyms_filename))
1073 return -EINVAL; 1098 return -EINVAL;
1074 1099
1075 /* Modules and kernel must be present at their original addresses */ 1100 /* Modules and kernel must be present at their original addresses */
1076 if (validate_kcore_addresses(kallsyms_filename, map)) 1101 if (validate_kcore_addresses(kallsyms_filename, map))
1077 return -EINVAL; 1102 return -EINVAL;
1078 1103
1079 md.dso = dso; 1104 md.dso = dso;
1080 md.type = map->type; 1105 md.type = map->type;
1081 INIT_LIST_HEAD(&md.maps); 1106 INIT_LIST_HEAD(&md.maps);
1082 1107
1083 fd = open(kcore_filename, O_RDONLY); 1108 fd = open(kcore_filename, O_RDONLY);
1084 if (fd < 0) 1109 if (fd < 0)
1085 return -EINVAL; 1110 return -EINVAL;
1086 1111
1087 /* Read new maps into temporary lists */ 1112 /* Read new maps into temporary lists */
1088 err = file__read_maps(fd, md.type == MAP__FUNCTION, kcore_mapfn, &md, 1113 err = file__read_maps(fd, md.type == MAP__FUNCTION, kcore_mapfn, &md,
1089 &is_64_bit); 1114 &is_64_bit);
1090 if (err) 1115 if (err)
1091 goto out_err; 1116 goto out_err;
1092 dso->is_64_bit = is_64_bit; 1117 dso->is_64_bit = is_64_bit;
1093 1118
1094 if (list_empty(&md.maps)) { 1119 if (list_empty(&md.maps)) {
1095 err = -EINVAL; 1120 err = -EINVAL;
1096 goto out_err; 1121 goto out_err;
1097 } 1122 }
1098 1123
1099 /* Remove old maps */ 1124 /* Remove old maps */
1100 old_map = map_groups__first(kmaps, map->type); 1125 old_map = map_groups__first(kmaps, map->type);
1101 while (old_map) { 1126 while (old_map) {
1102 struct map *next = map_groups__next(old_map); 1127 struct map *next = map_groups__next(old_map);
1103 1128
1104 if (old_map != map) 1129 if (old_map != map)
1105 map_groups__remove(kmaps, old_map); 1130 map_groups__remove(kmaps, old_map);
1106 old_map = next; 1131 old_map = next;
1107 } 1132 }
1108 1133
1109 /* Find the kernel map using the first symbol */ 1134 /* Find the kernel map using the first symbol */
1110 sym = dso__first_symbol(dso, map->type); 1135 sym = dso__first_symbol(dso, map->type);
1111 list_for_each_entry(new_map, &md.maps, node) { 1136 list_for_each_entry(new_map, &md.maps, node) {
1112 if (sym && sym->start >= new_map->start && 1137 if (sym && sym->start >= new_map->start &&
1113 sym->start < new_map->end) { 1138 sym->start < new_map->end) {
1114 replacement_map = new_map; 1139 replacement_map = new_map;
1115 break; 1140 break;
1116 } 1141 }
1117 } 1142 }
1118 1143
1119 if (!replacement_map) 1144 if (!replacement_map)
1120 replacement_map = list_entry(md.maps.next, struct map, node); 1145 replacement_map = list_entry(md.maps.next, struct map, node);
1121 1146
1122 /* Add new maps */ 1147 /* Add new maps */
1123 while (!list_empty(&md.maps)) { 1148 while (!list_empty(&md.maps)) {
1124 new_map = list_entry(md.maps.next, struct map, node); 1149 new_map = list_entry(md.maps.next, struct map, node);
1125 list_del(&new_map->node); 1150 list_del(&new_map->node);
1126 if (new_map == replacement_map) { 1151 if (new_map == replacement_map) {
1127 map->start = new_map->start; 1152 map->start = new_map->start;
1128 map->end = new_map->end; 1153 map->end = new_map->end;
1129 map->pgoff = new_map->pgoff; 1154 map->pgoff = new_map->pgoff;
1130 map->map_ip = new_map->map_ip; 1155 map->map_ip = new_map->map_ip;
1131 map->unmap_ip = new_map->unmap_ip; 1156 map->unmap_ip = new_map->unmap_ip;
1132 map__delete(new_map); 1157 map__delete(new_map);
1133 /* Ensure maps are correctly ordered */ 1158 /* Ensure maps are correctly ordered */
1134 map_groups__remove(kmaps, map); 1159 map_groups__remove(kmaps, map);
1135 map_groups__insert(kmaps, map); 1160 map_groups__insert(kmaps, map);
1136 } else { 1161 } else {
1137 map_groups__insert(kmaps, new_map); 1162 map_groups__insert(kmaps, new_map);
1138 } 1163 }
1139 } 1164 }
1140 1165
1141 /* 1166 /*
1142 * Set the data type and long name so that kcore can be read via 1167 * Set the data type and long name so that kcore can be read via
1143 * dso__data_read_addr(). 1168 * dso__data_read_addr().
1144 */ 1169 */
1145 if (dso->kernel == DSO_TYPE_GUEST_KERNEL) 1170 if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
1146 dso->binary_type = DSO_BINARY_TYPE__GUEST_KCORE; 1171 dso->binary_type = DSO_BINARY_TYPE__GUEST_KCORE;
1147 else 1172 else
1148 dso->binary_type = DSO_BINARY_TYPE__KCORE; 1173 dso->binary_type = DSO_BINARY_TYPE__KCORE;
1149 dso__set_long_name(dso, strdup(kcore_filename), true); 1174 dso__set_long_name(dso, strdup(kcore_filename), true);
1150 1175
1151 close(fd); 1176 close(fd);
1152 1177
1153 if (map->type == MAP__FUNCTION) 1178 if (map->type == MAP__FUNCTION)
1154 pr_debug("Using %s for kernel object code\n", kcore_filename); 1179 pr_debug("Using %s for kernel object code\n", kcore_filename);
1155 else 1180 else
1156 pr_debug("Using %s for kernel data\n", kcore_filename); 1181 pr_debug("Using %s for kernel data\n", kcore_filename);
1157 1182
1158 return 0; 1183 return 0;
1159 1184
1160 out_err: 1185 out_err:
1161 while (!list_empty(&md.maps)) { 1186 while (!list_empty(&md.maps)) {
1162 map = list_entry(md.maps.next, struct map, node); 1187 map = list_entry(md.maps.next, struct map, node);
1163 list_del(&map->node); 1188 list_del(&map->node);
1164 map__delete(map); 1189 map__delete(map);
1165 } 1190 }
1166 close(fd); 1191 close(fd);
1167 return -EINVAL; 1192 return -EINVAL;
1168 } 1193 }
1169 1194
1170 /* 1195 /*
1171 * If the kernel is relocated at boot time, kallsyms won't match. Compute the 1196 * If the kernel is relocated at boot time, kallsyms won't match. Compute the
1172 * delta based on the relocation reference symbol. 1197 * delta based on the relocation reference symbol.
1173 */ 1198 */
1174 static int kallsyms__delta(struct map *map, const char *filename, u64 *delta) 1199 static int kallsyms__delta(struct map *map, const char *filename, u64 *delta)
1175 { 1200 {
1176 struct kmap *kmap = map__kmap(map); 1201 struct kmap *kmap = map__kmap(map);
1177 u64 addr; 1202 u64 addr;
1178 1203
1179 if (!kmap->ref_reloc_sym || !kmap->ref_reloc_sym->name) 1204 if (!kmap->ref_reloc_sym || !kmap->ref_reloc_sym->name)
1180 return 0; 1205 return 0;
1181 1206
1182 addr = kallsyms__get_function_start(filename, 1207 addr = kallsyms__get_function_start(filename,
1183 kmap->ref_reloc_sym->name); 1208 kmap->ref_reloc_sym->name);
1184 if (!addr) 1209 if (!addr)
1185 return -1; 1210 return -1;
1186 1211
1187 *delta = addr - kmap->ref_reloc_sym->addr; 1212 *delta = addr - kmap->ref_reloc_sym->addr;
1188 return 0; 1213 return 0;
1189 } 1214 }
1190 1215
1191 int dso__load_kallsyms(struct dso *dso, const char *filename, 1216 int dso__load_kallsyms(struct dso *dso, const char *filename,
1192 struct map *map, symbol_filter_t filter) 1217 struct map *map, symbol_filter_t filter)
1193 { 1218 {
1194 u64 delta = 0; 1219 u64 delta = 0;
1195 1220
1196 if (symbol__restricted_filename(filename, "/proc/kallsyms")) 1221 if (symbol__restricted_filename(filename, "/proc/kallsyms"))
1197 return -1; 1222 return -1;
1198 1223
1199 if (dso__load_all_kallsyms(dso, filename, map) < 0) 1224 if (dso__load_all_kallsyms(dso, filename, map) < 0)
1200 return -1; 1225 return -1;
1201 1226
1202 if (kallsyms__delta(map, filename, &delta)) 1227 if (kallsyms__delta(map, filename, &delta))
1203 return -1; 1228 return -1;
1204 1229
1205 symbols__fixup_duplicate(&dso->symbols[map->type]); 1230 symbols__fixup_duplicate(&dso->symbols[map->type]);
1206 symbols__fixup_end(&dso->symbols[map->type]); 1231 symbols__fixup_end(&dso->symbols[map->type]);
1207 1232
1208 if (dso->kernel == DSO_TYPE_GUEST_KERNEL) 1233 if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
1209 dso->symtab_type = DSO_BINARY_TYPE__GUEST_KALLSYMS; 1234 dso->symtab_type = DSO_BINARY_TYPE__GUEST_KALLSYMS;
1210 else 1235 else
1211 dso->symtab_type = DSO_BINARY_TYPE__KALLSYMS; 1236 dso->symtab_type = DSO_BINARY_TYPE__KALLSYMS;
1212 1237
1213 if (!dso__load_kcore(dso, map, filename)) 1238 if (!dso__load_kcore(dso, map, filename))
1214 return dso__split_kallsyms_for_kcore(dso, map, filter); 1239 return dso__split_kallsyms_for_kcore(dso, map, filter);
1215 else 1240 else
1216 return dso__split_kallsyms(dso, map, delta, filter); 1241 return dso__split_kallsyms(dso, map, delta, filter);
1217 } 1242 }
1218 1243
1219 static int dso__load_perf_map(struct dso *dso, struct map *map, 1244 static int dso__load_perf_map(struct dso *dso, struct map *map,
1220 symbol_filter_t filter) 1245 symbol_filter_t filter)
1221 { 1246 {
1222 char *line = NULL; 1247 char *line = NULL;
1223 size_t n; 1248 size_t n;
1224 FILE *file; 1249 FILE *file;
1225 int nr_syms = 0; 1250 int nr_syms = 0;
1226 1251
1227 file = fopen(dso->long_name, "r"); 1252 file = fopen(dso->long_name, "r");
1228 if (file == NULL) 1253 if (file == NULL)
1229 goto out_failure; 1254 goto out_failure;
1230 1255
1231 while (!feof(file)) { 1256 while (!feof(file)) {
1232 u64 start, size; 1257 u64 start, size;
1233 struct symbol *sym; 1258 struct symbol *sym;
1234 int line_len, len; 1259 int line_len, len;
1235 1260
1236 line_len = getline(&line, &n, file); 1261 line_len = getline(&line, &n, file);
1237 if (line_len < 0) 1262 if (line_len < 0)
1238 break; 1263 break;
1239 1264
1240 if (!line) 1265 if (!line)
1241 goto out_failure; 1266 goto out_failure;
1242 1267
1243 line[--line_len] = '\0'; /* \n */ 1268 line[--line_len] = '\0'; /* \n */
1244 1269
1245 len = hex2u64(line, &start); 1270 len = hex2u64(line, &start);
1246 1271
1247 len++; 1272 len++;
1248 if (len + 2 >= line_len) 1273 if (len + 2 >= line_len)
1249 continue; 1274 continue;
1250 1275
1251 len += hex2u64(line + len, &size); 1276 len += hex2u64(line + len, &size);
1252 1277
1253 len++; 1278 len++;
1254 if (len + 2 >= line_len) 1279 if (len + 2 >= line_len)
1255 continue; 1280 continue;
1256 1281
1257 sym = symbol__new(start, size, STB_GLOBAL, line + len); 1282 sym = symbol__new(start, size, STB_GLOBAL, line + len);
1258 1283
1259 if (sym == NULL) 1284 if (sym == NULL)
1260 goto out_delete_line; 1285 goto out_delete_line;
1261 1286
1262 if (filter && filter(map, sym)) 1287 if (filter && filter(map, sym))
1263 symbol__delete(sym); 1288 symbol__delete(sym);
1264 else { 1289 else {
1265 symbols__insert(&dso->symbols[map->type], sym); 1290 symbols__insert(&dso->symbols[map->type], sym);
1266 nr_syms++; 1291 nr_syms++;
1267 } 1292 }
1268 } 1293 }
1269 1294
1270 free(line); 1295 free(line);
1271 fclose(file); 1296 fclose(file);
1272 1297
1273 return nr_syms; 1298 return nr_syms;
1274 1299
1275 out_delete_line: 1300 out_delete_line:
1276 free(line); 1301 free(line);
1277 out_failure: 1302 out_failure:
1278 return -1; 1303 return -1;
1279 } 1304 }
1280 1305
1281 static bool dso__is_compatible_symtab_type(struct dso *dso, bool kmod, 1306 static bool dso__is_compatible_symtab_type(struct dso *dso, bool kmod,
1282 enum dso_binary_type type) 1307 enum dso_binary_type type)
1283 { 1308 {
1284 switch (type) { 1309 switch (type) {
1285 case DSO_BINARY_TYPE__JAVA_JIT: 1310 case DSO_BINARY_TYPE__JAVA_JIT:
1286 case DSO_BINARY_TYPE__DEBUGLINK: 1311 case DSO_BINARY_TYPE__DEBUGLINK:
1287 case DSO_BINARY_TYPE__SYSTEM_PATH_DSO: 1312 case DSO_BINARY_TYPE__SYSTEM_PATH_DSO:
1288 case DSO_BINARY_TYPE__FEDORA_DEBUGINFO: 1313 case DSO_BINARY_TYPE__FEDORA_DEBUGINFO:
1289 case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO: 1314 case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO:
1290 case DSO_BINARY_TYPE__BUILDID_DEBUGINFO: 1315 case DSO_BINARY_TYPE__BUILDID_DEBUGINFO:
1291 case DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO: 1316 case DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO:
1292 return !kmod && dso->kernel == DSO_TYPE_USER; 1317 return !kmod && dso->kernel == DSO_TYPE_USER;
1293 1318
1294 case DSO_BINARY_TYPE__KALLSYMS: 1319 case DSO_BINARY_TYPE__KALLSYMS:
1295 case DSO_BINARY_TYPE__VMLINUX: 1320 case DSO_BINARY_TYPE__VMLINUX:
1296 case DSO_BINARY_TYPE__KCORE: 1321 case DSO_BINARY_TYPE__KCORE:
1297 return dso->kernel == DSO_TYPE_KERNEL; 1322 return dso->kernel == DSO_TYPE_KERNEL;
1298 1323
1299 case DSO_BINARY_TYPE__GUEST_KALLSYMS: 1324 case DSO_BINARY_TYPE__GUEST_KALLSYMS:
1300 case DSO_BINARY_TYPE__GUEST_VMLINUX: 1325 case DSO_BINARY_TYPE__GUEST_VMLINUX:
1301 case DSO_BINARY_TYPE__GUEST_KCORE: 1326 case DSO_BINARY_TYPE__GUEST_KCORE:
1302 return dso->kernel == DSO_TYPE_GUEST_KERNEL; 1327 return dso->kernel == DSO_TYPE_GUEST_KERNEL;
1303 1328
1304 case DSO_BINARY_TYPE__GUEST_KMODULE: 1329 case DSO_BINARY_TYPE__GUEST_KMODULE:
1305 case DSO_BINARY_TYPE__GUEST_KMODULE_COMP: 1330 case DSO_BINARY_TYPE__GUEST_KMODULE_COMP:
1306 case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE: 1331 case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE:
1307 case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP: 1332 case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP:
1308 /* 1333 /*
1309 * kernel modules know their symtab type - it's set when 1334 * kernel modules know their symtab type - it's set when
1310 * creating a module dso in machine__new_module(). 1335 * creating a module dso in machine__new_module().
1311 */ 1336 */
1312 return kmod && dso->symtab_type == type; 1337 return kmod && dso->symtab_type == type;
1313 1338
1314 case DSO_BINARY_TYPE__BUILD_ID_CACHE: 1339 case DSO_BINARY_TYPE__BUILD_ID_CACHE:
1315 return true; 1340 return true;
1316 1341
1317 case DSO_BINARY_TYPE__NOT_FOUND: 1342 case DSO_BINARY_TYPE__NOT_FOUND:
1318 default: 1343 default:
1319 return false; 1344 return false;
1320 } 1345 }
1321 } 1346 }
1322 1347
1323 int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter) 1348 int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter)
1324 { 1349 {
1325 char *name; 1350 char *name;
1326 int ret = -1; 1351 int ret = -1;
1327 u_int i; 1352 u_int i;
1328 struct machine *machine; 1353 struct machine *machine;
1329 char *root_dir = (char *) ""; 1354 char *root_dir = (char *) "";
1330 int ss_pos = 0; 1355 int ss_pos = 0;
1331 struct symsrc ss_[2]; 1356 struct symsrc ss_[2];
1332 struct symsrc *syms_ss = NULL, *runtime_ss = NULL; 1357 struct symsrc *syms_ss = NULL, *runtime_ss = NULL;
1333 bool kmod; 1358 bool kmod;
1334 1359
1335 dso__set_loaded(dso, map->type); 1360 dso__set_loaded(dso, map->type);
1336 1361
1337 if (dso->kernel == DSO_TYPE_KERNEL) 1362 if (dso->kernel == DSO_TYPE_KERNEL)
1338 return dso__load_kernel_sym(dso, map, filter); 1363 return dso__load_kernel_sym(dso, map, filter);
1339 else if (dso->kernel == DSO_TYPE_GUEST_KERNEL) 1364 else if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
1340 return dso__load_guest_kernel_sym(dso, map, filter); 1365 return dso__load_guest_kernel_sym(dso, map, filter);
1341 1366
1342 if (map->groups && map->groups->machine) 1367 if (map->groups && map->groups->machine)
1343 machine = map->groups->machine; 1368 machine = map->groups->machine;
1344 else 1369 else
1345 machine = NULL; 1370 machine = NULL;
1346 1371
1347 dso->adjust_symbols = 0; 1372 dso->adjust_symbols = 0;
1348 1373
1349 if (strncmp(dso->name, "/tmp/perf-", 10) == 0) { 1374 if (strncmp(dso->name, "/tmp/perf-", 10) == 0) {
1350 struct stat st; 1375 struct stat st;
1351 1376
1352 if (lstat(dso->name, &st) < 0) 1377 if (lstat(dso->name, &st) < 0)
1353 return -1; 1378 return -1;
1354 1379
1355 if (st.st_uid && (st.st_uid != geteuid())) { 1380 if (st.st_uid && (st.st_uid != geteuid())) {
1356 pr_warning("File %s not owned by current user or root, " 1381 pr_warning("File %s not owned by current user or root, "
1357 "ignoring it.\n", dso->name); 1382 "ignoring it.\n", dso->name);
1358 return -1; 1383 return -1;
1359 } 1384 }
1360 1385
1361 ret = dso__load_perf_map(dso, map, filter); 1386 ret = dso__load_perf_map(dso, map, filter);
1362 dso->symtab_type = ret > 0 ? DSO_BINARY_TYPE__JAVA_JIT : 1387 dso->symtab_type = ret > 0 ? DSO_BINARY_TYPE__JAVA_JIT :
1363 DSO_BINARY_TYPE__NOT_FOUND; 1388 DSO_BINARY_TYPE__NOT_FOUND;
1364 return ret; 1389 return ret;
1365 } 1390 }
1366 1391
1367 if (machine) 1392 if (machine)
1368 root_dir = machine->root_dir; 1393 root_dir = machine->root_dir;
1369 1394
1370 name = malloc(PATH_MAX); 1395 name = malloc(PATH_MAX);
1371 if (!name) 1396 if (!name)
1372 return -1; 1397 return -1;
1373 1398
1374 kmod = dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE || 1399 kmod = dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE ||
1375 dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP || 1400 dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP ||
1376 dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE || 1401 dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE ||
1377 dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE_COMP; 1402 dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE_COMP;
1378 1403
1379 /* 1404 /*
1380 * Iterate over candidate debug images. 1405 * Iterate over candidate debug images.
1381 * Keep track of "interesting" ones (those which have a symtab, dynsym, 1406 * Keep track of "interesting" ones (those which have a symtab, dynsym,
1382 * and/or opd section) for processing. 1407 * and/or opd section) for processing.
1383 */ 1408 */
1384 for (i = 0; i < DSO_BINARY_TYPE__SYMTAB_CNT; i++) { 1409 for (i = 0; i < DSO_BINARY_TYPE__SYMTAB_CNT; i++) {
1385 struct symsrc *ss = &ss_[ss_pos]; 1410 struct symsrc *ss = &ss_[ss_pos];
1386 bool next_slot = false; 1411 bool next_slot = false;
1387 1412
1388 enum dso_binary_type symtab_type = binary_type_symtab[i]; 1413 enum dso_binary_type symtab_type = binary_type_symtab[i];
1389 1414
1390 if (!dso__is_compatible_symtab_type(dso, kmod, symtab_type)) 1415 if (!dso__is_compatible_symtab_type(dso, kmod, symtab_type))
1391 continue; 1416 continue;
1392 1417
1393 if (dso__read_binary_type_filename(dso, symtab_type, 1418 if (dso__read_binary_type_filename(dso, symtab_type,
1394 root_dir, name, PATH_MAX)) 1419 root_dir, name, PATH_MAX))
1395 continue; 1420 continue;
1396 1421
1397 /* Name is now the name of the next image to try */ 1422 /* Name is now the name of the next image to try */
1398 if (symsrc__init(ss, dso, name, symtab_type) < 0) 1423 if (symsrc__init(ss, dso, name, symtab_type) < 0)
1399 continue; 1424 continue;
1400 1425
1401 if (!syms_ss && symsrc__has_symtab(ss)) { 1426 if (!syms_ss && symsrc__has_symtab(ss)) {
1402 syms_ss = ss; 1427 syms_ss = ss;
1403 next_slot = true; 1428 next_slot = true;
1404 if (!dso->symsrc_filename) 1429 if (!dso->symsrc_filename)
1405 dso->symsrc_filename = strdup(name); 1430 dso->symsrc_filename = strdup(name);
1406 } 1431 }
1407 1432
1408 if (!runtime_ss && symsrc__possibly_runtime(ss)) { 1433 if (!runtime_ss && symsrc__possibly_runtime(ss)) {
1409 runtime_ss = ss; 1434 runtime_ss = ss;
1410 next_slot = true; 1435 next_slot = true;
1411 } 1436 }
1412 1437
1413 if (next_slot) { 1438 if (next_slot) {
1414 ss_pos++; 1439 ss_pos++;
1415 1440
1416 if (syms_ss && runtime_ss) 1441 if (syms_ss && runtime_ss)
1417 break; 1442 break;
1418 } else { 1443 } else {
1419 symsrc__destroy(ss); 1444 symsrc__destroy(ss);
1420 } 1445 }
1421 1446
1422 } 1447 }
1423 1448
1424 if (!runtime_ss && !syms_ss) 1449 if (!runtime_ss && !syms_ss)
1425 goto out_free; 1450 goto out_free;
1426 1451
1427 if (runtime_ss && !syms_ss) { 1452 if (runtime_ss && !syms_ss) {
1428 syms_ss = runtime_ss; 1453 syms_ss = runtime_ss;
1429 } 1454 }
1430 1455
1431 /* We'll have to hope for the best */ 1456 /* We'll have to hope for the best */
1432 if (!runtime_ss && syms_ss) 1457 if (!runtime_ss && syms_ss)
1433 runtime_ss = syms_ss; 1458 runtime_ss = syms_ss;
1434 1459
1435 if (syms_ss) 1460 if (syms_ss)
1436 ret = dso__load_sym(dso, map, syms_ss, runtime_ss, filter, kmod); 1461 ret = dso__load_sym(dso, map, syms_ss, runtime_ss, filter, kmod);
1437 else 1462 else
1438 ret = -1; 1463 ret = -1;
1439 1464
1440 if (ret > 0) { 1465 if (ret > 0) {
1441 int nr_plt; 1466 int nr_plt;
1442 1467
1443 nr_plt = dso__synthesize_plt_symbols(dso, runtime_ss, map, filter); 1468 nr_plt = dso__synthesize_plt_symbols(dso, runtime_ss, map, filter);
1444 if (nr_plt > 0) 1469 if (nr_plt > 0)
1445 ret += nr_plt; 1470 ret += nr_plt;
1446 } 1471 }
1447 1472
1448 for (; ss_pos > 0; ss_pos--) 1473 for (; ss_pos > 0; ss_pos--)
1449 symsrc__destroy(&ss_[ss_pos - 1]); 1474 symsrc__destroy(&ss_[ss_pos - 1]);
1450 out_free: 1475 out_free:
1451 free(name); 1476 free(name);
1452 if (ret < 0 && strstr(dso->name, " (deleted)") != NULL) 1477 if (ret < 0 && strstr(dso->name, " (deleted)") != NULL)
1453 return 0; 1478 return 0;
1454 return ret; 1479 return ret;
1455 } 1480 }
1456 1481
1457 struct map *map_groups__find_by_name(struct map_groups *mg, 1482 struct map *map_groups__find_by_name(struct map_groups *mg,
1458 enum map_type type, const char *name) 1483 enum map_type type, const char *name)
1459 { 1484 {
1460 struct rb_node *nd; 1485 struct rb_node *nd;
1461 1486
1462 for (nd = rb_first(&mg->maps[type]); nd; nd = rb_next(nd)) { 1487 for (nd = rb_first(&mg->maps[type]); nd; nd = rb_next(nd)) {
1463 struct map *map = rb_entry(nd, struct map, rb_node); 1488 struct map *map = rb_entry(nd, struct map, rb_node);
1464 1489
1465 if (map->dso && strcmp(map->dso->short_name, name) == 0) 1490 if (map->dso && strcmp(map->dso->short_name, name) == 0)
1466 return map; 1491 return map;
1467 } 1492 }
1468 1493
1469 return NULL; 1494 return NULL;
1470 } 1495 }
1471 1496
1472 int dso__load_vmlinux(struct dso *dso, struct map *map, 1497 int dso__load_vmlinux(struct dso *dso, struct map *map,
1473 const char *vmlinux, bool vmlinux_allocated, 1498 const char *vmlinux, bool vmlinux_allocated,
1474 symbol_filter_t filter) 1499 symbol_filter_t filter)
1475 { 1500 {
1476 int err = -1; 1501 int err = -1;
1477 struct symsrc ss; 1502 struct symsrc ss;
1478 char symfs_vmlinux[PATH_MAX]; 1503 char symfs_vmlinux[PATH_MAX];
1479 enum dso_binary_type symtab_type; 1504 enum dso_binary_type symtab_type;
1480 1505
1481 if (vmlinux[0] == '/') 1506 if (vmlinux[0] == '/')
1482 snprintf(symfs_vmlinux, sizeof(symfs_vmlinux), "%s", vmlinux); 1507 snprintf(symfs_vmlinux, sizeof(symfs_vmlinux), "%s", vmlinux);
1483 else 1508 else
1484 symbol__join_symfs(symfs_vmlinux, vmlinux); 1509 symbol__join_symfs(symfs_vmlinux, vmlinux);
1485 1510
1486 if (dso->kernel == DSO_TYPE_GUEST_KERNEL) 1511 if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
1487 symtab_type = DSO_BINARY_TYPE__GUEST_VMLINUX; 1512 symtab_type = DSO_BINARY_TYPE__GUEST_VMLINUX;
1488 else 1513 else
1489 symtab_type = DSO_BINARY_TYPE__VMLINUX; 1514 symtab_type = DSO_BINARY_TYPE__VMLINUX;
1490 1515
1491 if (symsrc__init(&ss, dso, symfs_vmlinux, symtab_type)) 1516 if (symsrc__init(&ss, dso, symfs_vmlinux, symtab_type))
1492 return -1; 1517 return -1;
1493 1518
1494 err = dso__load_sym(dso, map, &ss, &ss, filter, 0); 1519 err = dso__load_sym(dso, map, &ss, &ss, filter, 0);
1495 symsrc__destroy(&ss); 1520 symsrc__destroy(&ss);
1496 1521
1497 if (err > 0) { 1522 if (err > 0) {
1498 if (dso->kernel == DSO_TYPE_GUEST_KERNEL) 1523 if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
1499 dso->binary_type = DSO_BINARY_TYPE__GUEST_VMLINUX; 1524 dso->binary_type = DSO_BINARY_TYPE__GUEST_VMLINUX;
1500 else 1525 else
1501 dso->binary_type = DSO_BINARY_TYPE__VMLINUX; 1526 dso->binary_type = DSO_BINARY_TYPE__VMLINUX;
1502 dso__set_long_name(dso, vmlinux, vmlinux_allocated); 1527 dso__set_long_name(dso, vmlinux, vmlinux_allocated);
1503 dso__set_loaded(dso, map->type); 1528 dso__set_loaded(dso, map->type);
1504 pr_debug("Using %s for symbols\n", symfs_vmlinux); 1529 pr_debug("Using %s for symbols\n", symfs_vmlinux);
1505 } 1530 }
1506 1531
1507 return err; 1532 return err;
1508 } 1533 }
1509 1534
1510 int dso__load_vmlinux_path(struct dso *dso, struct map *map, 1535 int dso__load_vmlinux_path(struct dso *dso, struct map *map,
1511 symbol_filter_t filter) 1536 symbol_filter_t filter)
1512 { 1537 {
1513 int i, err = 0; 1538 int i, err = 0;
1514 char *filename = NULL; 1539 char *filename = NULL;
1515 1540
1516 if (!symbol_conf.ignore_vmlinux_buildid) 1541 if (!symbol_conf.ignore_vmlinux_buildid)
1517 filename = dso__build_id_filename(dso, NULL, 0); 1542 filename = dso__build_id_filename(dso, NULL, 0);
1518 if (filename != NULL) { 1543 if (filename != NULL) {
1519 err = dso__load_vmlinux(dso, map, filename, true, filter); 1544 err = dso__load_vmlinux(dso, map, filename, true, filter);
1520 if (err > 0) 1545 if (err > 0)
1521 goto out; 1546 goto out;
1522 free(filename); 1547 free(filename);
1523 } 1548 }
1524 1549
1525 pr_debug("Looking at the vmlinux_path (%d entries long)\n", 1550 pr_debug("Looking at the vmlinux_path (%d entries long)\n",
1526 vmlinux_path__nr_entries + 1); 1551 vmlinux_path__nr_entries + 1);
1527 1552
1528 for (i = 0; i < vmlinux_path__nr_entries; ++i) { 1553 for (i = 0; i < vmlinux_path__nr_entries; ++i) {
1529 err = dso__load_vmlinux(dso, map, vmlinux_path[i], false, filter); 1554 err = dso__load_vmlinux(dso, map, vmlinux_path[i], false, filter);
1530 if (err > 0) 1555 if (err > 0)
1531 break; 1556 break;
1532 } 1557 }
1533 out: 1558 out:
1534 return err; 1559 return err;
1535 } 1560 }
1536 1561
1537 static int find_matching_kcore(struct map *map, char *dir, size_t dir_sz) 1562 static int find_matching_kcore(struct map *map, char *dir, size_t dir_sz)
1538 { 1563 {
1539 char kallsyms_filename[PATH_MAX]; 1564 char kallsyms_filename[PATH_MAX];
1540 struct dirent *dent; 1565 struct dirent *dent;
1541 int ret = -1; 1566 int ret = -1;
1542 DIR *d; 1567 DIR *d;
1543 1568
1544 d = opendir(dir); 1569 d = opendir(dir);
1545 if (!d) 1570 if (!d)
1546 return -1; 1571 return -1;
1547 1572
1548 while (1) { 1573 while (1) {
1549 dent = readdir(d); 1574 dent = readdir(d);
1550 if (!dent) 1575 if (!dent)
1551 break; 1576 break;
1552 if (dent->d_type != DT_DIR) 1577 if (dent->d_type != DT_DIR)
1553 continue; 1578 continue;
1554 scnprintf(kallsyms_filename, sizeof(kallsyms_filename), 1579 scnprintf(kallsyms_filename, sizeof(kallsyms_filename),
1555 "%s/%s/kallsyms", dir, dent->d_name); 1580 "%s/%s/kallsyms", dir, dent->d_name);
1556 if (!validate_kcore_addresses(kallsyms_filename, map)) { 1581 if (!validate_kcore_addresses(kallsyms_filename, map)) {
1557 strlcpy(dir, kallsyms_filename, dir_sz); 1582 strlcpy(dir, kallsyms_filename, dir_sz);
1558 ret = 0; 1583 ret = 0;
1559 break; 1584 break;
1560 } 1585 }
1561 } 1586 }
1562 1587
1563 closedir(d); 1588 closedir(d);
1564 1589
1565 return ret; 1590 return ret;
1566 } 1591 }
1567 1592
1568 static char *dso__find_kallsyms(struct dso *dso, struct map *map) 1593 static char *dso__find_kallsyms(struct dso *dso, struct map *map)
1569 { 1594 {
1570 u8 host_build_id[BUILD_ID_SIZE]; 1595 u8 host_build_id[BUILD_ID_SIZE];
1571 char sbuild_id[BUILD_ID_SIZE * 2 + 1]; 1596 char sbuild_id[BUILD_ID_SIZE * 2 + 1];
1572 bool is_host = false; 1597 bool is_host = false;
1573 char path[PATH_MAX]; 1598 char path[PATH_MAX];
1574 1599
1575 if (!dso->has_build_id) { 1600 if (!dso->has_build_id) {
1576 /* 1601 /*
1577 * Last resort, if we don't have a build-id and couldn't find 1602 * Last resort, if we don't have a build-id and couldn't find
1578 * any vmlinux file, try the running kernel kallsyms table. 1603 * any vmlinux file, try the running kernel kallsyms table.
1579 */ 1604 */
1580 goto proc_kallsyms; 1605 goto proc_kallsyms;
1581 } 1606 }
1582 1607
1583 if (sysfs__read_build_id("/sys/kernel/notes", host_build_id, 1608 if (sysfs__read_build_id("/sys/kernel/notes", host_build_id,
1584 sizeof(host_build_id)) == 0) 1609 sizeof(host_build_id)) == 0)
1585 is_host = dso__build_id_equal(dso, host_build_id); 1610 is_host = dso__build_id_equal(dso, host_build_id);
1586 1611
1587 build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id); 1612 build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id);
1588 1613
1589 scnprintf(path, sizeof(path), "%s/[kernel.kcore]/%s", buildid_dir, 1614 scnprintf(path, sizeof(path), "%s/[kernel.kcore]/%s", buildid_dir,
1590 sbuild_id); 1615 sbuild_id);
1591 1616
1592 /* Use /proc/kallsyms if possible */ 1617 /* Use /proc/kallsyms if possible */
1593 if (is_host) { 1618 if (is_host) {
1594 DIR *d; 1619 DIR *d;
1595 int fd; 1620 int fd;
1596 1621
1597 /* If no cached kcore go with /proc/kallsyms */ 1622 /* If no cached kcore go with /proc/kallsyms */
1598 d = opendir(path); 1623 d = opendir(path);
1599 if (!d) 1624 if (!d)
1600 goto proc_kallsyms; 1625 goto proc_kallsyms;
1601 closedir(d); 1626 closedir(d);
1602 1627
1603 /* 1628 /*
1604 * Do not check the build-id cache, until we know we cannot use 1629 * Do not check the build-id cache, until we know we cannot use
1605 * /proc/kcore. 1630 * /proc/kcore.
1606 */ 1631 */
1607 fd = open("/proc/kcore", O_RDONLY); 1632 fd = open("/proc/kcore", O_RDONLY);
1608 if (fd != -1) { 1633 if (fd != -1) {
1609 close(fd); 1634 close(fd);
1610 /* If module maps match go with /proc/kallsyms */ 1635 /* If module maps match go with /proc/kallsyms */
1611 if (!validate_kcore_addresses("/proc/kallsyms", map)) 1636 if (!validate_kcore_addresses("/proc/kallsyms", map))
1612 goto proc_kallsyms; 1637 goto proc_kallsyms;
1613 } 1638 }
1614 1639
1615 /* Find kallsyms in build-id cache with kcore */ 1640 /* Find kallsyms in build-id cache with kcore */
1616 if (!find_matching_kcore(map, path, sizeof(path))) 1641 if (!find_matching_kcore(map, path, sizeof(path)))
1617 return strdup(path); 1642 return strdup(path);
1618 1643
1619 goto proc_kallsyms; 1644 goto proc_kallsyms;
1620 } 1645 }
1621 1646
1622 /* Find kallsyms in build-id cache with kcore */ 1647 /* Find kallsyms in build-id cache with kcore */
1623 if (!find_matching_kcore(map, path, sizeof(path))) 1648 if (!find_matching_kcore(map, path, sizeof(path)))
1624 return strdup(path); 1649 return strdup(path);
1625 1650
1626 scnprintf(path, sizeof(path), "%s/[kernel.kallsyms]/%s", 1651 scnprintf(path, sizeof(path), "%s/[kernel.kallsyms]/%s",
1627 buildid_dir, sbuild_id); 1652 buildid_dir, sbuild_id);
1628 1653
1629 if (access(path, F_OK)) { 1654 if (access(path, F_OK)) {
1630 pr_err("No kallsyms or vmlinux with build-id %s was found\n", 1655 pr_err("No kallsyms or vmlinux with build-id %s was found\n",
1631 sbuild_id); 1656 sbuild_id);
1632 return NULL; 1657 return NULL;
1633 } 1658 }
1634 1659
1635 return strdup(path); 1660 return strdup(path);
1636 1661
1637 proc_kallsyms: 1662 proc_kallsyms:
1638 return strdup("/proc/kallsyms"); 1663 return strdup("/proc/kallsyms");
1639 } 1664 }
1640 1665
1641 static int dso__load_kernel_sym(struct dso *dso, struct map *map, 1666 static int dso__load_kernel_sym(struct dso *dso, struct map *map,
1642 symbol_filter_t filter) 1667 symbol_filter_t filter)
1643 { 1668 {
1644 int err; 1669 int err;
1645 const char *kallsyms_filename = NULL; 1670 const char *kallsyms_filename = NULL;
1646 char *kallsyms_allocated_filename = NULL; 1671 char *kallsyms_allocated_filename = NULL;
1647 /* 1672 /*
1648 * Step 1: if the user specified a kallsyms or vmlinux filename, use 1673 * Step 1: if the user specified a kallsyms or vmlinux filename, use
1649 * it and only it, reporting errors to the user if it cannot be used. 1674 * it and only it, reporting errors to the user if it cannot be used.
1650 * 1675 *
1651 * For instance, try to analyse an ARM perf.data file _without_ a 1676 * For instance, try to analyse an ARM perf.data file _without_ a
1652 * build-id, or if the user specifies the wrong path to the right 1677 * build-id, or if the user specifies the wrong path to the right
1653 * vmlinux file, obviously we can't fallback to another vmlinux (a 1678 * vmlinux file, obviously we can't fallback to another vmlinux (a
1654 * x86_86 one, on the machine where analysis is being performed, say), 1679 * x86_86 one, on the machine where analysis is being performed, say),
1655 * or worse, /proc/kallsyms. 1680 * or worse, /proc/kallsyms.
1656 * 1681 *
1657 * If the specified file _has_ a build-id and there is a build-id 1682 * If the specified file _has_ a build-id and there is a build-id
1658 * section in the perf.data file, we will still do the expected 1683 * section in the perf.data file, we will still do the expected
1659 * validation in dso__load_vmlinux and will bail out if they don't 1684 * validation in dso__load_vmlinux and will bail out if they don't
1660 * match. 1685 * match.
1661 */ 1686 */
1662 if (symbol_conf.kallsyms_name != NULL) { 1687 if (symbol_conf.kallsyms_name != NULL) {
1663 kallsyms_filename = symbol_conf.kallsyms_name; 1688 kallsyms_filename = symbol_conf.kallsyms_name;
1664 goto do_kallsyms; 1689 goto do_kallsyms;
1665 } 1690 }
1666 1691
1667 if (!symbol_conf.ignore_vmlinux && symbol_conf.vmlinux_name != NULL) { 1692 if (!symbol_conf.ignore_vmlinux && symbol_conf.vmlinux_name != NULL) {
1668 return dso__load_vmlinux(dso, map, symbol_conf.vmlinux_name, 1693 return dso__load_vmlinux(dso, map, symbol_conf.vmlinux_name,
1669 false, filter); 1694 false, filter);
1670 } 1695 }
1671 1696
1672 if (!symbol_conf.ignore_vmlinux && vmlinux_path != NULL) { 1697 if (!symbol_conf.ignore_vmlinux && vmlinux_path != NULL) {
1673 err = dso__load_vmlinux_path(dso, map, filter); 1698 err = dso__load_vmlinux_path(dso, map, filter);
1674 if (err > 0) 1699 if (err > 0)
1675 return err; 1700 return err;
1676 } 1701 }
1677 1702
1678 /* do not try local files if a symfs was given */ 1703 /* do not try local files if a symfs was given */
1679 if (symbol_conf.symfs[0] != 0) 1704 if (symbol_conf.symfs[0] != 0)
1680 return -1; 1705 return -1;
1681 1706
1682 kallsyms_allocated_filename = dso__find_kallsyms(dso, map); 1707 kallsyms_allocated_filename = dso__find_kallsyms(dso, map);
1683 if (!kallsyms_allocated_filename) 1708 if (!kallsyms_allocated_filename)
1684 return -1; 1709 return -1;
1685 1710
1686 kallsyms_filename = kallsyms_allocated_filename; 1711 kallsyms_filename = kallsyms_allocated_filename;
1687 1712
1688 do_kallsyms: 1713 do_kallsyms:
1689 err = dso__load_kallsyms(dso, kallsyms_filename, map, filter); 1714 err = dso__load_kallsyms(dso, kallsyms_filename, map, filter);
1690 if (err > 0) 1715 if (err > 0)
1691 pr_debug("Using %s for symbols\n", kallsyms_filename); 1716 pr_debug("Using %s for symbols\n", kallsyms_filename);
1692 free(kallsyms_allocated_filename); 1717 free(kallsyms_allocated_filename);
1693 1718
1694 if (err > 0 && !dso__is_kcore(dso)) { 1719 if (err > 0 && !dso__is_kcore(dso)) {
1695 dso->binary_type = DSO_BINARY_TYPE__KALLSYMS; 1720 dso->binary_type = DSO_BINARY_TYPE__KALLSYMS;
1696 dso__set_long_name(dso, "[kernel.kallsyms]", false); 1721 dso__set_long_name(dso, "[kernel.kallsyms]", false);
1697 map__fixup_start(map); 1722 map__fixup_start(map);
1698 map__fixup_end(map); 1723 map__fixup_end(map);
1699 } 1724 }
1700 1725
1701 return err; 1726 return err;
1702 } 1727 }
1703 1728
1704 static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map, 1729 static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map,
1705 symbol_filter_t filter) 1730 symbol_filter_t filter)
1706 { 1731 {
1707 int err; 1732 int err;
1708 const char *kallsyms_filename = NULL; 1733 const char *kallsyms_filename = NULL;
1709 struct machine *machine; 1734 struct machine *machine;
1710 char path[PATH_MAX]; 1735 char path[PATH_MAX];
1711 1736
1712 if (!map->groups) { 1737 if (!map->groups) {
1713 pr_debug("Guest kernel map hasn't the point to groups\n"); 1738 pr_debug("Guest kernel map hasn't the point to groups\n");
1714 return -1; 1739 return -1;
1715 } 1740 }
1716 machine = map->groups->machine; 1741 machine = map->groups->machine;
1717 1742
1718 if (machine__is_default_guest(machine)) { 1743 if (machine__is_default_guest(machine)) {
1719 /* 1744 /*
1720 * if the user specified a vmlinux filename, use it and only 1745 * if the user specified a vmlinux filename, use it and only
1721 * it, reporting errors to the user if it cannot be used. 1746 * it, reporting errors to the user if it cannot be used.
1722 * Or use file guest_kallsyms inputted by user on commandline 1747 * Or use file guest_kallsyms inputted by user on commandline
1723 */ 1748 */
1724 if (symbol_conf.default_guest_vmlinux_name != NULL) { 1749 if (symbol_conf.default_guest_vmlinux_name != NULL) {
1725 err = dso__load_vmlinux(dso, map, 1750 err = dso__load_vmlinux(dso, map,
1726 symbol_conf.default_guest_vmlinux_name, 1751 symbol_conf.default_guest_vmlinux_name,
1727 false, filter); 1752 false, filter);
1728 return err; 1753 return err;
1729 } 1754 }
1730 1755
1731 kallsyms_filename = symbol_conf.default_guest_kallsyms; 1756 kallsyms_filename = symbol_conf.default_guest_kallsyms;
1732 if (!kallsyms_filename) 1757 if (!kallsyms_filename)
1733 return -1; 1758 return -1;
1734 } else { 1759 } else {
1735 sprintf(path, "%s/proc/kallsyms", machine->root_dir); 1760 sprintf(path, "%s/proc/kallsyms", machine->root_dir);
1736 kallsyms_filename = path; 1761 kallsyms_filename = path;
1737 } 1762 }
1738 1763
1739 err = dso__load_kallsyms(dso, kallsyms_filename, map, filter); 1764 err = dso__load_kallsyms(dso, kallsyms_filename, map, filter);
1740 if (err > 0) 1765 if (err > 0)
1741 pr_debug("Using %s for symbols\n", kallsyms_filename); 1766 pr_debug("Using %s for symbols\n", kallsyms_filename);
1742 if (err > 0 && !dso__is_kcore(dso)) { 1767 if (err > 0 && !dso__is_kcore(dso)) {
1743 dso->binary_type = DSO_BINARY_TYPE__GUEST_KALLSYMS; 1768 dso->binary_type = DSO_BINARY_TYPE__GUEST_KALLSYMS;
1744 machine__mmap_name(machine, path, sizeof(path)); 1769 machine__mmap_name(machine, path, sizeof(path));
1745 dso__set_long_name(dso, strdup(path), true); 1770 dso__set_long_name(dso, strdup(path), true);
1746 map__fixup_start(map); 1771 map__fixup_start(map);
1747 map__fixup_end(map); 1772 map__fixup_end(map);
1748 } 1773 }
1749 1774
1750 return err; 1775 return err;
1751 } 1776 }
1752 1777
1753 static void vmlinux_path__exit(void) 1778 static void vmlinux_path__exit(void)
1754 { 1779 {
1755 while (--vmlinux_path__nr_entries >= 0) 1780 while (--vmlinux_path__nr_entries >= 0)
1756 zfree(&vmlinux_path[vmlinux_path__nr_entries]); 1781 zfree(&vmlinux_path[vmlinux_path__nr_entries]);
1757 1782
1758 zfree(&vmlinux_path); 1783 zfree(&vmlinux_path);
1759 } 1784 }
1760 1785
1761 static int vmlinux_path__init(struct perf_session_env *env) 1786 static int vmlinux_path__init(struct perf_session_env *env)
1762 { 1787 {
1763 struct utsname uts; 1788 struct utsname uts;
1764 char bf[PATH_MAX]; 1789 char bf[PATH_MAX];
1765 char *kernel_version; 1790 char *kernel_version;
1766 1791
1767 vmlinux_path = malloc(sizeof(char *) * 6); 1792 vmlinux_path = malloc(sizeof(char *) * 6);
1768 if (vmlinux_path == NULL) 1793 if (vmlinux_path == NULL)
1769 return -1; 1794 return -1;
1770 1795
1771 vmlinux_path[vmlinux_path__nr_entries] = strdup("vmlinux"); 1796 vmlinux_path[vmlinux_path__nr_entries] = strdup("vmlinux");
1772 if (vmlinux_path[vmlinux_path__nr_entries] == NULL) 1797 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1773 goto out_fail; 1798 goto out_fail;
1774 ++vmlinux_path__nr_entries; 1799 ++vmlinux_path__nr_entries;
1775 vmlinux_path[vmlinux_path__nr_entries] = strdup("/boot/vmlinux"); 1800 vmlinux_path[vmlinux_path__nr_entries] = strdup("/boot/vmlinux");
1776 if (vmlinux_path[vmlinux_path__nr_entries] == NULL) 1801 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1777 goto out_fail; 1802 goto out_fail;
1778 ++vmlinux_path__nr_entries; 1803 ++vmlinux_path__nr_entries;
1779 1804
1780 /* only try kernel version if no symfs was given */ 1805 /* only try kernel version if no symfs was given */
1781 if (symbol_conf.symfs[0] != 0) 1806 if (symbol_conf.symfs[0] != 0)
1782 return 0; 1807 return 0;
1783 1808
1784 if (env) { 1809 if (env) {
1785 kernel_version = env->os_release; 1810 kernel_version = env->os_release;
1786 } else { 1811 } else {
1787 if (uname(&uts) < 0) 1812 if (uname(&uts) < 0)
1788 goto out_fail; 1813 goto out_fail;
1789 1814
1790 kernel_version = uts.release; 1815 kernel_version = uts.release;
1791 } 1816 }
1792 1817
1793 snprintf(bf, sizeof(bf), "/boot/vmlinux-%s", kernel_version); 1818 snprintf(bf, sizeof(bf), "/boot/vmlinux-%s", kernel_version);
1794 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf); 1819 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1795 if (vmlinux_path[vmlinux_path__nr_entries] == NULL) 1820 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1796 goto out_fail; 1821 goto out_fail;
1797 ++vmlinux_path__nr_entries; 1822 ++vmlinux_path__nr_entries;
1798 snprintf(bf, sizeof(bf), "/usr/lib/debug/boot/vmlinux-%s", 1823 snprintf(bf, sizeof(bf), "/usr/lib/debug/boot/vmlinux-%s",
1799 kernel_version); 1824 kernel_version);
1800 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf); 1825 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1801 if (vmlinux_path[vmlinux_path__nr_entries] == NULL) 1826 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1802 goto out_fail; 1827 goto out_fail;
1803 ++vmlinux_path__nr_entries; 1828 ++vmlinux_path__nr_entries;
1804 snprintf(bf, sizeof(bf), "/lib/modules/%s/build/vmlinux", kernel_version); 1829 snprintf(bf, sizeof(bf), "/lib/modules/%s/build/vmlinux", kernel_version);
1805 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf); 1830 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1806 if (vmlinux_path[vmlinux_path__nr_entries] == NULL) 1831 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1807 goto out_fail; 1832 goto out_fail;
1808 ++vmlinux_path__nr_entries; 1833 ++vmlinux_path__nr_entries;
1809 snprintf(bf, sizeof(bf), "/usr/lib/debug/lib/modules/%s/vmlinux", 1834 snprintf(bf, sizeof(bf), "/usr/lib/debug/lib/modules/%s/vmlinux",
1810 kernel_version); 1835 kernel_version);
1811 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf); 1836 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1812 if (vmlinux_path[vmlinux_path__nr_entries] == NULL) 1837 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1813 goto out_fail; 1838 goto out_fail;
1814 ++vmlinux_path__nr_entries; 1839 ++vmlinux_path__nr_entries;
1815 1840
1816 return 0; 1841 return 0;
1817 1842
1818 out_fail: 1843 out_fail:
1819 vmlinux_path__exit(); 1844 vmlinux_path__exit();
1820 return -1; 1845 return -1;
1821 } 1846 }
1822 1847
1823 int setup_list(struct strlist **list, const char *list_str, 1848 int setup_list(struct strlist **list, const char *list_str,
1824 const char *list_name) 1849 const char *list_name)
1825 { 1850 {
1826 if (list_str == NULL) 1851 if (list_str == NULL)
1827 return 0; 1852 return 0;
1828 1853
1829 *list = strlist__new(true, list_str); 1854 *list = strlist__new(true, list_str);
1830 if (!*list) { 1855 if (!*list) {
1831 pr_err("problems parsing %s list\n", list_name); 1856 pr_err("problems parsing %s list\n", list_name);
1832 return -1; 1857 return -1;
1833 } 1858 }
1834 return 0; 1859 return 0;
1835 } 1860 }
1836 1861
1837 static bool symbol__read_kptr_restrict(void) 1862 static bool symbol__read_kptr_restrict(void)
1838 { 1863 {
1839 bool value = false; 1864 bool value = false;
1840 1865
1841 if (geteuid() != 0) { 1866 if (geteuid() != 0) {
1842 FILE *fp = fopen("/proc/sys/kernel/kptr_restrict", "r"); 1867 FILE *fp = fopen("/proc/sys/kernel/kptr_restrict", "r");
1843 if (fp != NULL) { 1868 if (fp != NULL) {
1844 char line[8]; 1869 char line[8];
1845 1870
1846 if (fgets(line, sizeof(line), fp) != NULL) 1871 if (fgets(line, sizeof(line), fp) != NULL)
1847 value = atoi(line) != 0; 1872 value = atoi(line) != 0;
1848 1873
1849 fclose(fp); 1874 fclose(fp);
1850 } 1875 }
1851 } 1876 }
1852 1877
1853 return value; 1878 return value;
1854 } 1879 }
1855 1880
1856 int symbol__init(struct perf_session_env *env) 1881 int symbol__init(struct perf_session_env *env)
1857 { 1882 {
1858 const char *symfs; 1883 const char *symfs;
1859 1884
1860 if (symbol_conf.initialized) 1885 if (symbol_conf.initialized)
1861 return 0; 1886 return 0;
1862 1887
1863 symbol_conf.priv_size = PERF_ALIGN(symbol_conf.priv_size, sizeof(u64)); 1888 symbol_conf.priv_size = PERF_ALIGN(symbol_conf.priv_size, sizeof(u64));
1864 1889
1865 symbol__elf_init(); 1890 symbol__elf_init();
1866 1891
1867 if (symbol_conf.sort_by_name) 1892 if (symbol_conf.sort_by_name)
1868 symbol_conf.priv_size += (sizeof(struct symbol_name_rb_node) - 1893 symbol_conf.priv_size += (sizeof(struct symbol_name_rb_node) -
1869 sizeof(struct symbol)); 1894 sizeof(struct symbol));
1870 1895
1871 if (symbol_conf.try_vmlinux_path && vmlinux_path__init(env) < 0) 1896 if (symbol_conf.try_vmlinux_path && vmlinux_path__init(env) < 0)
1872 return -1; 1897 return -1;
1873 1898
1874 if (symbol_conf.field_sep && *symbol_conf.field_sep == '.') { 1899 if (symbol_conf.field_sep && *symbol_conf.field_sep == '.') {
1875 pr_err("'.' is the only non valid --field-separator argument\n"); 1900 pr_err("'.' is the only non valid --field-separator argument\n");
1876 return -1; 1901 return -1;
1877 } 1902 }
1878 1903
1879 if (setup_list(&symbol_conf.dso_list, 1904 if (setup_list(&symbol_conf.dso_list,
1880 symbol_conf.dso_list_str, "dso") < 0) 1905 symbol_conf.dso_list_str, "dso") < 0)
1881 return -1; 1906 return -1;
1882 1907
1883 if (setup_list(&symbol_conf.comm_list, 1908 if (setup_list(&symbol_conf.comm_list,
1884 symbol_conf.comm_list_str, "comm") < 0) 1909 symbol_conf.comm_list_str, "comm") < 0)
1885 goto out_free_dso_list; 1910 goto out_free_dso_list;
1886 1911
1887 if (setup_list(&symbol_conf.sym_list, 1912 if (setup_list(&symbol_conf.sym_list,
1888 symbol_conf.sym_list_str, "symbol") < 0) 1913 symbol_conf.sym_list_str, "symbol") < 0)
1889 goto out_free_comm_list; 1914 goto out_free_comm_list;
1890 1915
1891 /* 1916 /*
1892 * A path to symbols of "/" is identical to "" 1917 * A path to symbols of "/" is identical to ""
1893 * reset here for simplicity. 1918 * reset here for simplicity.
1894 */ 1919 */
1895 symfs = realpath(symbol_conf.symfs, NULL); 1920 symfs = realpath(symbol_conf.symfs, NULL);
1896 if (symfs == NULL) 1921 if (symfs == NULL)
1897 symfs = symbol_conf.symfs; 1922 symfs = symbol_conf.symfs;
1898 if (strcmp(symfs, "/") == 0) 1923 if (strcmp(symfs, "/") == 0)
1899 symbol_conf.symfs = ""; 1924 symbol_conf.symfs = "";
1900 if (symfs != symbol_conf.symfs) 1925 if (symfs != symbol_conf.symfs)
1901 free((void *)symfs); 1926 free((void *)symfs);
1902 1927
1903 symbol_conf.kptr_restrict = symbol__read_kptr_restrict(); 1928 symbol_conf.kptr_restrict = symbol__read_kptr_restrict();
1904 1929
1905 symbol_conf.initialized = true; 1930 symbol_conf.initialized = true;
1906 return 0; 1931 return 0;
1907 1932
1908 out_free_comm_list: 1933 out_free_comm_list:
1909 strlist__delete(symbol_conf.comm_list); 1934 strlist__delete(symbol_conf.comm_list);
1910 out_free_dso_list: 1935 out_free_dso_list:
1911 strlist__delete(symbol_conf.dso_list); 1936 strlist__delete(symbol_conf.dso_list);
1912 return -1; 1937 return -1;
1913 } 1938 }
1914 1939
1915 void symbol__exit(void) 1940 void symbol__exit(void)
1916 { 1941 {
1917 if (!symbol_conf.initialized) 1942 if (!symbol_conf.initialized)
1918 return; 1943 return;
1919 strlist__delete(symbol_conf.sym_list); 1944 strlist__delete(symbol_conf.sym_list);
1920 strlist__delete(symbol_conf.dso_list); 1945 strlist__delete(symbol_conf.dso_list);
1921 strlist__delete(symbol_conf.comm_list); 1946 strlist__delete(symbol_conf.comm_list);
1922 vmlinux_path__exit(); 1947 vmlinux_path__exit();
1923 symbol_conf.sym_list = symbol_conf.dso_list = symbol_conf.comm_list = NULL; 1948 symbol_conf.sym_list = symbol_conf.dso_list = symbol_conf.comm_list = NULL;
1924 symbol_conf.initialized = false; 1949 symbol_conf.initialized = false;
1925 } 1950 }
tools/perf/util/symbol.h
1 #ifndef __PERF_SYMBOL 1 #ifndef __PERF_SYMBOL
2 #define __PERF_SYMBOL 1 2 #define __PERF_SYMBOL 1
3 3
4 #include <linux/types.h> 4 #include <linux/types.h>
5 #include <stdbool.h> 5 #include <stdbool.h>
6 #include <stdint.h> 6 #include <stdint.h>
7 #include "map.h" 7 #include "map.h"
8 #include "../perf.h" 8 #include "../perf.h"
9 #include <linux/list.h> 9 #include <linux/list.h>
10 #include <linux/rbtree.h> 10 #include <linux/rbtree.h>
11 #include <stdio.h> 11 #include <stdio.h>
12 #include <byteswap.h> 12 #include <byteswap.h>
13 #include <libgen.h> 13 #include <libgen.h>
14 #include "build-id.h" 14 #include "build-id.h"
15 #include "event.h" 15 #include "event.h"
16 #include "util.h" 16 #include "util.h"
17 17
18 #ifdef HAVE_LIBELF_SUPPORT 18 #ifdef HAVE_LIBELF_SUPPORT
19 #include <libelf.h> 19 #include <libelf.h>
20 #include <gelf.h> 20 #include <gelf.h>
21 #endif 21 #endif
22 #include <elf.h> 22 #include <elf.h>
23 23
24 #include "dso.h" 24 #include "dso.h"
25 25
26 /* 26 /*
27 * libelf 0.8.x and earlier do not support ELF_C_READ_MMAP; 27 * libelf 0.8.x and earlier do not support ELF_C_READ_MMAP;
28 * for newer versions we can use mmap to reduce memory usage: 28 * for newer versions we can use mmap to reduce memory usage:
29 */ 29 */
30 #ifdef HAVE_LIBELF_MMAP_SUPPORT 30 #ifdef HAVE_LIBELF_MMAP_SUPPORT
31 # define PERF_ELF_C_READ_MMAP ELF_C_READ_MMAP 31 # define PERF_ELF_C_READ_MMAP ELF_C_READ_MMAP
32 #else 32 #else
33 # define PERF_ELF_C_READ_MMAP ELF_C_READ 33 # define PERF_ELF_C_READ_MMAP ELF_C_READ
34 #endif 34 #endif
35 35
36 #ifdef HAVE_LIBELF_SUPPORT 36 #ifdef HAVE_LIBELF_SUPPORT
37 extern Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep, 37 extern Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
38 GElf_Shdr *shp, const char *name, size_t *idx); 38 GElf_Shdr *shp, const char *name, size_t *idx);
39 #endif 39 #endif
40 40
41 #ifndef DMGL_PARAMS 41 #ifndef DMGL_PARAMS
42 #define DMGL_NO_OPTS 0 /* For readability... */ 42 #define DMGL_NO_OPTS 0 /* For readability... */
43 #define DMGL_PARAMS (1 << 0) /* Include function args */ 43 #define DMGL_PARAMS (1 << 0) /* Include function args */
44 #define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ 44 #define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
45 #endif 45 #endif
46 46
47 /** struct symbol - symtab entry 47 /** struct symbol - symtab entry
48 * 48 *
49 * @ignore - resolvable but tools ignore it (e.g. idle routines) 49 * @ignore - resolvable but tools ignore it (e.g. idle routines)
50 */ 50 */
51 struct symbol { 51 struct symbol {
52 struct rb_node rb_node; 52 struct rb_node rb_node;
53 u64 start; 53 u64 start;
54 u64 end; 54 u64 end;
55 u16 namelen; 55 u16 namelen;
56 u8 binding; 56 u8 binding;
57 bool ignore; 57 bool ignore;
58 char name[0]; 58 char name[0];
59 }; 59 };
60 60
61 void symbol__delete(struct symbol *sym); 61 void symbol__delete(struct symbol *sym);
62 void symbols__delete(struct rb_root *symbols); 62 void symbols__delete(struct rb_root *symbols);
63 63
64 /* symbols__for_each_entry - iterate over symbols (rb_root) 64 /* symbols__for_each_entry - iterate over symbols (rb_root)
65 * 65 *
66 * @symbols: the rb_root of symbols 66 * @symbols: the rb_root of symbols
67 * @pos: the 'struct symbol *' to use as a loop cursor 67 * @pos: the 'struct symbol *' to use as a loop cursor
68 * @nd: the 'struct rb_node *' to use as a temporary storage 68 * @nd: the 'struct rb_node *' to use as a temporary storage
69 */ 69 */
70 #define symbols__for_each_entry(symbols, pos, nd) \ 70 #define symbols__for_each_entry(symbols, pos, nd) \
71 for (nd = rb_first(symbols); \ 71 for (nd = rb_first(symbols); \
72 nd && (pos = rb_entry(nd, struct symbol, rb_node)); \ 72 nd && (pos = rb_entry(nd, struct symbol, rb_node)); \
73 nd = rb_next(nd)) 73 nd = rb_next(nd))
74 74
75 static inline size_t symbol__size(const struct symbol *sym) 75 static inline size_t symbol__size(const struct symbol *sym)
76 { 76 {
77 return sym->end - sym->start; 77 return sym->end - sym->start;
78 } 78 }
79 79
80 struct strlist; 80 struct strlist;
81 81
82 struct symbol_conf { 82 struct symbol_conf {
83 unsigned short priv_size; 83 unsigned short priv_size;
84 unsigned short nr_events; 84 unsigned short nr_events;
85 bool try_vmlinux_path, 85 bool try_vmlinux_path,
86 ignore_vmlinux, 86 ignore_vmlinux,
87 ignore_vmlinux_buildid, 87 ignore_vmlinux_buildid,
88 show_kernel_path, 88 show_kernel_path,
89 use_modules, 89 use_modules,
90 sort_by_name, 90 sort_by_name,
91 show_nr_samples, 91 show_nr_samples,
92 show_total_period, 92 show_total_period,
93 use_callchain, 93 use_callchain,
94 cumulate_callchain, 94 cumulate_callchain,
95 exclude_other, 95 exclude_other,
96 show_cpu_utilization, 96 show_cpu_utilization,
97 initialized, 97 initialized,
98 kptr_restrict, 98 kptr_restrict,
99 annotate_asm_raw, 99 annotate_asm_raw,
100 annotate_src, 100 annotate_src,
101 event_group, 101 event_group,
102 demangle, 102 demangle,
103 demangle_kernel, 103 demangle_kernel,
104 filter_relative, 104 filter_relative,
105 show_hist_headers, 105 show_hist_headers,
106 branch_callstack; 106 branch_callstack;
107 const char *vmlinux_name, 107 const char *vmlinux_name,
108 *kallsyms_name, 108 *kallsyms_name,
109 *source_prefix, 109 *source_prefix,
110 *field_sep; 110 *field_sep;
111 const char *default_guest_vmlinux_name, 111 const char *default_guest_vmlinux_name,
112 *default_guest_kallsyms, 112 *default_guest_kallsyms,
113 *default_guest_modules; 113 *default_guest_modules;
114 const char *guestmount; 114 const char *guestmount;
115 const char *dso_list_str, 115 const char *dso_list_str,
116 *comm_list_str, 116 *comm_list_str,
117 *sym_list_str, 117 *sym_list_str,
118 *col_width_list_str; 118 *col_width_list_str;
119 struct strlist *dso_list, 119 struct strlist *dso_list,
120 *comm_list, 120 *comm_list,
121 *sym_list, 121 *sym_list,
122 *dso_from_list, 122 *dso_from_list,
123 *dso_to_list, 123 *dso_to_list,
124 *sym_from_list, 124 *sym_from_list,
125 *sym_to_list; 125 *sym_to_list;
126 const char *symfs; 126 const char *symfs;
127 }; 127 };
128 128
129 extern struct symbol_conf symbol_conf; 129 extern struct symbol_conf symbol_conf;
130 130
131 static inline int __symbol__join_symfs(char *bf, size_t size, const char *path) 131 static inline int __symbol__join_symfs(char *bf, size_t size, const char *path)
132 { 132 {
133 return path__join(bf, size, symbol_conf.symfs, path); 133 return path__join(bf, size, symbol_conf.symfs, path);
134 } 134 }
135 135
136 #define symbol__join_symfs(bf, path) __symbol__join_symfs(bf, sizeof(bf), path) 136 #define symbol__join_symfs(bf, path) __symbol__join_symfs(bf, sizeof(bf), path)
137 137
138 extern int vmlinux_path__nr_entries; 138 extern int vmlinux_path__nr_entries;
139 extern char **vmlinux_path; 139 extern char **vmlinux_path;
140 140
141 static inline void *symbol__priv(struct symbol *sym) 141 static inline void *symbol__priv(struct symbol *sym)
142 { 142 {
143 return ((void *)sym) - symbol_conf.priv_size; 143 return ((void *)sym) - symbol_conf.priv_size;
144 } 144 }
145 145
146 struct ref_reloc_sym { 146 struct ref_reloc_sym {
147 const char *name; 147 const char *name;
148 u64 addr; 148 u64 addr;
149 u64 unrelocated_addr; 149 u64 unrelocated_addr;
150 }; 150 };
151 151
152 struct map_symbol { 152 struct map_symbol {
153 struct map *map; 153 struct map *map;
154 struct symbol *sym; 154 struct symbol *sym;
155 bool unfolded; 155 bool unfolded;
156 bool has_children; 156 bool has_children;
157 }; 157 };
158 158
159 struct addr_map_symbol { 159 struct addr_map_symbol {
160 struct map *map; 160 struct map *map;
161 struct symbol *sym; 161 struct symbol *sym;
162 u64 addr; 162 u64 addr;
163 u64 al_addr; 163 u64 al_addr;
164 }; 164 };
165 165
166 struct branch_info { 166 struct branch_info {
167 struct addr_map_symbol from; 167 struct addr_map_symbol from;
168 struct addr_map_symbol to; 168 struct addr_map_symbol to;
169 struct branch_flags flags; 169 struct branch_flags flags;
170 }; 170 };
171 171
172 struct mem_info { 172 struct mem_info {
173 struct addr_map_symbol iaddr; 173 struct addr_map_symbol iaddr;
174 struct addr_map_symbol daddr; 174 struct addr_map_symbol daddr;
175 union perf_mem_data_src data_src; 175 union perf_mem_data_src data_src;
176 }; 176 };
177 177
178 struct addr_location { 178 struct addr_location {
179 struct machine *machine; 179 struct machine *machine;
180 struct thread *thread; 180 struct thread *thread;
181 struct map *map; 181 struct map *map;
182 struct symbol *sym; 182 struct symbol *sym;
183 u64 addr; 183 u64 addr;
184 char level; 184 char level;
185 u8 filtered; 185 u8 filtered;
186 u8 cpumode; 186 u8 cpumode;
187 s32 cpu; 187 s32 cpu;
188 }; 188 };
189 189
190 struct symsrc { 190 struct symsrc {
191 char *name; 191 char *name;
192 int fd; 192 int fd;
193 enum dso_binary_type type; 193 enum dso_binary_type type;
194 194
195 #ifdef HAVE_LIBELF_SUPPORT 195 #ifdef HAVE_LIBELF_SUPPORT
196 Elf *elf; 196 Elf *elf;
197 GElf_Ehdr ehdr; 197 GElf_Ehdr ehdr;
198 198
199 Elf_Scn *opdsec; 199 Elf_Scn *opdsec;
200 size_t opdidx; 200 size_t opdidx;
201 GElf_Shdr opdshdr; 201 GElf_Shdr opdshdr;
202 202
203 Elf_Scn *symtab; 203 Elf_Scn *symtab;
204 GElf_Shdr symshdr; 204 GElf_Shdr symshdr;
205 205
206 Elf_Scn *dynsym; 206 Elf_Scn *dynsym;
207 size_t dynsym_idx; 207 size_t dynsym_idx;
208 GElf_Shdr dynshdr; 208 GElf_Shdr dynshdr;
209 209
210 bool adjust_symbols; 210 bool adjust_symbols;
211 bool is_64_bit; 211 bool is_64_bit;
212 #endif 212 #endif
213 }; 213 };
214 214
215 void symsrc__destroy(struct symsrc *ss); 215 void symsrc__destroy(struct symsrc *ss);
216 int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name, 216 int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name,
217 enum dso_binary_type type); 217 enum dso_binary_type type);
218 bool symsrc__has_symtab(struct symsrc *ss); 218 bool symsrc__has_symtab(struct symsrc *ss);
219 bool symsrc__possibly_runtime(struct symsrc *ss); 219 bool symsrc__possibly_runtime(struct symsrc *ss);
220 220
221 int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter); 221 int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter);
222 int dso__load_vmlinux(struct dso *dso, struct map *map, 222 int dso__load_vmlinux(struct dso *dso, struct map *map,
223 const char *vmlinux, bool vmlinux_allocated, 223 const char *vmlinux, bool vmlinux_allocated,
224 symbol_filter_t filter); 224 symbol_filter_t filter);
225 int dso__load_vmlinux_path(struct dso *dso, struct map *map, 225 int dso__load_vmlinux_path(struct dso *dso, struct map *map,
226 symbol_filter_t filter); 226 symbol_filter_t filter);
227 int dso__load_kallsyms(struct dso *dso, const char *filename, struct map *map, 227 int dso__load_kallsyms(struct dso *dso, const char *filename, struct map *map,
228 symbol_filter_t filter); 228 symbol_filter_t filter);
229 229
230 struct symbol *dso__find_symbol(struct dso *dso, enum map_type type, 230 struct symbol *dso__find_symbol(struct dso *dso, enum map_type type,
231 u64 addr); 231 u64 addr);
232 struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type, 232 struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type,
233 const char *name); 233 const char *name);
234 struct symbol *symbol__next_by_name(struct symbol *sym);
234 235
235 struct symbol *dso__first_symbol(struct dso *dso, enum map_type type); 236 struct symbol *dso__first_symbol(struct dso *dso, enum map_type type);
236 struct symbol *dso__next_symbol(struct symbol *sym); 237 struct symbol *dso__next_symbol(struct symbol *sym);
237 238
238 enum dso_type dso__type_fd(int fd); 239 enum dso_type dso__type_fd(int fd);
239 240
240 int filename__read_build_id(const char *filename, void *bf, size_t size); 241 int filename__read_build_id(const char *filename, void *bf, size_t size);
241 int sysfs__read_build_id(const char *filename, void *bf, size_t size); 242 int sysfs__read_build_id(const char *filename, void *bf, size_t size);
242 int modules__parse(const char *filename, void *arg, 243 int modules__parse(const char *filename, void *arg,
243 int (*process_module)(void *arg, const char *name, 244 int (*process_module)(void *arg, const char *name,
244 u64 start)); 245 u64 start));
245 int filename__read_debuglink(const char *filename, char *debuglink, 246 int filename__read_debuglink(const char *filename, char *debuglink,
246 size_t size); 247 size_t size);
247 248
248 struct perf_session_env; 249 struct perf_session_env;
249 int symbol__init(struct perf_session_env *env); 250 int symbol__init(struct perf_session_env *env);
250 void symbol__exit(void); 251 void symbol__exit(void);
251 void symbol__elf_init(void); 252 void symbol__elf_init(void);
252 struct symbol *symbol__new(u64 start, u64 len, u8 binding, const char *name); 253 struct symbol *symbol__new(u64 start, u64 len, u8 binding, const char *name);
253 size_t symbol__fprintf_symname_offs(const struct symbol *sym, 254 size_t symbol__fprintf_symname_offs(const struct symbol *sym,
254 const struct addr_location *al, FILE *fp); 255 const struct addr_location *al, FILE *fp);
255 size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp); 256 size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp);
256 size_t symbol__fprintf(struct symbol *sym, FILE *fp); 257 size_t symbol__fprintf(struct symbol *sym, FILE *fp);
257 bool symbol_type__is_a(char symbol_type, enum map_type map_type); 258 bool symbol_type__is_a(char symbol_type, enum map_type map_type);
258 bool symbol__restricted_filename(const char *filename, 259 bool symbol__restricted_filename(const char *filename,
259 const char *restricted_filename); 260 const char *restricted_filename);
260 bool symbol__is_idle(struct symbol *sym); 261 bool symbol__is_idle(struct symbol *sym);
261 262
262 int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, 263 int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
263 struct symsrc *runtime_ss, symbol_filter_t filter, 264 struct symsrc *runtime_ss, symbol_filter_t filter,
264 int kmodule); 265 int kmodule);
265 int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, 266 int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss,
266 struct map *map, symbol_filter_t filter); 267 struct map *map, symbol_filter_t filter);
267 268
268 void symbols__insert(struct rb_root *symbols, struct symbol *sym); 269 void symbols__insert(struct rb_root *symbols, struct symbol *sym);
269 void symbols__fixup_duplicate(struct rb_root *symbols); 270 void symbols__fixup_duplicate(struct rb_root *symbols);
270 void symbols__fixup_end(struct rb_root *symbols); 271 void symbols__fixup_end(struct rb_root *symbols);
271 void __map_groups__fixup_end(struct map_groups *mg, enum map_type type); 272 void __map_groups__fixup_end(struct map_groups *mg, enum map_type type);
272 273
273 typedef int (*mapfn_t)(u64 start, u64 len, u64 pgoff, void *data); 274 typedef int (*mapfn_t)(u64 start, u64 len, u64 pgoff, void *data);
274 int file__read_maps(int fd, bool exe, mapfn_t mapfn, void *data, 275 int file__read_maps(int fd, bool exe, mapfn_t mapfn, void *data,
275 bool *is_64_bit); 276 bool *is_64_bit);
276 277
277 #define PERF_KCORE_EXTRACT "/tmp/perf-kcore-XXXXXX" 278 #define PERF_KCORE_EXTRACT "/tmp/perf-kcore-XXXXXX"
278 279
279 struct kcore_extract { 280 struct kcore_extract {
280 char *kcore_filename; 281 char *kcore_filename;
281 u64 addr; 282 u64 addr;
282 u64 offs; 283 u64 offs;
283 u64 len; 284 u64 len;
284 char extract_filename[sizeof(PERF_KCORE_EXTRACT)]; 285 char extract_filename[sizeof(PERF_KCORE_EXTRACT)];
285 int fd; 286 int fd;
286 }; 287 };
287 288
288 int kcore_extract__create(struct kcore_extract *kce); 289 int kcore_extract__create(struct kcore_extract *kce);
289 void kcore_extract__delete(struct kcore_extract *kce); 290 void kcore_extract__delete(struct kcore_extract *kce);
290 291
291 int kcore_copy(const char *from_dir, const char *to_dir); 292 int kcore_copy(const char *from_dir, const char *to_dir);
292 int compare_proc_modules(const char *from, const char *to); 293 int compare_proc_modules(const char *from, const char *to);
293 294
294 int setup_list(struct strlist **list, const char *list_str, 295 int setup_list(struct strlist **list, const char *list_str,
295 const char *list_name); 296 const char *list_name);
296 297
297 #endif /* __PERF_SYMBOL */ 298 #endif /* __PERF_SYMBOL */
298 299