aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/build-id.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/build-id.c')
-rw-r--r--tools/perf/util/build-id.c93
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
284static 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
306int 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
336out:
337 free(dir_name);
338 if (ret)
339 strlist__delete(list);
340 else
341 *result = list;
342
343 return ret;
344}
345
284int build_id_cache__add_s(const char *sbuild_id, const char *name, 346int 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}