5 #include "arch/common.h"
7 struct unwind_libunwind_ops __weak
*local_unwind_libunwind_ops
;
8 struct unwind_libunwind_ops __weak
*x86_32_unwind_libunwind_ops
;
9 struct unwind_libunwind_ops __weak
*arm64_unwind_libunwind_ops
;
11 static void unwind__register_ops(struct thread
*thread
,
12 struct unwind_libunwind_ops
*ops
)
14 thread
->unwind_libunwind_ops
= ops
;
17 int unwind__prepare_access(struct thread
*thread
, struct map
*map
,
21 enum dso_type dso_type
;
22 struct unwind_libunwind_ops
*ops
= local_unwind_libunwind_ops
;
25 if (thread
->addr_space
) {
26 pr_debug("unwind: thread map already set, dso=%s\n",
33 /* env->arch is NULL for live-mode (i.e. perf top) */
34 if (!thread
->mg
->machine
->env
|| !thread
->mg
->machine
->env
->arch
)
37 dso_type
= dso__type(map
->dso
, thread
->mg
->machine
);
38 if (dso_type
== DSO__TYPE_UNKNOWN
)
41 arch
= normalize_arch(thread
->mg
->machine
->env
->arch
);
43 if (!strcmp(arch
, "x86")) {
44 if (dso_type
!= DSO__TYPE_64BIT
)
45 ops
= x86_32_unwind_libunwind_ops
;
46 } else if (!strcmp(arch
, "arm64") || !strcmp(arch
, "arm")) {
47 if (dso_type
== DSO__TYPE_64BIT
)
48 ops
= arm64_unwind_libunwind_ops
;
52 pr_err("unwind: target platform=%s is not supported\n", arch
);
56 unwind__register_ops(thread
, ops
);
58 err
= thread
->unwind_libunwind_ops
->prepare_access(thread
);
60 *initialized
= err
? false : true;
64 void unwind__flush_access(struct thread
*thread
)
66 if (thread
->unwind_libunwind_ops
)
67 thread
->unwind_libunwind_ops
->flush_access(thread
);
70 void unwind__finish_access(struct thread
*thread
)
72 if (thread
->unwind_libunwind_ops
)
73 thread
->unwind_libunwind_ops
->finish_access(thread
);
76 int unwind__get_entries(unwind_entry_cb_t cb
, void *arg
,
77 struct thread
*thread
,
78 struct perf_sample
*data
, int max_stack
)
80 if (thread
->unwind_libunwind_ops
)
81 return thread
->unwind_libunwind_ops
->get_entries(cb
, arg
, thread
, data
, max_stack
);