diff options
Diffstat (limited to 'tools/perf/util/build-id.c')
-rw-r--r-- | tools/perf/util/build-id.c | 93 |
1 files changed, 76 insertions, 17 deletions
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index 0bc33be5a78c..ffdc338df925 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c | |||
@@ -281,35 +281,93 @@ void disable_buildid_cache(void) | |||
281 | no_buildid_cache = true; | 281 | no_buildid_cache = true; |
282 | } | 282 | } |
283 | 283 | ||
284 | static char *build_id_cache__dirname_from_path(const char *name, | ||
285 | bool is_kallsyms, bool is_vdso) | ||
286 | { | ||
287 | char *realname = (char *)name, *filename; | ||
288 | bool slash = is_kallsyms || is_vdso; | ||
289 | |||
290 | if (!slash) { | ||
291 | realname = realpath(name, NULL); | ||
292 | if (!realname) | ||
293 | return NULL; | ||
294 | } | ||
295 | |||
296 | if (asprintf(&filename, "%s%s%s", buildid_dir, slash ? "/" : "", | ||
297 | is_vdso ? DSO__NAME_VDSO : realname) < 0) | ||
298 | filename = NULL; | ||
299 | |||
300 | if (!slash) | ||
301 | free(realname); | ||
302 | |||
303 | return filename; | ||
304 | } | ||
305 | |||
306 | int build_id_cache__list_build_ids(const char *pathname, | ||
307 | struct strlist **result) | ||
308 | { | ||
309 | struct strlist *list; | ||
310 | char *dir_name; | ||
311 | DIR *dir; | ||
312 | struct dirent *d; | ||
313 | int ret = 0; | ||
314 | |||
315 | list = strlist__new(true, NULL); | ||
316 | dir_name = build_id_cache__dirname_from_path(pathname, false, false); | ||
317 | if (!list || !dir_name) { | ||
318 | ret = -ENOMEM; | ||
319 | goto out; | ||
320 | } | ||
321 | |||
322 | /* List up all dirents */ | ||
323 | dir = opendir(dir_name); | ||
324 | if (!dir) { | ||
325 | ret = -errno; | ||
326 | goto out; | ||
327 | } | ||
328 | |||
329 | while ((d = readdir(dir)) != NULL) { | ||
330 | if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, "..")) | ||
331 | continue; | ||
332 | strlist__add(list, d->d_name); | ||
333 | } | ||
334 | closedir(dir); | ||
335 | |||
336 | out: | ||
337 | free(dir_name); | ||
338 | if (ret) | ||
339 | strlist__delete(list); | ||
340 | else | ||
341 | *result = list; | ||
342 | |||
343 | return ret; | ||
344 | } | ||
345 | |||
284 | int build_id_cache__add_s(const char *sbuild_id, const char *name, | 346 | int build_id_cache__add_s(const char *sbuild_id, const char *name, |
285 | bool is_kallsyms, bool is_vdso) | 347 | bool is_kallsyms, bool is_vdso) |
286 | { | 348 | { |
287 | const size_t size = PATH_MAX; | 349 | const size_t size = PATH_MAX; |
288 | char *realname, *filename = zalloc(size), | 350 | char *realname = NULL, *filename = NULL, *dir_name = NULL, |
289 | *linkname = zalloc(size), *targetname, *tmp; | 351 | *linkname = zalloc(size), *targetname, *tmp; |
290 | int len, err = -1; | 352 | int err = -1; |
291 | bool slash = is_kallsyms || is_vdso; | ||
292 | 353 | ||
293 | if (is_kallsyms) { | 354 | if (!is_kallsyms) { |
294 | if (symbol_conf.kptr_restrict) { | ||
295 | pr_debug("Not caching a kptr_restrict'ed /proc/kallsyms\n"); | ||
296 | err = 0; | ||
297 | goto out_free; | ||
298 | } | ||
299 | realname = (char *) name; | ||
300 | } else | ||
301 | realname = realpath(name, NULL); | 355 | realname = realpath(name, NULL); |
356 | if (!realname) | ||
357 | goto out_free; | ||
358 | } | ||
302 | 359 | ||
303 | if (realname == NULL || filename == NULL || linkname == NULL) | 360 | dir_name = build_id_cache__dirname_from_path(name, is_kallsyms, is_vdso); |
361 | if (!dir_name) | ||
304 | goto out_free; | 362 | goto out_free; |
305 | 363 | ||
306 | len = scnprintf(filename, size, "%s%s%s", | 364 | if (mkdir_p(dir_name, 0755)) |
307 | buildid_dir, slash ? "/" : "", | ||
308 | is_vdso ? DSO__NAME_VDSO : realname); | ||
309 | if (mkdir_p(filename, 0755)) | ||
310 | goto out_free; | 365 | goto out_free; |
311 | 366 | ||
312 | snprintf(filename + len, size - len, "/%s", sbuild_id); | 367 | if (asprintf(&filename, "%s/%s", dir_name, sbuild_id) < 0) { |
368 | filename = NULL; | ||
369 | goto out_free; | ||
370 | } | ||
313 | 371 | ||
314 | if (access(filename, F_OK)) { | 372 | if (access(filename, F_OK)) { |
315 | if (is_kallsyms) { | 373 | if (is_kallsyms) { |
@@ -337,6 +395,7 @@ out_free: | |||
337 | if (!is_kallsyms) | 395 | if (!is_kallsyms) |
338 | free(realname); | 396 | free(realname); |
339 | free(filename); | 397 | free(filename); |
398 | free(dir_name); | ||
340 | free(linkname); | 399 | free(linkname); |
341 | return err; | 400 | return err; |
342 | } | 401 | } |