Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.10 83 lines 2.2 kB view raw
1#include "unwind.h" 2#include "thread.h" 3#include "session.h" 4#include "debug.h" 5#include "arch/common.h" 6 7struct unwind_libunwind_ops __weak *local_unwind_libunwind_ops; 8struct unwind_libunwind_ops __weak *x86_32_unwind_libunwind_ops; 9struct unwind_libunwind_ops __weak *arm64_unwind_libunwind_ops; 10 11static void unwind__register_ops(struct thread *thread, 12 struct unwind_libunwind_ops *ops) 13{ 14 thread->unwind_libunwind_ops = ops; 15} 16 17int unwind__prepare_access(struct thread *thread, struct map *map, 18 bool *initialized) 19{ 20 const char *arch; 21 enum dso_type dso_type; 22 struct unwind_libunwind_ops *ops = local_unwind_libunwind_ops; 23 int err; 24 25 if (thread->addr_space) { 26 pr_debug("unwind: thread map already set, dso=%s\n", 27 map->dso->name); 28 if (initialized) 29 *initialized = true; 30 return 0; 31 } 32 33 /* env->arch is NULL for live-mode (i.e. perf top) */ 34 if (!thread->mg->machine->env || !thread->mg->machine->env->arch) 35 goto out_register; 36 37 dso_type = dso__type(map->dso, thread->mg->machine); 38 if (dso_type == DSO__TYPE_UNKNOWN) 39 return 0; 40 41 arch = normalize_arch(thread->mg->machine->env->arch); 42 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; 49 } 50 51 if (!ops) { 52 pr_err("unwind: target platform=%s is not supported\n", arch); 53 return -1; 54 } 55out_register: 56 unwind__register_ops(thread, ops); 57 58 err = thread->unwind_libunwind_ops->prepare_access(thread); 59 if (initialized) 60 *initialized = err ? false : true; 61 return err; 62} 63 64void unwind__flush_access(struct thread *thread) 65{ 66 if (thread->unwind_libunwind_ops) 67 thread->unwind_libunwind_ops->flush_access(thread); 68} 69 70void unwind__finish_access(struct thread *thread) 71{ 72 if (thread->unwind_libunwind_ops) 73 thread->unwind_libunwind_ops->finish_access(thread); 74} 75 76int unwind__get_entries(unwind_entry_cb_t cb, void *arg, 77 struct thread *thread, 78 struct perf_sample *data, int max_stack) 79{ 80 if (thread->unwind_libunwind_ops) 81 return thread->unwind_libunwind_ops->get_entries(cb, arg, thread, data, max_stack); 82 return 0; 83}