aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2010-01-20 12:28:45 -0500
committerIngo Molnar <mingo@elte.hu>2010-01-21 02:31:29 -0500
commitef12a141306c90336a3a10d40213ecd98624d274 (patch)
tree6c6d06c1c7bb5b769cc46c8da05f561aa2443b91 /tools/perf/util
parentdc8d6ab2b61a2d92b5d7438565ccd20b29724cb2 (diff)
perf buildid-cache: Add new command to manage build-id cache
For now it just has operations to examine a given file, find its build-id and add or remove it to/from the cache. Useful, for instance, when adding binaries sent together with a perf.data file, so that we can add them to the cache and have the tools find it when resolving symbols. It'll also manage the size of the cache like 'ccache' does. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Frédéric Weisbecker <fweisbec@gmail.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Paul Mackerras <paulus@samba.org> LKML-Reference: <1264008525-29025-1-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/util')
-rw-r--r--tools/perf/util/header.c72
-rw-r--r--tools/perf/util/header.h5
-rw-r--r--tools/perf/util/symbol.c4
-rw-r--r--tools/perf/util/symbol.h2
4 files changed, 71 insertions, 12 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
234static int dso__cache_build_id(struct dso *self, const char *debugdir) 234int 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
278static 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
289int 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;
321out_free:
322 free(filename);
323 free(linkname);
324 return err;
325}
326
327static 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
281static int __dsos__cache_build_ids(struct list_head *head, const char *debugdir) 335static int __dsos__cache_build_ids(struct list_head *head, const char *debugdir)
282{ 336{
283 struct dso *pos; 337 struct dso *pos;
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index ccc8540feccd..82a6af72d4cc 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -5,6 +5,7 @@
5#include <sys/types.h> 5#include <sys/types.h>
6#include <stdbool.h> 6#include <stdbool.h>
7#include "types.h" 7#include "types.h"
8#include "event.h"
8 9
9#include <linux/bitmap.h> 10#include <linux/bitmap.h>
10 11
@@ -84,4 +85,8 @@ int perf_header__process_sections(struct perf_header *self, int fd,
84 struct perf_header *ph, 85 struct perf_header *ph,
85 int feat, int fd)); 86 int feat, int fd));
86 87
88int build_id_cache__add_s(const char *sbuild_id, const char *debugdir,
89 const char *name, bool is_kallsyms);
90int build_id_cache__remove_s(const char *sbuild_id, const char *debugdir);
91
87#endif /* __PERF_HEADER_H */ 92#endif /* __PERF_HEADER_H */
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index b6ab23dd5f9f..6f30fe18c265 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -345,10 +345,10 @@ void dso__sort_by_name(struct dso *self, enum map_type type)
345 &self->symbols[type]); 345 &self->symbols[type]);
346} 346}
347 347
348int build_id__sprintf(u8 *self, int len, char *bf) 348int build_id__sprintf(const u8 *self, int len, char *bf)
349{ 349{
350 char *bid = bf; 350 char *bid = bf;
351 u8 *raw = self; 351 const u8 *raw = self;
352 int i; 352 int i;
353 353
354 for (i = 0; i < len; ++i) { 354 for (i = 0; i < len; ++i) {
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 525085fd0735..ffe0b0f2e5d3 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -144,7 +144,7 @@ struct symbol *dso__find_symbol_by_name(struct dso *self, enum map_type type,
144int filename__read_build_id(const char *filename, void *bf, size_t size); 144int filename__read_build_id(const char *filename, void *bf, size_t size);
145int sysfs__read_build_id(const char *filename, void *bf, size_t size); 145int sysfs__read_build_id(const char *filename, void *bf, size_t size);
146bool dsos__read_build_ids(void); 146bool dsos__read_build_ids(void);
147int build_id__sprintf(u8 *self, int len, char *bf); 147int build_id__sprintf(const u8 *self, int len, char *bf);
148int kallsyms__parse(const char *filename, void *arg, 148int kallsyms__parse(const char *filename, void *arg,
149 int (*process_symbol)(void *arg, const char *name, 149 int (*process_symbol)(void *arg, const char *name,
150 char type, u64 start)); 150 char type, u64 start));