diff options
-rw-r--r-- | tools/perf/builtin-buildid-list.c | 36 | ||||
-rw-r--r-- | tools/perf/util/header.c | 495 |
2 files changed, 264 insertions, 267 deletions
diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c index cb690a65bf02..4895668577b5 100644 --- a/tools/perf/builtin-buildid-list.c +++ b/tools/perf/builtin-buildid-list.c | |||
@@ -39,24 +39,6 @@ static const struct option options[] = { | |||
39 | OPT_END() | 39 | OPT_END() |
40 | }; | 40 | }; |
41 | 41 | ||
42 | static int perf_session__list_build_ids(void) | ||
43 | { | ||
44 | struct perf_session *session; | ||
45 | |||
46 | session = perf_session__new(input_name, O_RDONLY, force, false, | ||
47 | &build_id__mark_dso_hit_ops); | ||
48 | if (session == NULL) | ||
49 | return -1; | ||
50 | |||
51 | if (with_hits) | ||
52 | perf_session__process_events(session, &build_id__mark_dso_hit_ops); | ||
53 | |||
54 | perf_session__fprintf_dsos_buildid(session, stdout, with_hits); | ||
55 | |||
56 | perf_session__delete(session); | ||
57 | return 0; | ||
58 | } | ||
59 | |||
60 | static int sysfs__fprintf_build_id(FILE *fp) | 42 | static int sysfs__fprintf_build_id(FILE *fp) |
61 | { | 43 | { |
62 | u8 kallsyms_build_id[BUILD_ID_SIZE]; | 44 | u8 kallsyms_build_id[BUILD_ID_SIZE]; |
@@ -85,6 +67,24 @@ static int filename__fprintf_build_id(const char *name, FILE *fp) | |||
85 | return fprintf(fp, "%s\n", sbuild_id); | 67 | return fprintf(fp, "%s\n", sbuild_id); |
86 | } | 68 | } |
87 | 69 | ||
70 | static int perf_session__list_build_ids(void) | ||
71 | { | ||
72 | struct perf_session *session; | ||
73 | |||
74 | session = perf_session__new(input_name, O_RDONLY, force, false, | ||
75 | &build_id__mark_dso_hit_ops); | ||
76 | if (session == NULL) | ||
77 | return -1; | ||
78 | |||
79 | if (with_hits) | ||
80 | perf_session__process_events(session, &build_id__mark_dso_hit_ops); | ||
81 | |||
82 | perf_session__fprintf_dsos_buildid(session, stdout, with_hits); | ||
83 | |||
84 | perf_session__delete(session); | ||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | static int __cmd_buildid_list(void) | 88 | static int __cmd_buildid_list(void) |
89 | { | 89 | { |
90 | if (show_kernel) | 90 | if (show_kernel) |
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 428a4a2ce350..609d79b5fb5e 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
@@ -28,9 +28,6 @@ static struct perf_trace_event_type *events; | |||
28 | static u32 header_argc; | 28 | static u32 header_argc; |
29 | static const char **header_argv; | 29 | static const char **header_argv; |
30 | 30 | ||
31 | static int dsos__write_buildid_table(struct perf_header *header, int fd); | ||
32 | static int perf_session__cache_build_ids(struct perf_session *session); | ||
33 | |||
34 | int perf_header__push_event(u64 id, const char *name) | 31 | int perf_header__push_event(u64 id, const char *name) |
35 | { | 32 | { |
36 | if (strlen(name) > MAX_EVENT_NAME) | 33 | if (strlen(name) > MAX_EVENT_NAME) |
@@ -187,6 +184,252 @@ perf_header__set_cmdline(int argc, const char **argv) | |||
187 | return 0; | 184 | return 0; |
188 | } | 185 | } |
189 | 186 | ||
187 | #define dsos__for_each_with_build_id(pos, head) \ | ||
188 | list_for_each_entry(pos, head, node) \ | ||
189 | if (!pos->has_build_id) \ | ||
190 | continue; \ | ||
191 | else | ||
192 | |||
193 | static int __dsos__write_buildid_table(struct list_head *head, pid_t pid, | ||
194 | u16 misc, int fd) | ||
195 | { | ||
196 | struct dso *pos; | ||
197 | |||
198 | dsos__for_each_with_build_id(pos, head) { | ||
199 | int err; | ||
200 | struct build_id_event b; | ||
201 | size_t len; | ||
202 | |||
203 | if (!pos->hit) | ||
204 | continue; | ||
205 | len = pos->long_name_len + 1; | ||
206 | len = ALIGN(len, NAME_ALIGN); | ||
207 | memset(&b, 0, sizeof(b)); | ||
208 | memcpy(&b.build_id, pos->build_id, sizeof(pos->build_id)); | ||
209 | b.pid = pid; | ||
210 | b.header.misc = misc; | ||
211 | b.header.size = sizeof(b) + len; | ||
212 | err = do_write(fd, &b, sizeof(b)); | ||
213 | if (err < 0) | ||
214 | return err; | ||
215 | err = write_padded(fd, pos->long_name, | ||
216 | pos->long_name_len + 1, len); | ||
217 | if (err < 0) | ||
218 | return err; | ||
219 | } | ||
220 | |||
221 | return 0; | ||
222 | } | ||
223 | |||
224 | static int machine__write_buildid_table(struct machine *machine, int fd) | ||
225 | { | ||
226 | int err; | ||
227 | u16 kmisc = PERF_RECORD_MISC_KERNEL, | ||
228 | umisc = PERF_RECORD_MISC_USER; | ||
229 | |||
230 | if (!machine__is_host(machine)) { | ||
231 | kmisc = PERF_RECORD_MISC_GUEST_KERNEL; | ||
232 | umisc = PERF_RECORD_MISC_GUEST_USER; | ||
233 | } | ||
234 | |||
235 | err = __dsos__write_buildid_table(&machine->kernel_dsos, machine->pid, | ||
236 | kmisc, fd); | ||
237 | if (err == 0) | ||
238 | err = __dsos__write_buildid_table(&machine->user_dsos, | ||
239 | machine->pid, umisc, fd); | ||
240 | return err; | ||
241 | } | ||
242 | |||
243 | static int dsos__write_buildid_table(struct perf_header *header, int fd) | ||
244 | { | ||
245 | struct perf_session *session = container_of(header, | ||
246 | struct perf_session, header); | ||
247 | struct rb_node *nd; | ||
248 | int err = machine__write_buildid_table(&session->host_machine, fd); | ||
249 | |||
250 | if (err) | ||
251 | return err; | ||
252 | |||
253 | for (nd = rb_first(&session->machines); nd; nd = rb_next(nd)) { | ||
254 | struct machine *pos = rb_entry(nd, struct machine, rb_node); | ||
255 | err = machine__write_buildid_table(pos, fd); | ||
256 | if (err) | ||
257 | break; | ||
258 | } | ||
259 | return err; | ||
260 | } | ||
261 | |||
262 | int build_id_cache__add_s(const char *sbuild_id, const char *debugdir, | ||
263 | const char *name, bool is_kallsyms) | ||
264 | { | ||
265 | const size_t size = PATH_MAX; | ||
266 | char *realname, *filename = zalloc(size), | ||
267 | *linkname = zalloc(size), *targetname; | ||
268 | int len, err = -1; | ||
269 | |||
270 | if (is_kallsyms) { | ||
271 | if (symbol_conf.kptr_restrict) { | ||
272 | pr_debug("Not caching a kptr_restrict'ed /proc/kallsyms\n"); | ||
273 | return 0; | ||
274 | } | ||
275 | realname = (char *)name; | ||
276 | } else | ||
277 | realname = realpath(name, NULL); | ||
278 | |||
279 | if (realname == NULL || filename == NULL || linkname == NULL) | ||
280 | goto out_free; | ||
281 | |||
282 | len = snprintf(filename, size, "%s%s%s", | ||
283 | debugdir, is_kallsyms ? "/" : "", realname); | ||
284 | if (mkdir_p(filename, 0755)) | ||
285 | goto out_free; | ||
286 | |||
287 | snprintf(filename + len, sizeof(filename) - len, "/%s", sbuild_id); | ||
288 | |||
289 | if (access(filename, F_OK)) { | ||
290 | if (is_kallsyms) { | ||
291 | if (copyfile("/proc/kallsyms", filename)) | ||
292 | goto out_free; | ||
293 | } else if (link(realname, filename) && copyfile(name, filename)) | ||
294 | goto out_free; | ||
295 | } | ||
296 | |||
297 | len = snprintf(linkname, size, "%s/.build-id/%.2s", | ||
298 | debugdir, sbuild_id); | ||
299 | |||
300 | if (access(linkname, X_OK) && mkdir_p(linkname, 0755)) | ||
301 | goto out_free; | ||
302 | |||
303 | snprintf(linkname + len, size - len, "/%s", sbuild_id + 2); | ||
304 | targetname = filename + strlen(debugdir) - 5; | ||
305 | memcpy(targetname, "../..", 5); | ||
306 | |||
307 | if (symlink(targetname, linkname) == 0) | ||
308 | err = 0; | ||
309 | out_free: | ||
310 | if (!is_kallsyms) | ||
311 | free(realname); | ||
312 | free(filename); | ||
313 | free(linkname); | ||
314 | return err; | ||
315 | } | ||
316 | |||
317 | static int build_id_cache__add_b(const u8 *build_id, size_t build_id_size, | ||
318 | const char *name, const char *debugdir, | ||
319 | bool is_kallsyms) | ||
320 | { | ||
321 | char sbuild_id[BUILD_ID_SIZE * 2 + 1]; | ||
322 | |||
323 | build_id__sprintf(build_id, build_id_size, sbuild_id); | ||
324 | |||
325 | return build_id_cache__add_s(sbuild_id, debugdir, name, is_kallsyms); | ||
326 | } | ||
327 | |||
328 | int build_id_cache__remove_s(const char *sbuild_id, const char *debugdir) | ||
329 | { | ||
330 | const size_t size = PATH_MAX; | ||
331 | char *filename = zalloc(size), | ||
332 | *linkname = zalloc(size); | ||
333 | int err = -1; | ||
334 | |||
335 | if (filename == NULL || linkname == NULL) | ||
336 | goto out_free; | ||
337 | |||
338 | snprintf(linkname, size, "%s/.build-id/%.2s/%s", | ||
339 | debugdir, sbuild_id, sbuild_id + 2); | ||
340 | |||
341 | if (access(linkname, F_OK)) | ||
342 | goto out_free; | ||
343 | |||
344 | if (readlink(linkname, filename, size - 1) < 0) | ||
345 | goto out_free; | ||
346 | |||
347 | if (unlink(linkname)) | ||
348 | goto out_free; | ||
349 | |||
350 | /* | ||
351 | * Since the link is relative, we must make it absolute: | ||
352 | */ | ||
353 | snprintf(linkname, size, "%s/.build-id/%.2s/%s", | ||
354 | debugdir, sbuild_id, filename); | ||
355 | |||
356 | if (unlink(linkname)) | ||
357 | goto out_free; | ||
358 | |||
359 | err = 0; | ||
360 | out_free: | ||
361 | free(filename); | ||
362 | free(linkname); | ||
363 | return err; | ||
364 | } | ||
365 | |||
366 | static int dso__cache_build_id(struct dso *dso, const char *debugdir) | ||
367 | { | ||
368 | bool is_kallsyms = dso->kernel && dso->long_name[0] != '/'; | ||
369 | |||
370 | return build_id_cache__add_b(dso->build_id, sizeof(dso->build_id), | ||
371 | dso->long_name, debugdir, is_kallsyms); | ||
372 | } | ||
373 | |||
374 | static int __dsos__cache_build_ids(struct list_head *head, const char *debugdir) | ||
375 | { | ||
376 | struct dso *pos; | ||
377 | int err = 0; | ||
378 | |||
379 | dsos__for_each_with_build_id(pos, head) | ||
380 | if (dso__cache_build_id(pos, debugdir)) | ||
381 | err = -1; | ||
382 | |||
383 | return err; | ||
384 | } | ||
385 | |||
386 | static int machine__cache_build_ids(struct machine *machine, const char *debugdir) | ||
387 | { | ||
388 | int ret = __dsos__cache_build_ids(&machine->kernel_dsos, debugdir); | ||
389 | ret |= __dsos__cache_build_ids(&machine->user_dsos, debugdir); | ||
390 | return ret; | ||
391 | } | ||
392 | |||
393 | static int perf_session__cache_build_ids(struct perf_session *session) | ||
394 | { | ||
395 | struct rb_node *nd; | ||
396 | int ret; | ||
397 | char debugdir[PATH_MAX]; | ||
398 | |||
399 | snprintf(debugdir, sizeof(debugdir), "%s", buildid_dir); | ||
400 | |||
401 | if (mkdir(debugdir, 0755) != 0 && errno != EEXIST) | ||
402 | return -1; | ||
403 | |||
404 | ret = machine__cache_build_ids(&session->host_machine, debugdir); | ||
405 | |||
406 | for (nd = rb_first(&session->machines); nd; nd = rb_next(nd)) { | ||
407 | struct machine *pos = rb_entry(nd, struct machine, rb_node); | ||
408 | ret |= machine__cache_build_ids(pos, debugdir); | ||
409 | } | ||
410 | return ret ? -1 : 0; | ||
411 | } | ||
412 | |||
413 | static bool machine__read_build_ids(struct machine *machine, bool with_hits) | ||
414 | { | ||
415 | bool ret = __dsos__read_build_ids(&machine->kernel_dsos, with_hits); | ||
416 | ret |= __dsos__read_build_ids(&machine->user_dsos, with_hits); | ||
417 | return ret; | ||
418 | } | ||
419 | |||
420 | static bool perf_session__read_build_ids(struct perf_session *session, bool with_hits) | ||
421 | { | ||
422 | struct rb_node *nd; | ||
423 | bool ret = machine__read_build_ids(&session->host_machine, with_hits); | ||
424 | |||
425 | for (nd = rb_first(&session->machines); nd; nd = rb_next(nd)) { | ||
426 | struct machine *pos = rb_entry(nd, struct machine, rb_node); | ||
427 | ret |= machine__read_build_ids(pos, with_hits); | ||
428 | } | ||
429 | |||
430 | return ret; | ||
431 | } | ||
432 | |||
190 | static int write_trace_info(int fd, struct perf_header *h __used, | 433 | static int write_trace_info(int fd, struct perf_header *h __used, |
191 | struct perf_evlist *evlist) | 434 | struct perf_evlist *evlist) |
192 | { | 435 | { |
@@ -1136,252 +1379,6 @@ int perf_header__fprintf_info(struct perf_session *session, FILE *fp, bool full) | |||
1136 | return 0; | 1379 | return 0; |
1137 | } | 1380 | } |
1138 | 1381 | ||
1139 | #define dsos__for_each_with_build_id(pos, head) \ | ||
1140 | list_for_each_entry(pos, head, node) \ | ||
1141 | if (!pos->has_build_id) \ | ||
1142 | continue; \ | ||
1143 | else | ||
1144 | |||
1145 | static int __dsos__write_buildid_table(struct list_head *head, pid_t pid, | ||
1146 | u16 misc, int fd) | ||
1147 | { | ||
1148 | struct dso *pos; | ||
1149 | |||
1150 | dsos__for_each_with_build_id(pos, head) { | ||
1151 | int err; | ||
1152 | struct build_id_event b; | ||
1153 | size_t len; | ||
1154 | |||
1155 | if (!pos->hit) | ||
1156 | continue; | ||
1157 | len = pos->long_name_len + 1; | ||
1158 | len = ALIGN(len, NAME_ALIGN); | ||
1159 | memset(&b, 0, sizeof(b)); | ||
1160 | memcpy(&b.build_id, pos->build_id, sizeof(pos->build_id)); | ||
1161 | b.pid = pid; | ||
1162 | b.header.misc = misc; | ||
1163 | b.header.size = sizeof(b) + len; | ||
1164 | err = do_write(fd, &b, sizeof(b)); | ||
1165 | if (err < 0) | ||
1166 | return err; | ||
1167 | err = write_padded(fd, pos->long_name, | ||
1168 | pos->long_name_len + 1, len); | ||
1169 | if (err < 0) | ||
1170 | return err; | ||
1171 | } | ||
1172 | |||
1173 | return 0; | ||
1174 | } | ||
1175 | |||
1176 | static int machine__write_buildid_table(struct machine *machine, int fd) | ||
1177 | { | ||
1178 | int err; | ||
1179 | u16 kmisc = PERF_RECORD_MISC_KERNEL, | ||
1180 | umisc = PERF_RECORD_MISC_USER; | ||
1181 | |||
1182 | if (!machine__is_host(machine)) { | ||
1183 | kmisc = PERF_RECORD_MISC_GUEST_KERNEL; | ||
1184 | umisc = PERF_RECORD_MISC_GUEST_USER; | ||
1185 | } | ||
1186 | |||
1187 | err = __dsos__write_buildid_table(&machine->kernel_dsos, machine->pid, | ||
1188 | kmisc, fd); | ||
1189 | if (err == 0) | ||
1190 | err = __dsos__write_buildid_table(&machine->user_dsos, | ||
1191 | machine->pid, umisc, fd); | ||
1192 | return err; | ||
1193 | } | ||
1194 | |||
1195 | static int dsos__write_buildid_table(struct perf_header *header, int fd) | ||
1196 | { | ||
1197 | struct perf_session *session = container_of(header, | ||
1198 | struct perf_session, header); | ||
1199 | struct rb_node *nd; | ||
1200 | int err = machine__write_buildid_table(&session->host_machine, fd); | ||
1201 | |||
1202 | if (err) | ||
1203 | return err; | ||
1204 | |||
1205 | for (nd = rb_first(&session->machines); nd; nd = rb_next(nd)) { | ||
1206 | struct machine *pos = rb_entry(nd, struct machine, rb_node); | ||
1207 | err = machine__write_buildid_table(pos, fd); | ||
1208 | if (err) | ||
1209 | break; | ||
1210 | } | ||
1211 | return err; | ||
1212 | } | ||
1213 | |||
1214 | int build_id_cache__add_s(const char *sbuild_id, const char *debugdir, | ||
1215 | const char *name, bool is_kallsyms) | ||
1216 | { | ||
1217 | const size_t size = PATH_MAX; | ||
1218 | char *realname, *filename = zalloc(size), | ||
1219 | *linkname = zalloc(size), *targetname; | ||
1220 | int len, err = -1; | ||
1221 | |||
1222 | if (is_kallsyms) { | ||
1223 | if (symbol_conf.kptr_restrict) { | ||
1224 | pr_debug("Not caching a kptr_restrict'ed /proc/kallsyms\n"); | ||
1225 | return 0; | ||
1226 | } | ||
1227 | realname = (char *)name; | ||
1228 | } else | ||
1229 | realname = realpath(name, NULL); | ||
1230 | |||
1231 | if (realname == NULL || filename == NULL || linkname == NULL) | ||
1232 | goto out_free; | ||
1233 | |||
1234 | len = snprintf(filename, size, "%s%s%s", | ||
1235 | debugdir, is_kallsyms ? "/" : "", realname); | ||
1236 | if (mkdir_p(filename, 0755)) | ||
1237 | goto out_free; | ||
1238 | |||
1239 | snprintf(filename + len, sizeof(filename) - len, "/%s", sbuild_id); | ||
1240 | |||
1241 | if (access(filename, F_OK)) { | ||
1242 | if (is_kallsyms) { | ||
1243 | if (copyfile("/proc/kallsyms", filename)) | ||
1244 | goto out_free; | ||
1245 | } else if (link(realname, filename) && copyfile(name, filename)) | ||
1246 | goto out_free; | ||
1247 | } | ||
1248 | |||
1249 | len = snprintf(linkname, size, "%s/.build-id/%.2s", | ||
1250 | debugdir, sbuild_id); | ||
1251 | |||
1252 | if (access(linkname, X_OK) && mkdir_p(linkname, 0755)) | ||
1253 | goto out_free; | ||
1254 | |||
1255 | snprintf(linkname + len, size - len, "/%s", sbuild_id + 2); | ||
1256 | targetname = filename + strlen(debugdir) - 5; | ||
1257 | memcpy(targetname, "../..", 5); | ||
1258 | |||
1259 | if (symlink(targetname, linkname) == 0) | ||
1260 | err = 0; | ||
1261 | out_free: | ||
1262 | if (!is_kallsyms) | ||
1263 | free(realname); | ||
1264 | free(filename); | ||
1265 | free(linkname); | ||
1266 | return err; | ||
1267 | } | ||
1268 | |||
1269 | static int build_id_cache__add_b(const u8 *build_id, size_t build_id_size, | ||
1270 | const char *name, const char *debugdir, | ||
1271 | bool is_kallsyms) | ||
1272 | { | ||
1273 | char sbuild_id[BUILD_ID_SIZE * 2 + 1]; | ||
1274 | |||
1275 | build_id__sprintf(build_id, build_id_size, sbuild_id); | ||
1276 | |||
1277 | return build_id_cache__add_s(sbuild_id, debugdir, name, is_kallsyms); | ||
1278 | } | ||
1279 | |||
1280 | int build_id_cache__remove_s(const char *sbuild_id, const char *debugdir) | ||
1281 | { | ||
1282 | const size_t size = PATH_MAX; | ||
1283 | char *filename = zalloc(size), | ||
1284 | *linkname = zalloc(size); | ||
1285 | int err = -1; | ||
1286 | |||
1287 | if (filename == NULL || linkname == NULL) | ||
1288 | goto out_free; | ||
1289 | |||
1290 | snprintf(linkname, size, "%s/.build-id/%.2s/%s", | ||
1291 | debugdir, sbuild_id, sbuild_id + 2); | ||
1292 | |||
1293 | if (access(linkname, F_OK)) | ||
1294 | goto out_free; | ||
1295 | |||
1296 | if (readlink(linkname, filename, size - 1) < 0) | ||
1297 | goto out_free; | ||
1298 | |||
1299 | if (unlink(linkname)) | ||
1300 | goto out_free; | ||
1301 | |||
1302 | /* | ||
1303 | * Since the link is relative, we must make it absolute: | ||
1304 | */ | ||
1305 | snprintf(linkname, size, "%s/.build-id/%.2s/%s", | ||
1306 | debugdir, sbuild_id, filename); | ||
1307 | |||
1308 | if (unlink(linkname)) | ||
1309 | goto out_free; | ||
1310 | |||
1311 | err = 0; | ||
1312 | out_free: | ||
1313 | free(filename); | ||
1314 | free(linkname); | ||
1315 | return err; | ||
1316 | } | ||
1317 | |||
1318 | static int dso__cache_build_id(struct dso *dso, const char *debugdir) | ||
1319 | { | ||
1320 | bool is_kallsyms = dso->kernel && dso->long_name[0] != '/'; | ||
1321 | |||
1322 | return build_id_cache__add_b(dso->build_id, sizeof(dso->build_id), | ||
1323 | dso->long_name, debugdir, is_kallsyms); | ||
1324 | } | ||
1325 | |||
1326 | static int __dsos__cache_build_ids(struct list_head *head, const char *debugdir) | ||
1327 | { | ||
1328 | struct dso *pos; | ||
1329 | int err = 0; | ||
1330 | |||
1331 | dsos__for_each_with_build_id(pos, head) | ||
1332 | if (dso__cache_build_id(pos, debugdir)) | ||
1333 | err = -1; | ||
1334 | |||
1335 | return err; | ||
1336 | } | ||
1337 | |||
1338 | static int machine__cache_build_ids(struct machine *machine, const char *debugdir) | ||
1339 | { | ||
1340 | int ret = __dsos__cache_build_ids(&machine->kernel_dsos, debugdir); | ||
1341 | ret |= __dsos__cache_build_ids(&machine->user_dsos, debugdir); | ||
1342 | return ret; | ||
1343 | } | ||
1344 | |||
1345 | static int perf_session__cache_build_ids(struct perf_session *session) | ||
1346 | { | ||
1347 | struct rb_node *nd; | ||
1348 | int ret; | ||
1349 | char debugdir[PATH_MAX]; | ||
1350 | |||
1351 | snprintf(debugdir, sizeof(debugdir), "%s", buildid_dir); | ||
1352 | |||
1353 | if (mkdir(debugdir, 0755) != 0 && errno != EEXIST) | ||
1354 | return -1; | ||
1355 | |||
1356 | ret = machine__cache_build_ids(&session->host_machine, debugdir); | ||
1357 | |||
1358 | for (nd = rb_first(&session->machines); nd; nd = rb_next(nd)) { | ||
1359 | struct machine *pos = rb_entry(nd, struct machine, rb_node); | ||
1360 | ret |= machine__cache_build_ids(pos, debugdir); | ||
1361 | } | ||
1362 | return ret ? -1 : 0; | ||
1363 | } | ||
1364 | |||
1365 | static bool machine__read_build_ids(struct machine *machine, bool with_hits) | ||
1366 | { | ||
1367 | bool ret = __dsos__read_build_ids(&machine->kernel_dsos, with_hits); | ||
1368 | ret |= __dsos__read_build_ids(&machine->user_dsos, with_hits); | ||
1369 | return ret; | ||
1370 | } | ||
1371 | |||
1372 | static bool perf_session__read_build_ids(struct perf_session *session, bool with_hits) | ||
1373 | { | ||
1374 | struct rb_node *nd; | ||
1375 | bool ret = machine__read_build_ids(&session->host_machine, with_hits); | ||
1376 | |||
1377 | for (nd = rb_first(&session->machines); nd; nd = rb_next(nd)) { | ||
1378 | struct machine *pos = rb_entry(nd, struct machine, rb_node); | ||
1379 | ret |= machine__read_build_ids(pos, with_hits); | ||
1380 | } | ||
1381 | |||
1382 | return ret; | ||
1383 | } | ||
1384 | |||
1385 | static int do_write_feat(int fd, struct perf_header *h, int type, | 1382 | static int do_write_feat(int fd, struct perf_header *h, int type, |
1386 | struct perf_file_section **p, | 1383 | struct perf_file_section **p, |
1387 | struct perf_evlist *evlist) | 1384 | struct perf_evlist *evlist) |