perf unwind: Check the target platform before assigning unwind methods
[linux-2.6-block.git] / tools / perf / util / unwind-libunwind.c
CommitLineData
f6d72532
HK
1#include "unwind.h"
2#include "thread.h"
d64ec10e
HK
3#include "session.h"
4#include "debug.h"
5#include "arch/common.h"
f6d72532
HK
6
7struct unwind_libunwind_ops __weak *local_unwind_libunwind_ops;
8
9static void unwind__register_ops(struct thread *thread,
10 struct unwind_libunwind_ops *ops)
11{
12 thread->unwind_libunwind_ops = ops;
13}
14
d64ec10e 15int unwind__prepare_access(struct thread *thread, struct map *map)
f6d72532 16{
d64ec10e
HK
17 const char *arch;
18 enum dso_type dso_type;
19
20 if (thread->addr_space) {
21 pr_debug("unwind: thread map already set, dso=%s\n",
22 map->dso->name);
23 return 0;
24 }
25
26 /* env->arch is NULL for live-mode (i.e. perf top) */
27 if (!thread->mg->machine->env || !thread->mg->machine->env->arch)
28 goto out_register;
29
30 dso_type = dso__type(map->dso, thread->mg->machine);
31 if (dso_type == DSO__TYPE_UNKNOWN)
32 return 0;
33
34 arch = normalize_arch(thread->mg->machine->env->arch);
35 pr_debug("unwind: target platform=%s\n", arch);
36out_register:
f6d72532
HK
37 unwind__register_ops(thread, local_unwind_libunwind_ops);
38
39 return thread->unwind_libunwind_ops->prepare_access(thread);
40}
41
42void unwind__flush_access(struct thread *thread)
43{
44 if (thread->unwind_libunwind_ops)
45 thread->unwind_libunwind_ops->flush_access(thread);
46}
47
48void unwind__finish_access(struct thread *thread)
49{
50 if (thread->unwind_libunwind_ops)
51 thread->unwind_libunwind_ops->finish_access(thread);
52}
53
54int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
55 struct thread *thread,
56 struct perf_sample *data, int max_stack)
57{
58 if (thread->unwind_libunwind_ops)
59 return thread->unwind_libunwind_ops->get_entries(cb, arg, thread, data, max_stack);
60 return 0;
61}