diff options
author | Jiri Olsa <jolsa@redhat.com> | 2012-10-27 17:18:32 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2012-10-29 09:37:25 -0400 |
commit | cdd059d731eeb466f51a404ee6cbfafb0fc7c20b (patch) | |
tree | 36346ccb768ee0b8642b79bef6c7ad723a203a12 /tools/perf/util | |
parent | ea36c46be69c6e49c877971c4b3b3876b24b6082 (diff) |
perf tools: Move dso_* related functions into dso object
Moving dso_* related functions into dso object.
Keeping symbol loading related functions still in the symbol object as
it seems more convenient.
Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Tested-by: Namhyung Kim <namhyung@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1351372712-21104-6-git-send-email-jolsa@redhat.com
[ committer note: Use "symbol.h" instead of <symbol.h> to make it build with O= ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util')
-rw-r--r-- | tools/perf/util/dso.c | 594 | ||||
-rw-r--r-- | tools/perf/util/dso.h | 148 | ||||
-rw-r--r-- | tools/perf/util/symbol.c | 599 | ||||
-rw-r--r-- | tools/perf/util/symbol.h | 134 |
4 files changed, 749 insertions, 726 deletions
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c new file mode 100644 index 000000000000..db24a3f0c820 --- /dev/null +++ b/tools/perf/util/dso.c | |||
@@ -0,0 +1,594 @@ | |||
1 | #include "symbol.h" | ||
2 | #include "dso.h" | ||
3 | #include "util.h" | ||
4 | #include "debug.h" | ||
5 | |||
6 | char dso__symtab_origin(const struct dso *dso) | ||
7 | { | ||
8 | static const char origin[] = { | ||
9 | [DSO_BINARY_TYPE__KALLSYMS] = 'k', | ||
10 | [DSO_BINARY_TYPE__VMLINUX] = 'v', | ||
11 | [DSO_BINARY_TYPE__JAVA_JIT] = 'j', | ||
12 | [DSO_BINARY_TYPE__DEBUGLINK] = 'l', | ||
13 | [DSO_BINARY_TYPE__BUILD_ID_CACHE] = 'B', | ||
14 | [DSO_BINARY_TYPE__FEDORA_DEBUGINFO] = 'f', | ||
15 | [DSO_BINARY_TYPE__UBUNTU_DEBUGINFO] = 'u', | ||
16 | [DSO_BINARY_TYPE__BUILDID_DEBUGINFO] = 'b', | ||
17 | [DSO_BINARY_TYPE__SYSTEM_PATH_DSO] = 'd', | ||
18 | [DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE] = 'K', | ||
19 | [DSO_BINARY_TYPE__GUEST_KALLSYMS] = 'g', | ||
20 | [DSO_BINARY_TYPE__GUEST_KMODULE] = 'G', | ||
21 | [DSO_BINARY_TYPE__GUEST_VMLINUX] = 'V', | ||
22 | }; | ||
23 | |||
24 | if (dso == NULL || dso->symtab_type == DSO_BINARY_TYPE__NOT_FOUND) | ||
25 | return '!'; | ||
26 | return origin[dso->symtab_type]; | ||
27 | } | ||
28 | |||
29 | int dso__binary_type_file(struct dso *dso, enum dso_binary_type type, | ||
30 | char *root_dir, char *file, size_t size) | ||
31 | { | ||
32 | char build_id_hex[BUILD_ID_SIZE * 2 + 1]; | ||
33 | int ret = 0; | ||
34 | |||
35 | switch (type) { | ||
36 | case DSO_BINARY_TYPE__DEBUGLINK: { | ||
37 | char *debuglink; | ||
38 | |||
39 | strncpy(file, dso->long_name, size); | ||
40 | debuglink = file + dso->long_name_len; | ||
41 | while (debuglink != file && *debuglink != '/') | ||
42 | debuglink--; | ||
43 | if (*debuglink == '/') | ||
44 | debuglink++; | ||
45 | filename__read_debuglink(dso->long_name, debuglink, | ||
46 | size - (debuglink - file)); | ||
47 | } | ||
48 | break; | ||
49 | case DSO_BINARY_TYPE__BUILD_ID_CACHE: | ||
50 | /* skip the locally configured cache if a symfs is given */ | ||
51 | if (symbol_conf.symfs[0] || | ||
52 | (dso__build_id_filename(dso, file, size) == NULL)) | ||
53 | ret = -1; | ||
54 | break; | ||
55 | |||
56 | case DSO_BINARY_TYPE__FEDORA_DEBUGINFO: | ||
57 | snprintf(file, size, "%s/usr/lib/debug%s.debug", | ||
58 | symbol_conf.symfs, dso->long_name); | ||
59 | break; | ||
60 | |||
61 | case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO: | ||
62 | snprintf(file, size, "%s/usr/lib/debug%s", | ||
63 | symbol_conf.symfs, dso->long_name); | ||
64 | break; | ||
65 | |||
66 | case DSO_BINARY_TYPE__BUILDID_DEBUGINFO: | ||
67 | if (!dso->has_build_id) { | ||
68 | ret = -1; | ||
69 | break; | ||
70 | } | ||
71 | |||
72 | build_id__sprintf(dso->build_id, | ||
73 | sizeof(dso->build_id), | ||
74 | build_id_hex); | ||
75 | snprintf(file, size, | ||
76 | "%s/usr/lib/debug/.build-id/%.2s/%s.debug", | ||
77 | symbol_conf.symfs, build_id_hex, build_id_hex + 2); | ||
78 | break; | ||
79 | |||
80 | case DSO_BINARY_TYPE__SYSTEM_PATH_DSO: | ||
81 | snprintf(file, size, "%s%s", | ||
82 | symbol_conf.symfs, dso->long_name); | ||
83 | break; | ||
84 | |||
85 | case DSO_BINARY_TYPE__GUEST_KMODULE: | ||
86 | snprintf(file, size, "%s%s%s", symbol_conf.symfs, | ||
87 | root_dir, dso->long_name); | ||
88 | break; | ||
89 | |||
90 | case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE: | ||
91 | snprintf(file, size, "%s%s", symbol_conf.symfs, | ||
92 | dso->long_name); | ||
93 | break; | ||
94 | |||
95 | default: | ||
96 | case DSO_BINARY_TYPE__KALLSYMS: | ||
97 | case DSO_BINARY_TYPE__VMLINUX: | ||
98 | case DSO_BINARY_TYPE__GUEST_KALLSYMS: | ||
99 | case DSO_BINARY_TYPE__GUEST_VMLINUX: | ||
100 | case DSO_BINARY_TYPE__JAVA_JIT: | ||
101 | case DSO_BINARY_TYPE__NOT_FOUND: | ||
102 | ret = -1; | ||
103 | break; | ||
104 | } | ||
105 | |||
106 | return ret; | ||
107 | } | ||
108 | |||
109 | static int open_dso(struct dso *dso, struct machine *machine) | ||
110 | { | ||
111 | char *root_dir = (char *) ""; | ||
112 | char *name; | ||
113 | int fd; | ||
114 | |||
115 | name = malloc(PATH_MAX); | ||
116 | if (!name) | ||
117 | return -ENOMEM; | ||
118 | |||
119 | if (machine) | ||
120 | root_dir = machine->root_dir; | ||
121 | |||
122 | if (dso__binary_type_file(dso, dso->data_type, | ||
123 | root_dir, name, PATH_MAX)) { | ||
124 | free(name); | ||
125 | return -EINVAL; | ||
126 | } | ||
127 | |||
128 | fd = open(name, O_RDONLY); | ||
129 | free(name); | ||
130 | return fd; | ||
131 | } | ||
132 | |||
133 | int dso__data_fd(struct dso *dso, struct machine *machine) | ||
134 | { | ||
135 | static enum dso_binary_type binary_type_data[] = { | ||
136 | DSO_BINARY_TYPE__BUILD_ID_CACHE, | ||
137 | DSO_BINARY_TYPE__SYSTEM_PATH_DSO, | ||
138 | DSO_BINARY_TYPE__NOT_FOUND, | ||
139 | }; | ||
140 | int i = 0; | ||
141 | |||
142 | if (dso->data_type != DSO_BINARY_TYPE__NOT_FOUND) | ||
143 | return open_dso(dso, machine); | ||
144 | |||
145 | do { | ||
146 | int fd; | ||
147 | |||
148 | dso->data_type = binary_type_data[i++]; | ||
149 | |||
150 | fd = open_dso(dso, machine); | ||
151 | if (fd >= 0) | ||
152 | return fd; | ||
153 | |||
154 | } while (dso->data_type != DSO_BINARY_TYPE__NOT_FOUND); | ||
155 | |||
156 | return -EINVAL; | ||
157 | } | ||
158 | |||
159 | static void | ||
160 | dso_cache__free(struct rb_root *root) | ||
161 | { | ||
162 | struct rb_node *next = rb_first(root); | ||
163 | |||
164 | while (next) { | ||
165 | struct dso_cache *cache; | ||
166 | |||
167 | cache = rb_entry(next, struct dso_cache, rb_node); | ||
168 | next = rb_next(&cache->rb_node); | ||
169 | rb_erase(&cache->rb_node, root); | ||
170 | free(cache); | ||
171 | } | ||
172 | } | ||
173 | |||
174 | static struct dso_cache* | ||
175 | dso_cache__find(struct rb_root *root, u64 offset) | ||
176 | { | ||
177 | struct rb_node **p = &root->rb_node; | ||
178 | struct rb_node *parent = NULL; | ||
179 | struct dso_cache *cache; | ||
180 | |||
181 | while (*p != NULL) { | ||
182 | u64 end; | ||
183 | |||
184 | parent = *p; | ||
185 | cache = rb_entry(parent, struct dso_cache, rb_node); | ||
186 | end = cache->offset + DSO__DATA_CACHE_SIZE; | ||
187 | |||
188 | if (offset < cache->offset) | ||
189 | p = &(*p)->rb_left; | ||
190 | else if (offset >= end) | ||
191 | p = &(*p)->rb_right; | ||
192 | else | ||
193 | return cache; | ||
194 | } | ||
195 | return NULL; | ||
196 | } | ||
197 | |||
198 | static void | ||
199 | dso_cache__insert(struct rb_root *root, struct dso_cache *new) | ||
200 | { | ||
201 | struct rb_node **p = &root->rb_node; | ||
202 | struct rb_node *parent = NULL; | ||
203 | struct dso_cache *cache; | ||
204 | u64 offset = new->offset; | ||
205 | |||
206 | while (*p != NULL) { | ||
207 | u64 end; | ||
208 | |||
209 | parent = *p; | ||
210 | cache = rb_entry(parent, struct dso_cache, rb_node); | ||
211 | end = cache->offset + DSO__DATA_CACHE_SIZE; | ||
212 | |||
213 | if (offset < cache->offset) | ||
214 | p = &(*p)->rb_left; | ||
215 | else if (offset >= end) | ||
216 | p = &(*p)->rb_right; | ||
217 | } | ||
218 | |||
219 | rb_link_node(&new->rb_node, parent, p); | ||
220 | rb_insert_color(&new->rb_node, root); | ||
221 | } | ||
222 | |||
223 | static ssize_t | ||
224 | dso_cache__memcpy(struct dso_cache *cache, u64 offset, | ||
225 | u8 *data, u64 size) | ||
226 | { | ||
227 | u64 cache_offset = offset - cache->offset; | ||
228 | u64 cache_size = min(cache->size - cache_offset, size); | ||
229 | |||
230 | memcpy(data, cache->data + cache_offset, cache_size); | ||
231 | return cache_size; | ||
232 | } | ||
233 | |||
234 | static ssize_t | ||
235 | dso_cache__read(struct dso *dso, struct machine *machine, | ||
236 | u64 offset, u8 *data, ssize_t size) | ||
237 | { | ||
238 | struct dso_cache *cache; | ||
239 | ssize_t ret; | ||
240 | int fd; | ||
241 | |||
242 | fd = dso__data_fd(dso, machine); | ||
243 | if (fd < 0) | ||
244 | return -1; | ||
245 | |||
246 | do { | ||
247 | u64 cache_offset; | ||
248 | |||
249 | ret = -ENOMEM; | ||
250 | |||
251 | cache = zalloc(sizeof(*cache) + DSO__DATA_CACHE_SIZE); | ||
252 | if (!cache) | ||
253 | break; | ||
254 | |||
255 | cache_offset = offset & DSO__DATA_CACHE_MASK; | ||
256 | ret = -EINVAL; | ||
257 | |||
258 | if (-1 == lseek(fd, cache_offset, SEEK_SET)) | ||
259 | break; | ||
260 | |||
261 | ret = read(fd, cache->data, DSO__DATA_CACHE_SIZE); | ||
262 | if (ret <= 0) | ||
263 | break; | ||
264 | |||
265 | cache->offset = cache_offset; | ||
266 | cache->size = ret; | ||
267 | dso_cache__insert(&dso->cache, cache); | ||
268 | |||
269 | ret = dso_cache__memcpy(cache, offset, data, size); | ||
270 | |||
271 | } while (0); | ||
272 | |||
273 | if (ret <= 0) | ||
274 | free(cache); | ||
275 | |||
276 | close(fd); | ||
277 | return ret; | ||
278 | } | ||
279 | |||
280 | static ssize_t dso_cache_read(struct dso *dso, struct machine *machine, | ||
281 | u64 offset, u8 *data, ssize_t size) | ||
282 | { | ||
283 | struct dso_cache *cache; | ||
284 | |||
285 | cache = dso_cache__find(&dso->cache, offset); | ||
286 | if (cache) | ||
287 | return dso_cache__memcpy(cache, offset, data, size); | ||
288 | else | ||
289 | return dso_cache__read(dso, machine, offset, data, size); | ||
290 | } | ||
291 | |||
292 | ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine, | ||
293 | u64 offset, u8 *data, ssize_t size) | ||
294 | { | ||
295 | ssize_t r = 0; | ||
296 | u8 *p = data; | ||
297 | |||
298 | do { | ||
299 | ssize_t ret; | ||
300 | |||
301 | ret = dso_cache_read(dso, machine, offset, p, size); | ||
302 | if (ret < 0) | ||
303 | return ret; | ||
304 | |||
305 | /* Reached EOF, return what we have. */ | ||
306 | if (!ret) | ||
307 | break; | ||
308 | |||
309 | BUG_ON(ret > size); | ||
310 | |||
311 | r += ret; | ||
312 | p += ret; | ||
313 | offset += ret; | ||
314 | size -= ret; | ||
315 | |||
316 | } while (size); | ||
317 | |||
318 | return r; | ||
319 | } | ||
320 | |||
321 | ssize_t dso__data_read_addr(struct dso *dso, struct map *map, | ||
322 | struct machine *machine, u64 addr, | ||
323 | u8 *data, ssize_t size) | ||
324 | { | ||
325 | u64 offset = map->map_ip(map, addr); | ||
326 | return dso__data_read_offset(dso, machine, offset, data, size); | ||
327 | } | ||
328 | |||
329 | struct map *dso__new_map(const char *name) | ||
330 | { | ||
331 | struct map *map = NULL; | ||
332 | struct dso *dso = dso__new(name); | ||
333 | |||
334 | if (dso) | ||
335 | map = map__new2(0, dso, MAP__FUNCTION); | ||
336 | |||
337 | return map; | ||
338 | } | ||
339 | |||
340 | struct dso *dso__kernel_findnew(struct machine *machine, const char *name, | ||
341 | const char *short_name, int dso_type) | ||
342 | { | ||
343 | /* | ||
344 | * The kernel dso could be created by build_id processing. | ||
345 | */ | ||
346 | struct dso *dso = __dsos__findnew(&machine->kernel_dsos, name); | ||
347 | |||
348 | /* | ||
349 | * We need to run this in all cases, since during the build_id | ||
350 | * processing we had no idea this was the kernel dso. | ||
351 | */ | ||
352 | if (dso != NULL) { | ||
353 | dso__set_short_name(dso, short_name); | ||
354 | dso->kernel = dso_type; | ||
355 | } | ||
356 | |||
357 | return dso; | ||
358 | } | ||
359 | |||
360 | void dso__set_long_name(struct dso *dso, char *name) | ||
361 | { | ||
362 | if (name == NULL) | ||
363 | return; | ||
364 | dso->long_name = name; | ||
365 | dso->long_name_len = strlen(name); | ||
366 | } | ||
367 | |||
368 | void dso__set_short_name(struct dso *dso, const char *name) | ||
369 | { | ||
370 | if (name == NULL) | ||
371 | return; | ||
372 | dso->short_name = name; | ||
373 | dso->short_name_len = strlen(name); | ||
374 | } | ||
375 | |||
376 | static void dso__set_basename(struct dso *dso) | ||
377 | { | ||
378 | dso__set_short_name(dso, basename(dso->long_name)); | ||
379 | } | ||
380 | |||
381 | int dso__name_len(const struct dso *dso) | ||
382 | { | ||
383 | if (!dso) | ||
384 | return strlen("[unknown]"); | ||
385 | if (verbose) | ||
386 | return dso->long_name_len; | ||
387 | |||
388 | return dso->short_name_len; | ||
389 | } | ||
390 | |||
391 | bool dso__loaded(const struct dso *dso, enum map_type type) | ||
392 | { | ||
393 | return dso->loaded & (1 << type); | ||
394 | } | ||
395 | |||
396 | bool dso__sorted_by_name(const struct dso *dso, enum map_type type) | ||
397 | { | ||
398 | return dso->sorted_by_name & (1 << type); | ||
399 | } | ||
400 | |||
401 | void dso__set_sorted_by_name(struct dso *dso, enum map_type type) | ||
402 | { | ||
403 | dso->sorted_by_name |= (1 << type); | ||
404 | } | ||
405 | |||
406 | struct dso *dso__new(const char *name) | ||
407 | { | ||
408 | struct dso *dso = calloc(1, sizeof(*dso) + strlen(name) + 1); | ||
409 | |||
410 | if (dso != NULL) { | ||
411 | int i; | ||
412 | strcpy(dso->name, name); | ||
413 | dso__set_long_name(dso, dso->name); | ||
414 | dso__set_short_name(dso, dso->name); | ||
415 | for (i = 0; i < MAP__NR_TYPES; ++i) | ||
416 | dso->symbols[i] = dso->symbol_names[i] = RB_ROOT; | ||
417 | dso->cache = RB_ROOT; | ||
418 | dso->symtab_type = DSO_BINARY_TYPE__NOT_FOUND; | ||
419 | dso->data_type = DSO_BINARY_TYPE__NOT_FOUND; | ||
420 | dso->loaded = 0; | ||
421 | dso->sorted_by_name = 0; | ||
422 | dso->has_build_id = 0; | ||
423 | dso->kernel = DSO_TYPE_USER; | ||
424 | dso->needs_swap = DSO_SWAP__UNSET; | ||
425 | INIT_LIST_HEAD(&dso->node); | ||
426 | } | ||
427 | |||
428 | return dso; | ||
429 | } | ||
430 | |||
431 | void dso__delete(struct dso *dso) | ||
432 | { | ||
433 | int i; | ||
434 | for (i = 0; i < MAP__NR_TYPES; ++i) | ||
435 | symbols__delete(&dso->symbols[i]); | ||
436 | if (dso->sname_alloc) | ||
437 | free((char *)dso->short_name); | ||
438 | if (dso->lname_alloc) | ||
439 | free(dso->long_name); | ||
440 | dso_cache__free(&dso->cache); | ||
441 | free(dso); | ||
442 | } | ||
443 | |||
444 | void dso__set_build_id(struct dso *dso, void *build_id) | ||
445 | { | ||
446 | memcpy(dso->build_id, build_id, sizeof(dso->build_id)); | ||
447 | dso->has_build_id = 1; | ||
448 | } | ||
449 | |||
450 | bool dso__build_id_equal(const struct dso *dso, u8 *build_id) | ||
451 | { | ||
452 | return memcmp(dso->build_id, build_id, sizeof(dso->build_id)) == 0; | ||
453 | } | ||
454 | |||
455 | void dso__read_running_kernel_build_id(struct dso *dso, struct machine *machine) | ||
456 | { | ||
457 | char path[PATH_MAX]; | ||
458 | |||
459 | if (machine__is_default_guest(machine)) | ||
460 | return; | ||
461 | sprintf(path, "%s/sys/kernel/notes", machine->root_dir); | ||
462 | if (sysfs__read_build_id(path, dso->build_id, | ||
463 | sizeof(dso->build_id)) == 0) | ||
464 | dso->has_build_id = true; | ||
465 | } | ||
466 | |||
467 | int dso__kernel_module_get_build_id(struct dso *dso, | ||
468 | const char *root_dir) | ||
469 | { | ||
470 | char filename[PATH_MAX]; | ||
471 | /* | ||
472 | * kernel module short names are of the form "[module]" and | ||
473 | * we need just "module" here. | ||
474 | */ | ||
475 | const char *name = dso->short_name + 1; | ||
476 | |||
477 | snprintf(filename, sizeof(filename), | ||
478 | "%s/sys/module/%.*s/notes/.note.gnu.build-id", | ||
479 | root_dir, (int)strlen(name) - 1, name); | ||
480 | |||
481 | if (sysfs__read_build_id(filename, dso->build_id, | ||
482 | sizeof(dso->build_id)) == 0) | ||
483 | dso->has_build_id = true; | ||
484 | |||
485 | return 0; | ||
486 | } | ||
487 | |||
488 | bool __dsos__read_build_ids(struct list_head *head, bool with_hits) | ||
489 | { | ||
490 | bool have_build_id = false; | ||
491 | struct dso *pos; | ||
492 | |||
493 | list_for_each_entry(pos, head, node) { | ||
494 | if (with_hits && !pos->hit) | ||
495 | continue; | ||
496 | if (pos->has_build_id) { | ||
497 | have_build_id = true; | ||
498 | continue; | ||
499 | } | ||
500 | if (filename__read_build_id(pos->long_name, pos->build_id, | ||
501 | sizeof(pos->build_id)) > 0) { | ||
502 | have_build_id = true; | ||
503 | pos->has_build_id = true; | ||
504 | } | ||
505 | } | ||
506 | |||
507 | return have_build_id; | ||
508 | } | ||
509 | |||
510 | void dsos__add(struct list_head *head, struct dso *dso) | ||
511 | { | ||
512 | list_add_tail(&dso->node, head); | ||
513 | } | ||
514 | |||
515 | struct dso *dsos__find(struct list_head *head, const char *name) | ||
516 | { | ||
517 | struct dso *pos; | ||
518 | |||
519 | list_for_each_entry(pos, head, node) | ||
520 | if (strcmp(pos->long_name, name) == 0) | ||
521 | return pos; | ||
522 | return NULL; | ||
523 | } | ||
524 | |||
525 | struct dso *__dsos__findnew(struct list_head *head, const char *name) | ||
526 | { | ||
527 | struct dso *dso = dsos__find(head, name); | ||
528 | |||
529 | if (!dso) { | ||
530 | dso = dso__new(name); | ||
531 | if (dso != NULL) { | ||
532 | dsos__add(head, dso); | ||
533 | dso__set_basename(dso); | ||
534 | } | ||
535 | } | ||
536 | |||
537 | return dso; | ||
538 | } | ||
539 | |||
540 | size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp, | ||
541 | bool with_hits) | ||
542 | { | ||
543 | struct dso *pos; | ||
544 | size_t ret = 0; | ||
545 | |||
546 | list_for_each_entry(pos, head, node) { | ||
547 | if (with_hits && !pos->hit) | ||
548 | continue; | ||
549 | ret += dso__fprintf_buildid(pos, fp); | ||
550 | ret += fprintf(fp, " %s\n", pos->long_name); | ||
551 | } | ||
552 | return ret; | ||
553 | } | ||
554 | |||
555 | size_t __dsos__fprintf(struct list_head *head, FILE *fp) | ||
556 | { | ||
557 | struct dso *pos; | ||
558 | size_t ret = 0; | ||
559 | |||
560 | list_for_each_entry(pos, head, node) { | ||
561 | int i; | ||
562 | for (i = 0; i < MAP__NR_TYPES; ++i) | ||
563 | ret += dso__fprintf(pos, i, fp); | ||
564 | } | ||
565 | |||
566 | return ret; | ||
567 | } | ||
568 | |||
569 | size_t dso__fprintf_buildid(struct dso *dso, FILE *fp) | ||
570 | { | ||
571 | char sbuild_id[BUILD_ID_SIZE * 2 + 1]; | ||
572 | |||
573 | build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id); | ||
574 | return fprintf(fp, "%s", sbuild_id); | ||
575 | } | ||
576 | |||
577 | size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp) | ||
578 | { | ||
579 | struct rb_node *nd; | ||
580 | size_t ret = fprintf(fp, "dso: %s (", dso->short_name); | ||
581 | |||
582 | if (dso->short_name != dso->long_name) | ||
583 | ret += fprintf(fp, "%s, ", dso->long_name); | ||
584 | ret += fprintf(fp, "%s, %sloaded, ", map_type__name[type], | ||
585 | dso->loaded ? "" : "NOT "); | ||
586 | ret += dso__fprintf_buildid(dso, fp); | ||
587 | ret += fprintf(fp, ")\n"); | ||
588 | for (nd = rb_first(&dso->symbols[type]); nd; nd = rb_next(nd)) { | ||
589 | struct symbol *pos = rb_entry(nd, struct symbol, rb_node); | ||
590 | ret += symbol__fprintf(pos, fp); | ||
591 | } | ||
592 | |||
593 | return ret; | ||
594 | } | ||
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h new file mode 100644 index 000000000000..e03276940b99 --- /dev/null +++ b/tools/perf/util/dso.h | |||
@@ -0,0 +1,148 @@ | |||
1 | #ifndef __PERF_DSO | ||
2 | #define __PERF_DSO | ||
3 | |||
4 | #include <linux/types.h> | ||
5 | #include <linux/rbtree.h> | ||
6 | #include "types.h" | ||
7 | #include "map.h" | ||
8 | |||
9 | enum dso_binary_type { | ||
10 | DSO_BINARY_TYPE__KALLSYMS = 0, | ||
11 | DSO_BINARY_TYPE__GUEST_KALLSYMS, | ||
12 | DSO_BINARY_TYPE__VMLINUX, | ||
13 | DSO_BINARY_TYPE__GUEST_VMLINUX, | ||
14 | DSO_BINARY_TYPE__JAVA_JIT, | ||
15 | DSO_BINARY_TYPE__DEBUGLINK, | ||
16 | DSO_BINARY_TYPE__BUILD_ID_CACHE, | ||
17 | DSO_BINARY_TYPE__FEDORA_DEBUGINFO, | ||
18 | DSO_BINARY_TYPE__UBUNTU_DEBUGINFO, | ||
19 | DSO_BINARY_TYPE__BUILDID_DEBUGINFO, | ||
20 | DSO_BINARY_TYPE__SYSTEM_PATH_DSO, | ||
21 | DSO_BINARY_TYPE__GUEST_KMODULE, | ||
22 | DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE, | ||
23 | DSO_BINARY_TYPE__NOT_FOUND, | ||
24 | }; | ||
25 | |||
26 | enum dso_kernel_type { | ||
27 | DSO_TYPE_USER = 0, | ||
28 | DSO_TYPE_KERNEL, | ||
29 | DSO_TYPE_GUEST_KERNEL | ||
30 | }; | ||
31 | |||
32 | enum dso_swap_type { | ||
33 | DSO_SWAP__UNSET, | ||
34 | DSO_SWAP__NO, | ||
35 | DSO_SWAP__YES, | ||
36 | }; | ||
37 | |||
38 | #define DSO__SWAP(dso, type, val) \ | ||
39 | ({ \ | ||
40 | type ____r = val; \ | ||
41 | BUG_ON(dso->needs_swap == DSO_SWAP__UNSET); \ | ||
42 | if (dso->needs_swap == DSO_SWAP__YES) { \ | ||
43 | switch (sizeof(____r)) { \ | ||
44 | case 2: \ | ||
45 | ____r = bswap_16(val); \ | ||
46 | break; \ | ||
47 | case 4: \ | ||
48 | ____r = bswap_32(val); \ | ||
49 | break; \ | ||
50 | case 8: \ | ||
51 | ____r = bswap_64(val); \ | ||
52 | break; \ | ||
53 | default: \ | ||
54 | BUG_ON(1); \ | ||
55 | } \ | ||
56 | } \ | ||
57 | ____r; \ | ||
58 | }) | ||
59 | |||
60 | #define DSO__DATA_CACHE_SIZE 4096 | ||
61 | #define DSO__DATA_CACHE_MASK ~(DSO__DATA_CACHE_SIZE - 1) | ||
62 | |||
63 | struct dso_cache { | ||
64 | struct rb_node rb_node; | ||
65 | u64 offset; | ||
66 | u64 size; | ||
67 | char data[0]; | ||
68 | }; | ||
69 | |||
70 | struct dso { | ||
71 | struct list_head node; | ||
72 | struct rb_root symbols[MAP__NR_TYPES]; | ||
73 | struct rb_root symbol_names[MAP__NR_TYPES]; | ||
74 | struct rb_root cache; | ||
75 | enum dso_kernel_type kernel; | ||
76 | enum dso_swap_type needs_swap; | ||
77 | enum dso_binary_type symtab_type; | ||
78 | enum dso_binary_type data_type; | ||
79 | u8 adjust_symbols:1; | ||
80 | u8 has_build_id:1; | ||
81 | u8 hit:1; | ||
82 | u8 annotate_warned:1; | ||
83 | u8 sname_alloc:1; | ||
84 | u8 lname_alloc:1; | ||
85 | u8 sorted_by_name; | ||
86 | u8 loaded; | ||
87 | u8 build_id[BUILD_ID_SIZE]; | ||
88 | const char *short_name; | ||
89 | char *long_name; | ||
90 | u16 long_name_len; | ||
91 | u16 short_name_len; | ||
92 | char name[0]; | ||
93 | }; | ||
94 | |||
95 | static inline void dso__set_loaded(struct dso *dso, enum map_type type) | ||
96 | { | ||
97 | dso->loaded |= (1 << type); | ||
98 | } | ||
99 | |||
100 | struct dso *dso__new(const char *name); | ||
101 | void dso__delete(struct dso *dso); | ||
102 | |||
103 | void dso__set_short_name(struct dso *dso, const char *name); | ||
104 | void dso__set_long_name(struct dso *dso, char *name); | ||
105 | |||
106 | int dso__name_len(const struct dso *dso); | ||
107 | |||
108 | bool dso__loaded(const struct dso *dso, enum map_type type); | ||
109 | |||
110 | bool dso__sorted_by_name(const struct dso *dso, enum map_type type); | ||
111 | void dso__set_sorted_by_name(struct dso *dso, enum map_type type); | ||
112 | void dso__sort_by_name(struct dso *dso, enum map_type type); | ||
113 | |||
114 | void dso__set_build_id(struct dso *dso, void *build_id); | ||
115 | bool dso__build_id_equal(const struct dso *dso, u8 *build_id); | ||
116 | void dso__read_running_kernel_build_id(struct dso *dso, | ||
117 | struct machine *machine); | ||
118 | int dso__kernel_module_get_build_id(struct dso *dso, const char *root_dir); | ||
119 | |||
120 | char dso__symtab_origin(const struct dso *dso); | ||
121 | int dso__binary_type_file(struct dso *dso, enum dso_binary_type type, | ||
122 | char *root_dir, char *file, size_t size); | ||
123 | |||
124 | int dso__data_fd(struct dso *dso, struct machine *machine); | ||
125 | ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine, | ||
126 | u64 offset, u8 *data, ssize_t size); | ||
127 | ssize_t dso__data_read_addr(struct dso *dso, struct map *map, | ||
128 | struct machine *machine, u64 addr, | ||
129 | u8 *data, ssize_t size); | ||
130 | |||
131 | struct map *dso__new_map(const char *name); | ||
132 | struct dso *dso__kernel_findnew(struct machine *machine, const char *name, | ||
133 | const char *short_name, int dso_type); | ||
134 | |||
135 | void dsos__add(struct list_head *head, struct dso *dso); | ||
136 | struct dso *dsos__find(struct list_head *head, const char *name); | ||
137 | struct dso *__dsos__findnew(struct list_head *head, const char *name); | ||
138 | bool __dsos__read_build_ids(struct list_head *head, bool with_hits); | ||
139 | |||
140 | size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp, | ||
141 | bool with_hits); | ||
142 | size_t __dsos__fprintf(struct list_head *head, FILE *fp); | ||
143 | |||
144 | size_t dso__fprintf_buildid(struct dso *dso, FILE *fp); | ||
145 | size_t dso__fprintf_symbols_by_name(struct dso *dso, | ||
146 | enum map_type type, FILE *fp); | ||
147 | size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp); | ||
148 | #endif /* __PERF_DSO */ | ||
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index d3b1ecc00cbc..624c65e6ab98 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #define KSYM_NAME_LEN 256 | 23 | #define KSYM_NAME_LEN 256 |
24 | #endif | 24 | #endif |
25 | 25 | ||
26 | static void dso_cache__free(struct rb_root *root); | ||
27 | static int dso__load_kernel_sym(struct dso *dso, struct map *map, | 26 | static int dso__load_kernel_sym(struct dso *dso, struct map *map, |
28 | symbol_filter_t filter); | 27 | symbol_filter_t filter); |
29 | static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map, | 28 | static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map, |
@@ -56,39 +55,6 @@ static enum dso_binary_type binary_type_symtab[] = { | |||
56 | 55 | ||
57 | #define DSO_BINARY_TYPE__SYMTAB_CNT ARRAY_SIZE(binary_type_symtab) | 56 | #define DSO_BINARY_TYPE__SYMTAB_CNT ARRAY_SIZE(binary_type_symtab) |
58 | 57 | ||
59 | static enum dso_binary_type binary_type_data[] = { | ||
60 | DSO_BINARY_TYPE__BUILD_ID_CACHE, | ||
61 | DSO_BINARY_TYPE__SYSTEM_PATH_DSO, | ||
62 | DSO_BINARY_TYPE__NOT_FOUND, | ||
63 | }; | ||
64 | |||
65 | #define DSO_BINARY_TYPE__DATA_CNT ARRAY_SIZE(binary_type_data) | ||
66 | |||
67 | int dso__name_len(const struct dso *dso) | ||
68 | { | ||
69 | if (!dso) | ||
70 | return strlen("[unknown]"); | ||
71 | if (verbose) | ||
72 | return dso->long_name_len; | ||
73 | |||
74 | return dso->short_name_len; | ||
75 | } | ||
76 | |||
77 | bool dso__loaded(const struct dso *dso, enum map_type type) | ||
78 | { | ||
79 | return dso->loaded & (1 << type); | ||
80 | } | ||
81 | |||
82 | bool dso__sorted_by_name(const struct dso *dso, enum map_type type) | ||
83 | { | ||
84 | return dso->sorted_by_name & (1 << type); | ||
85 | } | ||
86 | |||
87 | static void dso__set_sorted_by_name(struct dso *dso, enum map_type type) | ||
88 | { | ||
89 | dso->sorted_by_name |= (1 << type); | ||
90 | } | ||
91 | |||
92 | bool symbol_type__is_a(char symbol_type, enum map_type map_type) | 58 | bool symbol_type__is_a(char symbol_type, enum map_type map_type) |
93 | { | 59 | { |
94 | symbol_type = toupper(symbol_type); | 60 | symbol_type = toupper(symbol_type); |
@@ -270,7 +236,7 @@ void symbol__delete(struct symbol *sym) | |||
270 | free(((void *)sym) - symbol_conf.priv_size); | 236 | free(((void *)sym) - symbol_conf.priv_size); |
271 | } | 237 | } |
272 | 238 | ||
273 | static size_t symbol__fprintf(struct symbol *sym, FILE *fp) | 239 | size_t symbol__fprintf(struct symbol *sym, FILE *fp) |
274 | { | 240 | { |
275 | return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %c %s\n", | 241 | return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %c %s\n", |
276 | sym->start, sym->end, | 242 | sym->start, sym->end, |
@@ -301,53 +267,7 @@ size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp) | |||
301 | return symbol__fprintf_symname_offs(sym, NULL, fp); | 267 | return symbol__fprintf_symname_offs(sym, NULL, fp); |
302 | } | 268 | } |
303 | 269 | ||
304 | void dso__set_long_name(struct dso *dso, char *name) | 270 | void symbols__delete(struct rb_root *symbols) |
305 | { | ||
306 | if (name == NULL) | ||
307 | return; | ||
308 | dso->long_name = name; | ||
309 | dso->long_name_len = strlen(name); | ||
310 | } | ||
311 | |||
312 | static void dso__set_short_name(struct dso *dso, const char *name) | ||
313 | { | ||
314 | if (name == NULL) | ||
315 | return; | ||
316 | dso->short_name = name; | ||
317 | dso->short_name_len = strlen(name); | ||
318 | } | ||
319 | |||
320 | static void dso__set_basename(struct dso *dso) | ||
321 | { | ||
322 | dso__set_short_name(dso, basename(dso->long_name)); | ||
323 | } | ||
324 | |||
325 | struct dso *dso__new(const char *name) | ||
326 | { | ||
327 | struct dso *dso = calloc(1, sizeof(*dso) + strlen(name) + 1); | ||
328 | |||
329 | if (dso != NULL) { | ||
330 | int i; | ||
331 | strcpy(dso->name, name); | ||
332 | dso__set_long_name(dso, dso->name); | ||
333 | dso__set_short_name(dso, dso->name); | ||
334 | for (i = 0; i < MAP__NR_TYPES; ++i) | ||
335 | dso->symbols[i] = dso->symbol_names[i] = RB_ROOT; | ||
336 | dso->cache = RB_ROOT; | ||
337 | dso->symtab_type = DSO_BINARY_TYPE__NOT_FOUND; | ||
338 | dso->data_type = DSO_BINARY_TYPE__NOT_FOUND; | ||
339 | dso->loaded = 0; | ||
340 | dso->sorted_by_name = 0; | ||
341 | dso->has_build_id = 0; | ||
342 | dso->kernel = DSO_TYPE_USER; | ||
343 | dso->needs_swap = DSO_SWAP__UNSET; | ||
344 | INIT_LIST_HEAD(&dso->node); | ||
345 | } | ||
346 | |||
347 | return dso; | ||
348 | } | ||
349 | |||
350 | static void symbols__delete(struct rb_root *symbols) | ||
351 | { | 271 | { |
352 | struct symbol *pos; | 272 | struct symbol *pos; |
353 | struct rb_node *next = rb_first(symbols); | 273 | struct rb_node *next = rb_first(symbols); |
@@ -360,25 +280,6 @@ static void symbols__delete(struct rb_root *symbols) | |||
360 | } | 280 | } |
361 | } | 281 | } |
362 | 282 | ||
363 | void dso__delete(struct dso *dso) | ||
364 | { | ||
365 | int i; | ||
366 | for (i = 0; i < MAP__NR_TYPES; ++i) | ||
367 | symbols__delete(&dso->symbols[i]); | ||
368 | if (dso->sname_alloc) | ||
369 | free((char *)dso->short_name); | ||
370 | if (dso->lname_alloc) | ||
371 | free(dso->long_name); | ||
372 | dso_cache__free(&dso->cache); | ||
373 | free(dso); | ||
374 | } | ||
375 | |||
376 | void dso__set_build_id(struct dso *dso, void *build_id) | ||
377 | { | ||
378 | memcpy(dso->build_id, build_id, sizeof(dso->build_id)); | ||
379 | dso->has_build_id = 1; | ||
380 | } | ||
381 | |||
382 | void symbols__insert(struct rb_root *symbols, struct symbol *sym) | 283 | void symbols__insert(struct rb_root *symbols, struct symbol *sym) |
383 | { | 284 | { |
384 | struct rb_node **p = &symbols->rb_node; | 285 | struct rb_node **p = &symbols->rb_node; |
@@ -504,14 +405,6 @@ void dso__sort_by_name(struct dso *dso, enum map_type type) | |||
504 | &dso->symbols[type]); | 405 | &dso->symbols[type]); |
505 | } | 406 | } |
506 | 407 | ||
507 | size_t dso__fprintf_buildid(struct dso *dso, FILE *fp) | ||
508 | { | ||
509 | char sbuild_id[BUILD_ID_SIZE * 2 + 1]; | ||
510 | |||
511 | build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id); | ||
512 | return fprintf(fp, "%s", sbuild_id); | ||
513 | } | ||
514 | |||
515 | size_t dso__fprintf_symbols_by_name(struct dso *dso, | 408 | size_t dso__fprintf_symbols_by_name(struct dso *dso, |
516 | enum map_type type, FILE *fp) | 409 | enum map_type type, FILE *fp) |
517 | { | 410 | { |
@@ -527,25 +420,6 @@ size_t dso__fprintf_symbols_by_name(struct dso *dso, | |||
527 | return ret; | 420 | return ret; |
528 | } | 421 | } |
529 | 422 | ||
530 | size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp) | ||
531 | { | ||
532 | struct rb_node *nd; | ||
533 | size_t ret = fprintf(fp, "dso: %s (", dso->short_name); | ||
534 | |||
535 | if (dso->short_name != dso->long_name) | ||
536 | ret += fprintf(fp, "%s, ", dso->long_name); | ||
537 | ret += fprintf(fp, "%s, %sloaded, ", map_type__name[type], | ||
538 | dso->loaded ? "" : "NOT "); | ||
539 | ret += dso__fprintf_buildid(dso, fp); | ||
540 | ret += fprintf(fp, ")\n"); | ||
541 | for (nd = rb_first(&dso->symbols[type]); nd; nd = rb_next(nd)) { | ||
542 | struct symbol *pos = rb_entry(nd, struct symbol, rb_node); | ||
543 | ret += symbol__fprintf(pos, fp); | ||
544 | } | ||
545 | |||
546 | return ret; | ||
547 | } | ||
548 | |||
549 | int kallsyms__parse(const char *filename, void *arg, | 423 | int kallsyms__parse(const char *filename, void *arg, |
550 | int (*process_symbol)(void *arg, const char *name, | 424 | int (*process_symbol)(void *arg, const char *name, |
551 | char type, u64 start)) | 425 | char type, u64 start)) |
@@ -877,136 +751,6 @@ out_failure: | |||
877 | return -1; | 751 | return -1; |
878 | } | 752 | } |
879 | 753 | ||
880 | bool dso__build_id_equal(const struct dso *dso, u8 *build_id) | ||
881 | { | ||
882 | return memcmp(dso->build_id, build_id, sizeof(dso->build_id)) == 0; | ||
883 | } | ||
884 | |||
885 | bool __dsos__read_build_ids(struct list_head *head, bool with_hits) | ||
886 | { | ||
887 | bool have_build_id = false; | ||
888 | struct dso *pos; | ||
889 | |||
890 | list_for_each_entry(pos, head, node) { | ||
891 | if (with_hits && !pos->hit) | ||
892 | continue; | ||
893 | if (pos->has_build_id) { | ||
894 | have_build_id = true; | ||
895 | continue; | ||
896 | } | ||
897 | if (filename__read_build_id(pos->long_name, pos->build_id, | ||
898 | sizeof(pos->build_id)) > 0) { | ||
899 | have_build_id = true; | ||
900 | pos->has_build_id = true; | ||
901 | } | ||
902 | } | ||
903 | |||
904 | return have_build_id; | ||
905 | } | ||
906 | |||
907 | char dso__symtab_origin(const struct dso *dso) | ||
908 | { | ||
909 | static const char origin[] = { | ||
910 | [DSO_BINARY_TYPE__KALLSYMS] = 'k', | ||
911 | [DSO_BINARY_TYPE__VMLINUX] = 'v', | ||
912 | [DSO_BINARY_TYPE__JAVA_JIT] = 'j', | ||
913 | [DSO_BINARY_TYPE__DEBUGLINK] = 'l', | ||
914 | [DSO_BINARY_TYPE__BUILD_ID_CACHE] = 'B', | ||
915 | [DSO_BINARY_TYPE__FEDORA_DEBUGINFO] = 'f', | ||
916 | [DSO_BINARY_TYPE__UBUNTU_DEBUGINFO] = 'u', | ||
917 | [DSO_BINARY_TYPE__BUILDID_DEBUGINFO] = 'b', | ||
918 | [DSO_BINARY_TYPE__SYSTEM_PATH_DSO] = 'd', | ||
919 | [DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE] = 'K', | ||
920 | [DSO_BINARY_TYPE__GUEST_KALLSYMS] = 'g', | ||
921 | [DSO_BINARY_TYPE__GUEST_KMODULE] = 'G', | ||
922 | [DSO_BINARY_TYPE__GUEST_VMLINUX] = 'V', | ||
923 | }; | ||
924 | |||
925 | if (dso == NULL || dso->symtab_type == DSO_BINARY_TYPE__NOT_FOUND) | ||
926 | return '!'; | ||
927 | return origin[dso->symtab_type]; | ||
928 | } | ||
929 | |||
930 | int dso__binary_type_file(struct dso *dso, enum dso_binary_type type, | ||
931 | char *root_dir, char *file, size_t size) | ||
932 | { | ||
933 | char build_id_hex[BUILD_ID_SIZE * 2 + 1]; | ||
934 | int ret = 0; | ||
935 | |||
936 | switch (type) { | ||
937 | case DSO_BINARY_TYPE__DEBUGLINK: { | ||
938 | char *debuglink; | ||
939 | |||
940 | strncpy(file, dso->long_name, size); | ||
941 | debuglink = file + dso->long_name_len; | ||
942 | while (debuglink != file && *debuglink != '/') | ||
943 | debuglink--; | ||
944 | if (*debuglink == '/') | ||
945 | debuglink++; | ||
946 | filename__read_debuglink(dso->long_name, debuglink, | ||
947 | size - (debuglink - file)); | ||
948 | } | ||
949 | break; | ||
950 | case DSO_BINARY_TYPE__BUILD_ID_CACHE: | ||
951 | /* skip the locally configured cache if a symfs is given */ | ||
952 | if (symbol_conf.symfs[0] || | ||
953 | (dso__build_id_filename(dso, file, size) == NULL)) | ||
954 | ret = -1; | ||
955 | break; | ||
956 | |||
957 | case DSO_BINARY_TYPE__FEDORA_DEBUGINFO: | ||
958 | snprintf(file, size, "%s/usr/lib/debug%s.debug", | ||
959 | symbol_conf.symfs, dso->long_name); | ||
960 | break; | ||
961 | |||
962 | case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO: | ||
963 | snprintf(file, size, "%s/usr/lib/debug%s", | ||
964 | symbol_conf.symfs, dso->long_name); | ||
965 | break; | ||
966 | |||
967 | case DSO_BINARY_TYPE__BUILDID_DEBUGINFO: | ||
968 | if (!dso->has_build_id) { | ||
969 | ret = -1; | ||
970 | break; | ||
971 | } | ||
972 | |||
973 | build_id__sprintf(dso->build_id, | ||
974 | sizeof(dso->build_id), | ||
975 | build_id_hex); | ||
976 | snprintf(file, size, | ||
977 | "%s/usr/lib/debug/.build-id/%.2s/%s.debug", | ||
978 | symbol_conf.symfs, build_id_hex, build_id_hex + 2); | ||
979 | break; | ||
980 | |||
981 | case DSO_BINARY_TYPE__SYSTEM_PATH_DSO: | ||
982 | snprintf(file, size, "%s%s", | ||
983 | symbol_conf.symfs, dso->long_name); | ||
984 | break; | ||
985 | |||
986 | case DSO_BINARY_TYPE__GUEST_KMODULE: | ||
987 | snprintf(file, size, "%s%s%s", symbol_conf.symfs, | ||
988 | root_dir, dso->long_name); | ||
989 | break; | ||
990 | |||
991 | case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE: | ||
992 | snprintf(file, size, "%s%s", symbol_conf.symfs, | ||
993 | dso->long_name); | ||
994 | break; | ||
995 | |||
996 | default: | ||
997 | case DSO_BINARY_TYPE__KALLSYMS: | ||
998 | case DSO_BINARY_TYPE__VMLINUX: | ||
999 | case DSO_BINARY_TYPE__GUEST_KALLSYMS: | ||
1000 | case DSO_BINARY_TYPE__GUEST_VMLINUX: | ||
1001 | case DSO_BINARY_TYPE__JAVA_JIT: | ||
1002 | case DSO_BINARY_TYPE__NOT_FOUND: | ||
1003 | ret = -1; | ||
1004 | break; | ||
1005 | } | ||
1006 | |||
1007 | return ret; | ||
1008 | } | ||
1009 | |||
1010 | int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter) | 754 | int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter) |
1011 | { | 755 | { |
1012 | char *name; | 756 | char *name; |
@@ -1142,27 +886,6 @@ struct map *map_groups__find_by_name(struct map_groups *mg, | |||
1142 | return NULL; | 886 | return NULL; |
1143 | } | 887 | } |
1144 | 888 | ||
1145 | static int dso__kernel_module_get_build_id(struct dso *dso, | ||
1146 | const char *root_dir) | ||
1147 | { | ||
1148 | char filename[PATH_MAX]; | ||
1149 | /* | ||
1150 | * kernel module short names are of the form "[module]" and | ||
1151 | * we need just "module" here. | ||
1152 | */ | ||
1153 | const char *name = dso->short_name + 1; | ||
1154 | |||
1155 | snprintf(filename, sizeof(filename), | ||
1156 | "%s/sys/module/%.*s/notes/.note.gnu.build-id", | ||
1157 | root_dir, (int)strlen(name) - 1, name); | ||
1158 | |||
1159 | if (sysfs__read_build_id(filename, dso->build_id, | ||
1160 | sizeof(dso->build_id)) == 0) | ||
1161 | dso->has_build_id = true; | ||
1162 | |||
1163 | return 0; | ||
1164 | } | ||
1165 | |||
1166 | static int map_groups__set_modules_path_dir(struct map_groups *mg, | 889 | static int map_groups__set_modules_path_dir(struct map_groups *mg, |
1167 | const char *dir_name) | 890 | const char *dir_name) |
1168 | { | 891 | { |
@@ -1576,50 +1299,6 @@ out_try_fixup: | |||
1576 | return err; | 1299 | return err; |
1577 | } | 1300 | } |
1578 | 1301 | ||
1579 | void dsos__add(struct list_head *head, struct dso *dso) | ||
1580 | { | ||
1581 | list_add_tail(&dso->node, head); | ||
1582 | } | ||
1583 | |||
1584 | struct dso *dsos__find(struct list_head *head, const char *name) | ||
1585 | { | ||
1586 | struct dso *pos; | ||
1587 | |||
1588 | list_for_each_entry(pos, head, node) | ||
1589 | if (strcmp(pos->long_name, name) == 0) | ||
1590 | return pos; | ||
1591 | return NULL; | ||
1592 | } | ||
1593 | |||
1594 | struct dso *__dsos__findnew(struct list_head *head, const char *name) | ||
1595 | { | ||
1596 | struct dso *dso = dsos__find(head, name); | ||
1597 | |||
1598 | if (!dso) { | ||
1599 | dso = dso__new(name); | ||
1600 | if (dso != NULL) { | ||
1601 | dsos__add(head, dso); | ||
1602 | dso__set_basename(dso); | ||
1603 | } | ||
1604 | } | ||
1605 | |||
1606 | return dso; | ||
1607 | } | ||
1608 | |||
1609 | size_t __dsos__fprintf(struct list_head *head, FILE *fp) | ||
1610 | { | ||
1611 | struct dso *pos; | ||
1612 | size_t ret = 0; | ||
1613 | |||
1614 | list_for_each_entry(pos, head, node) { | ||
1615 | int i; | ||
1616 | for (i = 0; i < MAP__NR_TYPES; ++i) | ||
1617 | ret += dso__fprintf(pos, i, fp); | ||
1618 | } | ||
1619 | |||
1620 | return ret; | ||
1621 | } | ||
1622 | |||
1623 | size_t machines__fprintf_dsos(struct rb_root *machines, FILE *fp) | 1302 | size_t machines__fprintf_dsos(struct rb_root *machines, FILE *fp) |
1624 | { | 1303 | { |
1625 | struct rb_node *nd; | 1304 | struct rb_node *nd; |
@@ -1634,21 +1313,6 @@ size_t machines__fprintf_dsos(struct rb_root *machines, FILE *fp) | |||
1634 | return ret; | 1313 | return ret; |
1635 | } | 1314 | } |
1636 | 1315 | ||
1637 | static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp, | ||
1638 | bool with_hits) | ||
1639 | { | ||
1640 | struct dso *pos; | ||
1641 | size_t ret = 0; | ||
1642 | |||
1643 | list_for_each_entry(pos, head, node) { | ||
1644 | if (with_hits && !pos->hit) | ||
1645 | continue; | ||
1646 | ret += dso__fprintf_buildid(pos, fp); | ||
1647 | ret += fprintf(fp, " %s\n", pos->long_name); | ||
1648 | } | ||
1649 | return ret; | ||
1650 | } | ||
1651 | |||
1652 | size_t machine__fprintf_dsos_buildid(struct machine *machine, FILE *fp, | 1316 | size_t machine__fprintf_dsos_buildid(struct machine *machine, FILE *fp, |
1653 | bool with_hits) | 1317 | bool with_hits) |
1654 | { | 1318 | { |
@@ -1669,39 +1333,6 @@ size_t machines__fprintf_dsos_buildid(struct rb_root *machines, | |||
1669 | return ret; | 1333 | return ret; |
1670 | } | 1334 | } |
1671 | 1335 | ||
1672 | static struct dso* | ||
1673 | dso__kernel_findnew(struct machine *machine, const char *name, | ||
1674 | const char *short_name, int dso_type) | ||
1675 | { | ||
1676 | /* | ||
1677 | * The kernel dso could be created by build_id processing. | ||
1678 | */ | ||
1679 | struct dso *dso = __dsos__findnew(&machine->kernel_dsos, name); | ||
1680 | |||
1681 | /* | ||
1682 | * We need to run this in all cases, since during the build_id | ||
1683 | * processing we had no idea this was the kernel dso. | ||
1684 | */ | ||
1685 | if (dso != NULL) { | ||
1686 | dso__set_short_name(dso, short_name); | ||
1687 | dso->kernel = dso_type; | ||
1688 | } | ||
1689 | |||
1690 | return dso; | ||
1691 | } | ||
1692 | |||
1693 | void dso__read_running_kernel_build_id(struct dso *dso, struct machine *machine) | ||
1694 | { | ||
1695 | char path[PATH_MAX]; | ||
1696 | |||
1697 | if (machine__is_default_guest(machine)) | ||
1698 | return; | ||
1699 | sprintf(path, "%s/sys/kernel/notes", machine->root_dir); | ||
1700 | if (sysfs__read_build_id(path, dso->build_id, | ||
1701 | sizeof(dso->build_id)) == 0) | ||
1702 | dso->has_build_id = true; | ||
1703 | } | ||
1704 | |||
1705 | static struct dso *machine__get_kernel(struct machine *machine) | 1336 | static struct dso *machine__get_kernel(struct machine *machine) |
1706 | { | 1337 | { |
1707 | const char *vmlinux_name = NULL; | 1338 | const char *vmlinux_name = NULL; |
@@ -2144,229 +1775,3 @@ int machine__load_vmlinux_path(struct machine *machine, enum map_type type, | |||
2144 | 1775 | ||
2145 | return ret; | 1776 | return ret; |
2146 | } | 1777 | } |
2147 | |||
2148 | struct map *dso__new_map(const char *name) | ||
2149 | { | ||
2150 | struct map *map = NULL; | ||
2151 | struct dso *dso = dso__new(name); | ||
2152 | |||
2153 | if (dso) | ||
2154 | map = map__new2(0, dso, MAP__FUNCTION); | ||
2155 | |||
2156 | return map; | ||
2157 | } | ||
2158 | |||
2159 | static int open_dso(struct dso *dso, struct machine *machine) | ||
2160 | { | ||
2161 | char *root_dir = (char *) ""; | ||
2162 | char *name; | ||
2163 | int fd; | ||
2164 | |||
2165 | name = malloc(PATH_MAX); | ||
2166 | if (!name) | ||
2167 | return -ENOMEM; | ||
2168 | |||
2169 | if (machine) | ||
2170 | root_dir = machine->root_dir; | ||
2171 | |||
2172 | if (dso__binary_type_file(dso, dso->data_type, | ||
2173 | root_dir, name, PATH_MAX)) { | ||
2174 | free(name); | ||
2175 | return -EINVAL; | ||
2176 | } | ||
2177 | |||
2178 | fd = open(name, O_RDONLY); | ||
2179 | free(name); | ||
2180 | return fd; | ||
2181 | } | ||
2182 | |||
2183 | int dso__data_fd(struct dso *dso, struct machine *machine) | ||
2184 | { | ||
2185 | int i = 0; | ||
2186 | |||
2187 | if (dso->data_type != DSO_BINARY_TYPE__NOT_FOUND) | ||
2188 | return open_dso(dso, machine); | ||
2189 | |||
2190 | do { | ||
2191 | int fd; | ||
2192 | |||
2193 | dso->data_type = binary_type_data[i++]; | ||
2194 | |||
2195 | fd = open_dso(dso, machine); | ||
2196 | if (fd >= 0) | ||
2197 | return fd; | ||
2198 | |||
2199 | } while (dso->data_type != DSO_BINARY_TYPE__NOT_FOUND); | ||
2200 | |||
2201 | return -EINVAL; | ||
2202 | } | ||
2203 | |||
2204 | static void | ||
2205 | dso_cache__free(struct rb_root *root) | ||
2206 | { | ||
2207 | struct rb_node *next = rb_first(root); | ||
2208 | |||
2209 | while (next) { | ||
2210 | struct dso_cache *cache; | ||
2211 | |||
2212 | cache = rb_entry(next, struct dso_cache, rb_node); | ||
2213 | next = rb_next(&cache->rb_node); | ||
2214 | rb_erase(&cache->rb_node, root); | ||
2215 | free(cache); | ||
2216 | } | ||
2217 | } | ||
2218 | |||
2219 | static struct dso_cache* | ||
2220 | dso_cache__find(struct rb_root *root, u64 offset) | ||
2221 | { | ||
2222 | struct rb_node **p = &root->rb_node; | ||
2223 | struct rb_node *parent = NULL; | ||
2224 | struct dso_cache *cache; | ||
2225 | |||
2226 | while (*p != NULL) { | ||
2227 | u64 end; | ||
2228 | |||
2229 | parent = *p; | ||
2230 | cache = rb_entry(parent, struct dso_cache, rb_node); | ||
2231 | end = cache->offset + DSO__DATA_CACHE_SIZE; | ||
2232 | |||
2233 | if (offset < cache->offset) | ||
2234 | p = &(*p)->rb_left; | ||
2235 | else if (offset >= end) | ||
2236 | p = &(*p)->rb_right; | ||
2237 | else | ||
2238 | return cache; | ||
2239 | } | ||
2240 | return NULL; | ||
2241 | } | ||
2242 | |||
2243 | static void | ||
2244 | dso_cache__insert(struct rb_root *root, struct dso_cache *new) | ||
2245 | { | ||
2246 | struct rb_node **p = &root->rb_node; | ||
2247 | struct rb_node *parent = NULL; | ||
2248 | struct dso_cache *cache; | ||
2249 | u64 offset = new->offset; | ||
2250 | |||
2251 | while (*p != NULL) { | ||
2252 | u64 end; | ||
2253 | |||
2254 | parent = *p; | ||
2255 | cache = rb_entry(parent, struct dso_cache, rb_node); | ||
2256 | end = cache->offset + DSO__DATA_CACHE_SIZE; | ||
2257 | |||
2258 | if (offset < cache->offset) | ||
2259 | p = &(*p)->rb_left; | ||
2260 | else if (offset >= end) | ||
2261 | p = &(*p)->rb_right; | ||
2262 | } | ||
2263 | |||
2264 | rb_link_node(&new->rb_node, parent, p); | ||
2265 | rb_insert_color(&new->rb_node, root); | ||
2266 | } | ||
2267 | |||
2268 | static ssize_t | ||
2269 | dso_cache__memcpy(struct dso_cache *cache, u64 offset, | ||
2270 | u8 *data, u64 size) | ||
2271 | { | ||
2272 | u64 cache_offset = offset - cache->offset; | ||
2273 | u64 cache_size = min(cache->size - cache_offset, size); | ||
2274 | |||
2275 | memcpy(data, cache->data + cache_offset, cache_size); | ||
2276 | return cache_size; | ||
2277 | } | ||
2278 | |||
2279 | static ssize_t | ||
2280 | dso_cache__read(struct dso *dso, struct machine *machine, | ||
2281 | u64 offset, u8 *data, ssize_t size) | ||
2282 | { | ||
2283 | struct dso_cache *cache; | ||
2284 | ssize_t ret; | ||
2285 | int fd; | ||
2286 | |||
2287 | fd = dso__data_fd(dso, machine); | ||
2288 | if (fd < 0) | ||
2289 | return -1; | ||
2290 | |||
2291 | do { | ||
2292 | u64 cache_offset; | ||
2293 | |||
2294 | ret = -ENOMEM; | ||
2295 | |||
2296 | cache = zalloc(sizeof(*cache) + DSO__DATA_CACHE_SIZE); | ||
2297 | if (!cache) | ||
2298 | break; | ||
2299 | |||
2300 | cache_offset = offset & DSO__DATA_CACHE_MASK; | ||
2301 | ret = -EINVAL; | ||
2302 | |||
2303 | if (-1 == lseek(fd, cache_offset, SEEK_SET)) | ||
2304 | break; | ||
2305 | |||
2306 | ret = read(fd, cache->data, DSO__DATA_CACHE_SIZE); | ||
2307 | if (ret <= 0) | ||
2308 | break; | ||
2309 | |||
2310 | cache->offset = cache_offset; | ||
2311 | cache->size = ret; | ||
2312 | dso_cache__insert(&dso->cache, cache); | ||
2313 | |||
2314 | ret = dso_cache__memcpy(cache, offset, data, size); | ||
2315 | |||
2316 | } while (0); | ||
2317 | |||
2318 | if (ret <= 0) | ||
2319 | free(cache); | ||
2320 | |||
2321 | close(fd); | ||
2322 | return ret; | ||
2323 | } | ||
2324 | |||
2325 | static ssize_t dso_cache_read(struct dso *dso, struct machine *machine, | ||
2326 | u64 offset, u8 *data, ssize_t size) | ||
2327 | { | ||
2328 | struct dso_cache *cache; | ||
2329 | |||
2330 | cache = dso_cache__find(&dso->cache, offset); | ||
2331 | if (cache) | ||
2332 | return dso_cache__memcpy(cache, offset, data, size); | ||
2333 | else | ||
2334 | return dso_cache__read(dso, machine, offset, data, size); | ||
2335 | } | ||
2336 | |||
2337 | ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine, | ||
2338 | u64 offset, u8 *data, ssize_t size) | ||
2339 | { | ||
2340 | ssize_t r = 0; | ||
2341 | u8 *p = data; | ||
2342 | |||
2343 | do { | ||
2344 | ssize_t ret; | ||
2345 | |||
2346 | ret = dso_cache_read(dso, machine, offset, p, size); | ||
2347 | if (ret < 0) | ||
2348 | return ret; | ||
2349 | |||
2350 | /* Reached EOF, return what we have. */ | ||
2351 | if (!ret) | ||
2352 | break; | ||
2353 | |||
2354 | BUG_ON(ret > size); | ||
2355 | |||
2356 | r += ret; | ||
2357 | p += ret; | ||
2358 | offset += ret; | ||
2359 | size -= ret; | ||
2360 | |||
2361 | } while (size); | ||
2362 | |||
2363 | return r; | ||
2364 | } | ||
2365 | |||
2366 | ssize_t dso__data_read_addr(struct dso *dso, struct map *map, | ||
2367 | struct machine *machine, u64 addr, | ||
2368 | u8 *data, ssize_t size) | ||
2369 | { | ||
2370 | u64 offset = map->map_ip(map, addr); | ||
2371 | return dso__data_read_offset(dso, machine, offset, data, size); | ||
2372 | } | ||
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 45d3df8d36d0..863b05bea5ff 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
@@ -19,6 +19,8 @@ | |||
19 | #include <elf.h> | 19 | #include <elf.h> |
20 | #endif | 20 | #endif |
21 | 21 | ||
22 | #include "dso.h" | ||
23 | |||
22 | #ifdef HAVE_CPLUS_DEMANGLE | 24 | #ifdef HAVE_CPLUS_DEMANGLE |
23 | extern char *cplus_demangle(const char *, int); | 25 | extern char *cplus_demangle(const char *, int); |
24 | 26 | ||
@@ -70,6 +72,7 @@ struct symbol { | |||
70 | }; | 72 | }; |
71 | 73 | ||
72 | void symbol__delete(struct symbol *sym); | 74 | void symbol__delete(struct symbol *sym); |
75 | void symbols__delete(struct rb_root *symbols); | ||
73 | 76 | ||
74 | static inline size_t symbol__size(const struct symbol *sym) | 77 | static inline size_t symbol__size(const struct symbol *sym) |
75 | { | 78 | { |
@@ -160,70 +163,6 @@ struct addr_location { | |||
160 | s32 cpu; | 163 | s32 cpu; |
161 | }; | 164 | }; |
162 | 165 | ||
163 | enum dso_binary_type { | ||
164 | DSO_BINARY_TYPE__KALLSYMS = 0, | ||
165 | DSO_BINARY_TYPE__GUEST_KALLSYMS, | ||
166 | DSO_BINARY_TYPE__VMLINUX, | ||
167 | DSO_BINARY_TYPE__GUEST_VMLINUX, | ||
168 | DSO_BINARY_TYPE__JAVA_JIT, | ||
169 | DSO_BINARY_TYPE__DEBUGLINK, | ||
170 | DSO_BINARY_TYPE__BUILD_ID_CACHE, | ||
171 | DSO_BINARY_TYPE__FEDORA_DEBUGINFO, | ||
172 | DSO_BINARY_TYPE__UBUNTU_DEBUGINFO, | ||
173 | DSO_BINARY_TYPE__BUILDID_DEBUGINFO, | ||
174 | DSO_BINARY_TYPE__SYSTEM_PATH_DSO, | ||
175 | DSO_BINARY_TYPE__GUEST_KMODULE, | ||
176 | DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE, | ||
177 | DSO_BINARY_TYPE__NOT_FOUND, | ||
178 | }; | ||
179 | |||
180 | enum dso_kernel_type { | ||
181 | DSO_TYPE_USER = 0, | ||
182 | DSO_TYPE_KERNEL, | ||
183 | DSO_TYPE_GUEST_KERNEL | ||
184 | }; | ||
185 | |||
186 | enum dso_swap_type { | ||
187 | DSO_SWAP__UNSET, | ||
188 | DSO_SWAP__NO, | ||
189 | DSO_SWAP__YES, | ||
190 | }; | ||
191 | |||
192 | #define DSO__DATA_CACHE_SIZE 4096 | ||
193 | #define DSO__DATA_CACHE_MASK ~(DSO__DATA_CACHE_SIZE - 1) | ||
194 | |||
195 | struct dso_cache { | ||
196 | struct rb_node rb_node; | ||
197 | u64 offset; | ||
198 | u64 size; | ||
199 | char data[0]; | ||
200 | }; | ||
201 | |||
202 | struct dso { | ||
203 | struct list_head node; | ||
204 | struct rb_root symbols[MAP__NR_TYPES]; | ||
205 | struct rb_root symbol_names[MAP__NR_TYPES]; | ||
206 | struct rb_root cache; | ||
207 | enum dso_kernel_type kernel; | ||
208 | enum dso_swap_type needs_swap; | ||
209 | enum dso_binary_type symtab_type; | ||
210 | enum dso_binary_type data_type; | ||
211 | u8 adjust_symbols:1; | ||
212 | u8 has_build_id:1; | ||
213 | u8 hit:1; | ||
214 | u8 annotate_warned:1; | ||
215 | u8 sname_alloc:1; | ||
216 | u8 lname_alloc:1; | ||
217 | u8 sorted_by_name; | ||
218 | u8 loaded; | ||
219 | u8 build_id[BUILD_ID_SIZE]; | ||
220 | const char *short_name; | ||
221 | char *long_name; | ||
222 | u16 long_name_len; | ||
223 | u16 short_name_len; | ||
224 | char name[0]; | ||
225 | }; | ||
226 | |||
227 | struct symsrc { | 166 | struct symsrc { |
228 | char *name; | 167 | char *name; |
229 | int fd; | 168 | int fd; |
@@ -254,47 +193,6 @@ int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name, | |||
254 | bool symsrc__has_symtab(struct symsrc *ss); | 193 | bool symsrc__has_symtab(struct symsrc *ss); |
255 | bool symsrc__possibly_runtime(struct symsrc *ss); | 194 | bool symsrc__possibly_runtime(struct symsrc *ss); |
256 | 195 | ||
257 | #define DSO__SWAP(dso, type, val) \ | ||
258 | ({ \ | ||
259 | type ____r = val; \ | ||
260 | BUG_ON(dso->needs_swap == DSO_SWAP__UNSET); \ | ||
261 | if (dso->needs_swap == DSO_SWAP__YES) { \ | ||
262 | switch (sizeof(____r)) { \ | ||
263 | case 2: \ | ||
264 | ____r = bswap_16(val); \ | ||
265 | break; \ | ||
266 | case 4: \ | ||
267 | ____r = bswap_32(val); \ | ||
268 | break; \ | ||
269 | case 8: \ | ||
270 | ____r = bswap_64(val); \ | ||
271 | break; \ | ||
272 | default: \ | ||
273 | BUG_ON(1); \ | ||
274 | } \ | ||
275 | } \ | ||
276 | ____r; \ | ||
277 | }) | ||
278 | |||
279 | struct dso *dso__new(const char *name); | ||
280 | void dso__delete(struct dso *dso); | ||
281 | |||
282 | int dso__name_len(const struct dso *dso); | ||
283 | |||
284 | bool dso__loaded(const struct dso *dso, enum map_type type); | ||
285 | bool dso__sorted_by_name(const struct dso *dso, enum map_type type); | ||
286 | |||
287 | static inline void dso__set_loaded(struct dso *dso, enum map_type type) | ||
288 | { | ||
289 | dso->loaded |= (1 << type); | ||
290 | } | ||
291 | |||
292 | void dso__sort_by_name(struct dso *dso, enum map_type type); | ||
293 | |||
294 | void dsos__add(struct list_head *head, struct dso *dso); | ||
295 | struct dso *dsos__find(struct list_head *head, const char *name); | ||
296 | struct dso *__dsos__findnew(struct list_head *head, const char *name); | ||
297 | |||
298 | int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter); | 196 | int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter); |
299 | int dso__load_vmlinux(struct dso *dso, struct map *map, | 197 | int dso__load_vmlinux(struct dso *dso, struct map *map, |
300 | const char *vmlinux, symbol_filter_t filter); | 198 | const char *vmlinux, symbol_filter_t filter); |
@@ -307,25 +205,12 @@ int machine__load_kallsyms(struct machine *machine, const char *filename, | |||
307 | int machine__load_vmlinux_path(struct machine *machine, enum map_type type, | 205 | int machine__load_vmlinux_path(struct machine *machine, enum map_type type, |
308 | symbol_filter_t filter); | 206 | symbol_filter_t filter); |
309 | 207 | ||
310 | size_t __dsos__fprintf(struct list_head *head, FILE *fp); | ||
311 | |||
312 | size_t machine__fprintf_dsos_buildid(struct machine *machine, | 208 | size_t machine__fprintf_dsos_buildid(struct machine *machine, |
313 | FILE *fp, bool with_hits); | 209 | FILE *fp, bool with_hits); |
314 | size_t machines__fprintf_dsos(struct rb_root *machines, FILE *fp); | 210 | size_t machines__fprintf_dsos(struct rb_root *machines, FILE *fp); |
315 | size_t machines__fprintf_dsos_buildid(struct rb_root *machines, | 211 | size_t machines__fprintf_dsos_buildid(struct rb_root *machines, |
316 | FILE *fp, bool with_hits); | 212 | FILE *fp, bool with_hits); |
317 | size_t dso__fprintf_buildid(struct dso *dso, FILE *fp); | 213 | |
318 | size_t dso__fprintf_symbols_by_name(struct dso *dso, | ||
319 | enum map_type type, FILE *fp); | ||
320 | size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp); | ||
321 | |||
322 | char dso__symtab_origin(const struct dso *dso); | ||
323 | void dso__set_long_name(struct dso *dso, char *name); | ||
324 | void dso__set_build_id(struct dso *dso, void *build_id); | ||
325 | bool dso__build_id_equal(const struct dso *dso, u8 *build_id); | ||
326 | void dso__read_running_kernel_build_id(struct dso *dso, | ||
327 | struct machine *machine); | ||
328 | struct map *dso__new_map(const char *name); | ||
329 | struct symbol *dso__find_symbol(struct dso *dso, enum map_type type, | 214 | struct symbol *dso__find_symbol(struct dso *dso, enum map_type type, |
330 | u64 addr); | 215 | u64 addr); |
331 | struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type, | 216 | struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type, |
@@ -333,7 +218,6 @@ struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type, | |||
333 | 218 | ||
334 | int filename__read_build_id(const char *filename, void *bf, size_t size); | 219 | int filename__read_build_id(const char *filename, void *bf, size_t size); |
335 | int sysfs__read_build_id(const char *filename, void *bf, size_t size); | 220 | int sysfs__read_build_id(const char *filename, void *bf, size_t size); |
336 | bool __dsos__read_build_ids(struct list_head *head, bool with_hits); | ||
337 | int kallsyms__parse(const char *filename, void *arg, | 221 | int kallsyms__parse(const char *filename, void *arg, |
338 | int (*process_symbol)(void *arg, const char *name, | 222 | int (*process_symbol)(void *arg, const char *name, |
339 | char type, u64 start)); | 223 | char type, u64 start)); |
@@ -355,19 +239,11 @@ struct symbol *symbol__new(u64 start, u64 len, u8 binding, const char *name); | |||
355 | size_t symbol__fprintf_symname_offs(const struct symbol *sym, | 239 | size_t symbol__fprintf_symname_offs(const struct symbol *sym, |
356 | const struct addr_location *al, FILE *fp); | 240 | const struct addr_location *al, FILE *fp); |
357 | size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp); | 241 | size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp); |
242 | size_t symbol__fprintf(struct symbol *sym, FILE *fp); | ||
358 | bool symbol_type__is_a(char symbol_type, enum map_type map_type); | 243 | bool symbol_type__is_a(char symbol_type, enum map_type map_type); |
359 | 244 | ||
360 | size_t machine__fprintf_vmlinux_path(struct machine *machine, FILE *fp); | 245 | size_t machine__fprintf_vmlinux_path(struct machine *machine, FILE *fp); |
361 | 246 | ||
362 | int dso__binary_type_file(struct dso *dso, enum dso_binary_type type, | ||
363 | char *root_dir, char *file, size_t size); | ||
364 | |||
365 | int dso__data_fd(struct dso *dso, struct machine *machine); | ||
366 | ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine, | ||
367 | u64 offset, u8 *data, ssize_t size); | ||
368 | ssize_t dso__data_read_addr(struct dso *dso, struct map *map, | ||
369 | struct machine *machine, u64 addr, | ||
370 | u8 *data, ssize_t size); | ||
371 | int dso__test_data(void); | 247 | int dso__test_data(void); |
372 | int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, | 248 | int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, |
373 | struct symsrc *runtime_ss, symbol_filter_t filter, | 249 | struct symsrc *runtime_ss, symbol_filter_t filter, |