1 #include "unwind.h"
2 #include "thread.h"
3 #include "session.h"
4 #include "debug.h"
5 #include "arch/common.h"
6 
7 struct unwind_libunwind_ops __weak *local_unwind_libunwind_ops;
8 
9 static void unwind__register_ops(struct thread *thread,
10 			  struct unwind_libunwind_ops *ops)
11 {
12 	thread->unwind_libunwind_ops = ops;
13 }
14 
15 int unwind__prepare_access(struct thread *thread, struct map *map)
16 {
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);
36 out_register:
37 	unwind__register_ops(thread, local_unwind_libunwind_ops);
38 
39 	return thread->unwind_libunwind_ops->prepare_access(thread);
40 }
41 
42 void unwind__flush_access(struct thread *thread)
43 {
44 	if (thread->unwind_libunwind_ops)
45 		thread->unwind_libunwind_ops->flush_access(thread);
46 }
47 
48 void unwind__finish_access(struct thread *thread)
49 {
50 	if (thread->unwind_libunwind_ops)
51 		thread->unwind_libunwind_ops->finish_access(thread);
52 }
53 
54 int 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 }
62