diff options
Diffstat (limited to 'tools/perf/util/header.c')
-rw-r--r-- | tools/perf/util/header.c | 72 |
1 files changed, 63 insertions, 9 deletions
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 1b65fed0dd2d..2bb2bdb1f456 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
@@ -231,32 +231,29 @@ static int dsos__write_buildid_table(int fd) | |||
231 | return err; | 231 | return err; |
232 | } | 232 | } |
233 | 233 | ||
234 | static int dso__cache_build_id(struct dso *self, const char *debugdir) | 234 | int build_id_cache__add_s(const char *sbuild_id, const char *debugdir, |
235 | const char *name, bool is_kallsyms) | ||
235 | { | 236 | { |
236 | const size_t size = PATH_MAX; | 237 | const size_t size = PATH_MAX; |
237 | char *filename = malloc(size), | 238 | char *filename = malloc(size), |
238 | *linkname = malloc(size), *targetname, *sbuild_id; | 239 | *linkname = malloc(size), *targetname; |
239 | int len, err = -1; | 240 | int len, err = -1; |
240 | bool is_kallsyms = self->kernel && self->long_name[0] != '/'; | ||
241 | 241 | ||
242 | if (filename == NULL || linkname == NULL) | 242 | if (filename == NULL || linkname == NULL) |
243 | goto out_free; | 243 | goto out_free; |
244 | 244 | ||
245 | len = snprintf(filename, size, "%s%s%s", | 245 | len = snprintf(filename, size, "%s%s%s", |
246 | debugdir, is_kallsyms ? "/" : "", self->long_name); | 246 | debugdir, is_kallsyms ? "/" : "", name); |
247 | if (mkdir_p(filename, 0755)) | 247 | if (mkdir_p(filename, 0755)) |
248 | goto out_free; | 248 | goto out_free; |
249 | 249 | ||
250 | len += snprintf(filename + len, sizeof(filename) - len, "/"); | 250 | snprintf(filename + len, sizeof(filename) - len, "/%s", sbuild_id); |
251 | sbuild_id = filename + len; | ||
252 | build_id__sprintf(self->build_id, sizeof(self->build_id), sbuild_id); | ||
253 | 251 | ||
254 | if (access(filename, F_OK)) { | 252 | if (access(filename, F_OK)) { |
255 | if (is_kallsyms) { | 253 | if (is_kallsyms) { |
256 | if (copyfile("/proc/kallsyms", filename)) | 254 | if (copyfile("/proc/kallsyms", filename)) |
257 | goto out_free; | 255 | goto out_free; |
258 | } else if (link(self->long_name, filename) && | 256 | } else if (link(name, filename) && copyfile(name, filename)) |
259 | copyfile(self->long_name, filename)) | ||
260 | goto out_free; | 257 | goto out_free; |
261 | } | 258 | } |
262 | 259 | ||
@@ -278,6 +275,63 @@ out_free: | |||
278 | return err; | 275 | return err; |
279 | } | 276 | } |
280 | 277 | ||
278 | static int build_id_cache__add_b(const u8 *build_id, size_t build_id_size, | ||
279 | const char *name, const char *debugdir, | ||
280 | bool is_kallsyms) | ||
281 | { | ||
282 | char sbuild_id[BUILD_ID_SIZE * 2 + 1]; | ||
283 | |||
284 | build_id__sprintf(build_id, build_id_size, sbuild_id); | ||
285 | |||
286 | return build_id_cache__add_s(sbuild_id, debugdir, name, is_kallsyms); | ||
287 | } | ||
288 | |||
289 | int build_id_cache__remove_s(const char *sbuild_id, const char *debugdir) | ||
290 | { | ||
291 | const size_t size = PATH_MAX; | ||
292 | char *filename = malloc(size), | ||
293 | *linkname = malloc(size); | ||
294 | int err = -1; | ||
295 | |||
296 | if (filename == NULL || linkname == NULL) | ||
297 | goto out_free; | ||
298 | |||
299 | snprintf(linkname, size, "%s/.build-id/%.2s/%s", | ||
300 | debugdir, sbuild_id, sbuild_id + 2); | ||
301 | |||
302 | if (access(linkname, F_OK)) | ||
303 | goto out_free; | ||
304 | |||
305 | if (readlink(linkname, filename, size) < 0) | ||
306 | goto out_free; | ||
307 | |||
308 | if (unlink(linkname)) | ||
309 | goto out_free; | ||
310 | |||
311 | /* | ||
312 | * Since the link is relative, we must make it absolute: | ||
313 | */ | ||
314 | snprintf(linkname, size, "%s/.build-id/%.2s/%s", | ||
315 | debugdir, sbuild_id, filename); | ||
316 | |||
317 | if (unlink(linkname)) | ||
318 | goto out_free; | ||
319 | |||
320 | err = 0; | ||
321 | out_free: | ||
322 | free(filename); | ||
323 | free(linkname); | ||
324 | return err; | ||
325 | } | ||
326 | |||
327 | static int dso__cache_build_id(struct dso *self, const char *debugdir) | ||
328 | { | ||
329 | bool is_kallsyms = self->kernel && self->long_name[0] != '/'; | ||
330 | |||
331 | return build_id_cache__add_b(self->build_id, sizeof(self->build_id), | ||
332 | self->long_name, debugdir, is_kallsyms); | ||
333 | } | ||
334 | |||
281 | static int __dsos__cache_build_ids(struct list_head *head, const char *debugdir) | 335 | static int __dsos__cache_build_ids(struct list_head *head, const char *debugdir) |
282 | { | 336 | { |
283 | struct dso *pos; | 337 | struct dso *pos; |