blob: 0086726e00e018d3815ae7dd17fd3a33e94b1e35 [file] [log] [blame]
He Kuangf6d72532016-06-03 03:33:17 +00001#include "unwind.h"
2#include "thread.h"
He Kuangd64ec102016-06-03 03:33:19 +00003#include "session.h"
4#include "debug.h"
5#include "arch/common.h"
He Kuangf6d72532016-06-03 03:33:17 +00006
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
He Kuangd64ec102016-06-03 03:33:19 +000015int unwind__prepare_access(struct thread *thread, struct map *map)
He Kuangf6d72532016-06-03 03:33:17 +000016{
He Kuangd64ec102016-06-03 03:33:19 +000017 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:
He Kuangf6d72532016-06-03 03:33:17 +000037 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}