diff options
-rw-r--r-- | tools/perf/util/build-id.c | 58 |
1 files changed, 41 insertions, 17 deletions
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index 9f764f633e57..adbc36028636 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c | |||
@@ -93,6 +93,35 @@ int build_id__sprintf(const u8 *build_id, int len, char *bf) | |||
93 | return raw - build_id; | 93 | return raw - build_id; |
94 | } | 94 | } |
95 | 95 | ||
96 | /* asnprintf consolidates asprintf and snprintf */ | ||
97 | static int asnprintf(char **strp, size_t size, const char *fmt, ...) | ||
98 | { | ||
99 | va_list ap; | ||
100 | int ret; | ||
101 | |||
102 | if (!strp) | ||
103 | return -EINVAL; | ||
104 | |||
105 | va_start(ap, fmt); | ||
106 | if (*strp) | ||
107 | ret = vsnprintf(*strp, size, fmt, ap); | ||
108 | else | ||
109 | ret = vasprintf(strp, fmt, ap); | ||
110 | va_end(ap); | ||
111 | |||
112 | return ret; | ||
113 | } | ||
114 | |||
115 | static char *build_id__filename(const char *sbuild_id, char *bf, size_t size) | ||
116 | { | ||
117 | char *tmp = bf; | ||
118 | int ret = asnprintf(&bf, size, "%s/.build-id/%.2s/%s", buildid_dir, | ||
119 | sbuild_id, sbuild_id + 2); | ||
120 | if (ret < 0 || (tmp && size < (unsigned int)ret)) | ||
121 | return NULL; | ||
122 | return bf; | ||
123 | } | ||
124 | |||
96 | char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size) | 125 | char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size) |
97 | { | 126 | { |
98 | char build_id_hex[BUILD_ID_SIZE * 2 + 1]; | 127 | char build_id_hex[BUILD_ID_SIZE * 2 + 1]; |
@@ -101,14 +130,7 @@ char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size) | |||
101 | return NULL; | 130 | return NULL; |
102 | 131 | ||
103 | build_id__sprintf(dso->build_id, sizeof(dso->build_id), build_id_hex); | 132 | build_id__sprintf(dso->build_id, sizeof(dso->build_id), build_id_hex); |
104 | if (bf == NULL) { | 133 | return build_id__filename(build_id_hex, bf, size); |
105 | if (asprintf(&bf, "%s/.build-id/%.2s/%s", buildid_dir, | ||
106 | build_id_hex, build_id_hex + 2) < 0) | ||
107 | return NULL; | ||
108 | } else | ||
109 | snprintf(bf, size, "%s/.build-id/%.2s/%s", buildid_dir, | ||
110 | build_id_hex, build_id_hex + 2); | ||
111 | return bf; | ||
112 | } | 134 | } |
113 | 135 | ||
114 | #define dsos__for_each_with_build_id(pos, head) \ | 136 | #define dsos__for_each_with_build_id(pos, head) \ |
@@ -264,7 +286,7 @@ int build_id_cache__add_s(const char *sbuild_id, const char *name, | |||
264 | { | 286 | { |
265 | const size_t size = PATH_MAX; | 287 | const size_t size = PATH_MAX; |
266 | char *realname, *filename = zalloc(size), | 288 | char *realname, *filename = zalloc(size), |
267 | *linkname = zalloc(size), *targetname; | 289 | *linkname = zalloc(size), *targetname, *tmp; |
268 | int len, err = -1; | 290 | int len, err = -1; |
269 | bool slash = is_kallsyms || is_vdso; | 291 | bool slash = is_kallsyms || is_vdso; |
270 | 292 | ||
@@ -297,13 +319,15 @@ int build_id_cache__add_s(const char *sbuild_id, const char *name, | |||
297 | goto out_free; | 319 | goto out_free; |
298 | } | 320 | } |
299 | 321 | ||
300 | len = scnprintf(linkname, size, "%s/.build-id/%.2s", | 322 | if (!build_id__filename(sbuild_id, linkname, size)) |
301 | buildid_dir, sbuild_id); | 323 | goto out_free; |
324 | tmp = strrchr(linkname, '/'); | ||
325 | *tmp = '\0'; | ||
302 | 326 | ||
303 | if (access(linkname, X_OK) && mkdir_p(linkname, 0755)) | 327 | if (access(linkname, X_OK) && mkdir_p(linkname, 0755)) |
304 | goto out_free; | 328 | goto out_free; |
305 | 329 | ||
306 | snprintf(linkname + len, size - len, "/%s", sbuild_id + 2); | 330 | *tmp = '/'; |
307 | targetname = filename + strlen(buildid_dir) - 5; | 331 | targetname = filename + strlen(buildid_dir) - 5; |
308 | memcpy(targetname, "../..", 5); | 332 | memcpy(targetname, "../..", 5); |
309 | 333 | ||
@@ -332,14 +356,14 @@ int build_id_cache__remove_s(const char *sbuild_id) | |||
332 | { | 356 | { |
333 | const size_t size = PATH_MAX; | 357 | const size_t size = PATH_MAX; |
334 | char *filename = zalloc(size), | 358 | char *filename = zalloc(size), |
335 | *linkname = zalloc(size); | 359 | *linkname = zalloc(size), *tmp; |
336 | int err = -1; | 360 | int err = -1; |
337 | 361 | ||
338 | if (filename == NULL || linkname == NULL) | 362 | if (filename == NULL || linkname == NULL) |
339 | goto out_free; | 363 | goto out_free; |
340 | 364 | ||
341 | snprintf(linkname, size, "%s/.build-id/%.2s/%s", | 365 | if (!build_id__filename(sbuild_id, linkname, size)) |
342 | buildid_dir, sbuild_id, sbuild_id + 2); | 366 | goto out_free; |
343 | 367 | ||
344 | if (access(linkname, F_OK)) | 368 | if (access(linkname, F_OK)) |
345 | goto out_free; | 369 | goto out_free; |
@@ -353,8 +377,8 @@ int build_id_cache__remove_s(const char *sbuild_id) | |||
353 | /* | 377 | /* |
354 | * Since the link is relative, we must make it absolute: | 378 | * Since the link is relative, we must make it absolute: |
355 | */ | 379 | */ |
356 | snprintf(linkname, size, "%s/.build-id/%.2s/%s", | 380 | tmp = strrchr(linkname, '/') + 1; |
357 | buildid_dir, sbuild_id, filename); | 381 | snprintf(tmp, size - (tmp - linkname), "%s", filename); |
358 | 382 | ||
359 | if (unlink(linkname)) | 383 | if (unlink(linkname)) |
360 | goto out_free; | 384 | goto out_free; |