Linux Audio

Check our new training course

Loading...
v6.8
 1// SPDX-License-Identifier: GPL-2.0
 2#include "unwind.h"
 3#include "dso.h"
 4#include "map.h"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 5#include "thread.h"
 6#include "session.h"
 
 
 
 
 7#include "debug.h"
 8#include "env.h"
 9#include "callchain.h"
10
11struct unwind_libunwind_ops __weak *local_unwind_libunwind_ops;
12struct unwind_libunwind_ops __weak *x86_32_unwind_libunwind_ops;
13struct unwind_libunwind_ops __weak *arm64_unwind_libunwind_ops;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
15static void unwind__register_ops(struct maps *maps, struct unwind_libunwind_ops *ops)
 
 
 
 
16{
17	RC_CHK_ACCESS(maps)->unwind_libunwind_ops = ops;
 
18}
19
20int unwind__prepare_access(struct maps *maps, struct map *map, bool *initialized)
 
21{
22	const char *arch;
23	enum dso_type dso_type;
24	struct unwind_libunwind_ops *ops = local_unwind_libunwind_ops;
25	struct dso *dso = map__dso(map);
26	struct machine *machine;
27	int err;
 
 
 
 
 
 
 
 
28
29	if (!dwarf_callchain_users)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30		return 0;
 
31
32	if (maps__addr_space(maps)) {
33		pr_debug("unwind: thread map already set, dso=%s\n", dso->name);
34		if (initialized)
35			*initialized = true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36		return 0;
37	}
38
39	machine = maps__machine(maps);
40	/* env->arch is NULL for live-mode (i.e. perf top) */
41	if (!machine->env || !machine->env->arch)
42		goto out_register;
 
 
43
44	dso_type = dso__type(dso, machine);
45	if (dso_type == DSO__TYPE_UNKNOWN)
 
 
 
 
 
 
 
 
 
46		return 0;
 
47
48	arch = perf_env__arch(machine->env);
 
 
 
49
50	if (!strcmp(arch, "x86")) {
51		if (dso_type != DSO__TYPE_64BIT)
52			ops = x86_32_unwind_libunwind_ops;
53	} else if (!strcmp(arch, "arm64") || !strcmp(arch, "arm")) {
54		if (dso_type == DSO__TYPE_64BIT)
55			ops = arm64_unwind_libunwind_ops;
 
 
56	}
57
58	if (!ops) {
59		pr_warning_once("unwind: target platform=%s is not supported\n", arch);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60		return 0;
 
 
 
 
 
61	}
62out_register:
63	unwind__register_ops(maps, ops);
64
65	err = maps__unwind_libunwind_ops(maps)->prepare_access(maps);
66	if (initialized)
67		*initialized = err ? false : true;
68	return err;
69}
70
71void unwind__flush_access(struct maps *maps)
72{
73	const struct unwind_libunwind_ops *ops = maps__unwind_libunwind_ops(maps);
74
75	if (ops)
76		ops->flush_access(maps);
 
 
 
77}
78
79void unwind__finish_access(struct maps *maps)
80{
81	const struct unwind_libunwind_ops *ops = maps__unwind_libunwind_ops(maps);
 
 
 
82
83	if (ops)
84		ops->finish_access(maps);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85}
86
87int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
88			 struct thread *thread,
89			 struct perf_sample *data, int max_stack,
90			 bool best_effort)
91{
92	const struct unwind_libunwind_ops *ops = maps__unwind_libunwind_ops(thread__maps(thread));
 
 
 
 
93
94	if (ops)
95		return ops->get_entries(cb, arg, thread, data, max_stack, best_effort);
96	return 0;
 
 
 
 
97}
v4.6
  1/*
  2 * Post mortem Dwarf CFI based unwinding on top of regs and stack dumps.
  3 *
  4 * Lots of this code have been borrowed or heavily inspired from parts of
  5 * the libunwind 0.99 code which are (amongst other contributors I may have
  6 * forgotten):
  7 *
  8 * Copyright (C) 2002-2007 Hewlett-Packard Co
  9 *	Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
 10 *
 11 * And the bugs have been added by:
 12 *
 13 * Copyright (C) 2010, Frederic Weisbecker <fweisbec@gmail.com>
 14 * Copyright (C) 2012, Jiri Olsa <jolsa@redhat.com>
 15 *
 16 */
 17
 18#include <elf.h>
 19#include <gelf.h>
 20#include <fcntl.h>
 21#include <string.h>
 22#include <unistd.h>
 23#include <sys/mman.h>
 24#include <linux/list.h>
 25#include <libunwind.h>
 26#include <libunwind-ptrace.h>
 27#include "callchain.h"
 28#include "thread.h"
 29#include "session.h"
 30#include "perf_regs.h"
 31#include "unwind.h"
 32#include "symbol.h"
 33#include "util.h"
 34#include "debug.h"
 
 
 35
 36extern int
 37UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
 38				    unw_word_t ip,
 39				    unw_dyn_info_t *di,
 40				    unw_proc_info_t *pi,
 41				    int need_unwind_info, void *arg);
 42
 43#define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table)
 44
 45extern int
 46UNW_OBJ(dwarf_find_debug_frame) (int found, unw_dyn_info_t *di_debug,
 47				 unw_word_t ip,
 48				 unw_word_t segbase,
 49				 const char *obj_name, unw_word_t start,
 50				 unw_word_t end);
 51
 52#define dwarf_find_debug_frame UNW_OBJ(dwarf_find_debug_frame)
 53
 54#define DW_EH_PE_FORMAT_MASK	0x0f	/* format of the encoded value */
 55#define DW_EH_PE_APPL_MASK	0x70	/* how the value is to be applied */
 56
 57/* Pointer-encoding formats: */
 58#define DW_EH_PE_omit		0xff
 59#define DW_EH_PE_ptr		0x00	/* pointer-sized unsigned value */
 60#define DW_EH_PE_udata4		0x03	/* unsigned 32-bit value */
 61#define DW_EH_PE_udata8		0x04	/* unsigned 64-bit value */
 62#define DW_EH_PE_sdata4		0x0b	/* signed 32-bit value */
 63#define DW_EH_PE_sdata8		0x0c	/* signed 64-bit value */
 64
 65/* Pointer-encoding application: */
 66#define DW_EH_PE_absptr		0x00	/* absolute value */
 67#define DW_EH_PE_pcrel		0x10	/* rel. to addr. of encoded value */
 68
 69/*
 70 * The following are not documented by LSB v1.3, yet they are used by
 71 * GCC, presumably they aren't documented by LSB since they aren't
 72 * used on Linux:
 73 */
 74#define DW_EH_PE_funcrel	0x40	/* start-of-procedure-relative */
 75#define DW_EH_PE_aligned	0x50	/* aligned pointer */
 76
 77/* Flags intentionaly not handled, since they're not needed:
 78 * #define DW_EH_PE_indirect      0x80
 79 * #define DW_EH_PE_uleb128       0x01
 80 * #define DW_EH_PE_udata2        0x02
 81 * #define DW_EH_PE_sleb128       0x09
 82 * #define DW_EH_PE_sdata2        0x0a
 83 * #define DW_EH_PE_textrel       0x20
 84 * #define DW_EH_PE_datarel       0x30
 85 */
 86
 87struct unwind_info {
 88	struct perf_sample	*sample;
 89	struct machine		*machine;
 90	struct thread		*thread;
 91};
 92
 93#define dw_read(ptr, type, end) ({	\
 94	type *__p = (type *) ptr;	\
 95	type  __v;			\
 96	if ((__p + 1) > (type *) end)	\
 97		return -EINVAL;		\
 98	__v = *__p++;			\
 99	ptr = (typeof(ptr)) __p;	\
100	__v;				\
101	})
102
103static int __dw_read_encoded_value(u8 **p, u8 *end, u64 *val,
104				   u8 encoding)
105{
106	u8 *cur = *p;
107	*val = 0;
108
109	switch (encoding) {
110	case DW_EH_PE_omit:
111		*val = 0;
112		goto out;
113	case DW_EH_PE_ptr:
114		*val = dw_read(cur, unsigned long, end);
115		goto out;
116	default:
117		break;
118	}
119
120	switch (encoding & DW_EH_PE_APPL_MASK) {
121	case DW_EH_PE_absptr:
122		break;
123	case DW_EH_PE_pcrel:
124		*val = (unsigned long) cur;
125		break;
126	default:
127		return -EINVAL;
128	}
129
130	if ((encoding & 0x07) == 0x00)
131		encoding |= DW_EH_PE_udata4;
132
133	switch (encoding & DW_EH_PE_FORMAT_MASK) {
134	case DW_EH_PE_sdata4:
135		*val += dw_read(cur, s32, end);
136		break;
137	case DW_EH_PE_udata4:
138		*val += dw_read(cur, u32, end);
139		break;
140	case DW_EH_PE_sdata8:
141		*val += dw_read(cur, s64, end);
142		break;
143	case DW_EH_PE_udata8:
144		*val += dw_read(cur, u64, end);
145		break;
146	default:
147		return -EINVAL;
148	}
149
150 out:
151	*p = cur;
152	return 0;
153}
154
155#define dw_read_encoded_value(ptr, end, enc) ({			\
156	u64 __v;						\
157	if (__dw_read_encoded_value(&ptr, end, &__v, enc)) {	\
158		return -EINVAL;                                 \
159	}                                                       \
160	__v;                                                    \
161	})
162
163static u64 elf_section_offset(int fd, const char *name)
164{
165	Elf *elf;
166	GElf_Ehdr ehdr;
167	GElf_Shdr shdr;
168	u64 offset = 0;
169
170	elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
171	if (elf == NULL)
172		return 0;
173
174	do {
175		if (gelf_getehdr(elf, &ehdr) == NULL)
176			break;
177
178		if (!elf_section_by_name(elf, &ehdr, &shdr, name, NULL))
179			break;
180
181		offset = shdr.sh_offset;
182	} while (0);
183
184	elf_end(elf);
185	return offset;
186}
187
188#ifndef NO_LIBUNWIND_DEBUG_FRAME
189static int elf_is_exec(int fd, const char *name)
190{
191	Elf *elf;
192	GElf_Ehdr ehdr;
193	int retval = 0;
194
195	elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
196	if (elf == NULL)
197		return 0;
198	if (gelf_getehdr(elf, &ehdr) == NULL)
199		goto out;
200
201	retval = (ehdr.e_type == ET_EXEC);
202
203out:
204	elf_end(elf);
205	pr_debug("unwind: elf_is_exec(%s): %d\n", name, retval);
206	return retval;
207}
208#endif
209
210struct table_entry {
211	u32 start_ip_offset;
212	u32 fde_offset;
213};
214
215struct eh_frame_hdr {
216	unsigned char version;
217	unsigned char eh_frame_ptr_enc;
218	unsigned char fde_count_enc;
219	unsigned char table_enc;
220
221	/*
222	 * The rest of the header is variable-length and consists of the
223	 * following members:
224	 *
225	 *	encoded_t eh_frame_ptr;
226	 *	encoded_t fde_count;
227	 */
228
229	/* A single encoded pointer should not be more than 8 bytes. */
230	u64 enc[2];
231
232	/*
233	 * struct {
234	 *    encoded_t start_ip;
235	 *    encoded_t fde_addr;
236	 * } binary_search_table[fde_count];
237	 */
238	char data[0];
239} __packed;
240
241static int unwind_spec_ehframe(struct dso *dso, struct machine *machine,
242			       u64 offset, u64 *table_data, u64 *segbase,
243			       u64 *fde_count)
244{
245	struct eh_frame_hdr hdr;
246	u8 *enc = (u8 *) &hdr.enc;
247	u8 *end = (u8 *) &hdr.data;
248	ssize_t r;
249
250	r = dso__data_read_offset(dso, machine, offset,
251				  (u8 *) &hdr, sizeof(hdr));
252	if (r != sizeof(hdr))
253		return -EINVAL;
254
255	/* We dont need eh_frame_ptr, just skip it. */
256	dw_read_encoded_value(enc, end, hdr.eh_frame_ptr_enc);
257
258	*fde_count  = dw_read_encoded_value(enc, end, hdr.fde_count_enc);
259	*segbase    = offset;
260	*table_data = (enc - (u8 *) &hdr) + offset;
261	return 0;
262}
263
264static int read_unwind_spec_eh_frame(struct dso *dso, struct machine *machine,
265				     u64 *table_data, u64 *segbase,
266				     u64 *fde_count)
267{
268	int ret = -EINVAL, fd;
269	u64 offset = dso->data.eh_frame_hdr_offset;
270
271	if (offset == 0) {
272		fd = dso__data_get_fd(dso, machine);
273		if (fd < 0)
274			return -EINVAL;
275
276		/* Check the .eh_frame section for unwinding info */
277		offset = elf_section_offset(fd, ".eh_frame_hdr");
278		dso->data.eh_frame_hdr_offset = offset;
279		dso__data_put_fd(dso);
280	}
281
282	if (offset)
283		ret = unwind_spec_ehframe(dso, machine, offset,
284					  table_data, segbase,
285					  fde_count);
286
287	return ret;
288}
289
290#ifndef NO_LIBUNWIND_DEBUG_FRAME
291static int read_unwind_spec_debug_frame(struct dso *dso,
292					struct machine *machine, u64 *offset)
293{
294	int fd;
295	u64 ofs = dso->data.debug_frame_offset;
296
297	if (ofs == 0) {
298		fd = dso__data_get_fd(dso, machine);
299		if (fd < 0)
300			return -EINVAL;
301
302		/* Check the .debug_frame section for unwinding info */
303		ofs = elf_section_offset(fd, ".debug_frame");
304		dso->data.debug_frame_offset = ofs;
305		dso__data_put_fd(dso);
306	}
307
308	*offset = ofs;
309	if (*offset)
310		return 0;
311
312	return -EINVAL;
313}
314#endif
315
316static struct map *find_map(unw_word_t ip, struct unwind_info *ui)
317{
318	struct addr_location al;
319
320	thread__find_addr_map(ui->thread, PERF_RECORD_MISC_USER,
321			      MAP__FUNCTION, ip, &al);
322	if (!al.map) {
323		/*
324		 * We've seen cases (softice) where DWARF unwinder went
325		 * through non executable mmaps, which we need to lookup
326		 * in MAP__VARIABLE tree.
327		 */
328		thread__find_addr_map(ui->thread, PERF_RECORD_MISC_USER,
329				      MAP__VARIABLE, ip, &al);
330	}
331	return al.map;
332}
333
334static int
335find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
336	       int need_unwind_info, void *arg)
337{
338	struct unwind_info *ui = arg;
339	struct map *map;
340	unw_dyn_info_t di;
341	u64 table_data, segbase, fde_count;
342	int ret = -EINVAL;
343
344	map = find_map(ip, ui);
345	if (!map || !map->dso)
346		return -EINVAL;
347
348	pr_debug("unwind: find_proc_info dso %s\n", map->dso->name);
349
350	/* Check the .eh_frame section for unwinding info */
351	if (!read_unwind_spec_eh_frame(map->dso, ui->machine,
352				       &table_data, &segbase, &fde_count)) {
353		memset(&di, 0, sizeof(di));
354		di.format   = UNW_INFO_FORMAT_REMOTE_TABLE;
355		di.start_ip = map->start;
356		di.end_ip   = map->end;
357		di.u.rti.segbase    = map->start + segbase;
358		di.u.rti.table_data = map->start + table_data;
359		di.u.rti.table_len  = fde_count * sizeof(struct table_entry)
360				      / sizeof(unw_word_t);
361		ret = dwarf_search_unwind_table(as, ip, &di, pi,
362						need_unwind_info, arg);
363	}
364
365#ifndef NO_LIBUNWIND_DEBUG_FRAME
366	/* Check the .debug_frame section for unwinding info */
367	if (ret < 0 &&
368	    !read_unwind_spec_debug_frame(map->dso, ui->machine, &segbase)) {
369		int fd = dso__data_get_fd(map->dso, ui->machine);
370		int is_exec = elf_is_exec(fd, map->dso->name);
371		unw_word_t base = is_exec ? 0 : map->start;
372		const char *symfile;
373
374		if (fd >= 0)
375			dso__data_put_fd(map->dso);
376
377		symfile = map->dso->symsrc_filename ?: map->dso->name;
378
379		memset(&di, 0, sizeof(di));
380		if (dwarf_find_debug_frame(0, &di, ip, base, symfile,
381					   map->start, map->end))
382			return dwarf_search_unwind_table(as, ip, &di, pi,
383							 need_unwind_info, arg);
384	}
385#endif
386
387	return ret;
388}
389
390static int access_fpreg(unw_addr_space_t __maybe_unused as,
391			unw_regnum_t __maybe_unused num,
392			unw_fpreg_t __maybe_unused *val,
393			int __maybe_unused __write,
394			void __maybe_unused *arg)
395{
396	pr_err("unwind: access_fpreg unsupported\n");
397	return -UNW_EINVAL;
398}
399
400static int get_dyn_info_list_addr(unw_addr_space_t __maybe_unused as,
401				  unw_word_t __maybe_unused *dil_addr,
402				  void __maybe_unused *arg)
403{
404	return -UNW_ENOINFO;
405}
406
407static int resume(unw_addr_space_t __maybe_unused as,
408		  unw_cursor_t __maybe_unused *cu,
409		  void __maybe_unused *arg)
410{
411	pr_err("unwind: resume unsupported\n");
412	return -UNW_EINVAL;
413}
414
415static int
416get_proc_name(unw_addr_space_t __maybe_unused as,
417	      unw_word_t __maybe_unused addr,
418		char __maybe_unused *bufp, size_t __maybe_unused buf_len,
419		unw_word_t __maybe_unused *offp, void __maybe_unused *arg)
420{
421	pr_err("unwind: get_proc_name unsupported\n");
422	return -UNW_EINVAL;
423}
424
425static int access_dso_mem(struct unwind_info *ui, unw_word_t addr,
426			  unw_word_t *data)
427{
428	struct map *map;
429	ssize_t size;
430
431	map = find_map(addr, ui);
432	if (!map) {
433		pr_debug("unwind: no map for %lx\n", (unsigned long)addr);
434		return -1;
435	}
436
437	if (!map->dso)
438		return -1;
439
440	size = dso__data_read_addr(map->dso, map, ui->machine,
441				   addr, (u8 *) data, sizeof(*data));
442
443	return !(size == sizeof(*data));
444}
445
446static int access_mem(unw_addr_space_t __maybe_unused as,
447		      unw_word_t addr, unw_word_t *valp,
448		      int __write, void *arg)
449{
450	struct unwind_info *ui = arg;
451	struct stack_dump *stack = &ui->sample->user_stack;
452	u64 start, end;
453	int offset;
454	int ret;
455
456	/* Don't support write, probably not needed. */
457	if (__write || !stack || !ui->sample->user_regs.regs) {
458		*valp = 0;
459		return 0;
460	}
461
462	ret = perf_reg_value(&start, &ui->sample->user_regs, PERF_REG_SP);
463	if (ret)
464		return ret;
465
466	end = start + stack->size;
467
468	/* Check overflow. */
469	if (addr + sizeof(unw_word_t) < addr)
470		return -EINVAL;
471
472	if (addr < start || addr + sizeof(unw_word_t) >= end) {
473		ret = access_dso_mem(ui, addr, valp);
474		if (ret) {
475			pr_debug("unwind: access_mem %p not inside range"
476				 " 0x%" PRIx64 "-0x%" PRIx64 "\n",
477				 (void *) (uintptr_t) addr, start, end);
478			*valp = 0;
479			return ret;
480		}
481		return 0;
482	}
483
484	offset = addr - start;
485	*valp  = *(unw_word_t *)&stack->data[offset];
486	pr_debug("unwind: access_mem addr %p val %lx, offset %d\n",
487		 (void *) (uintptr_t) addr, (unsigned long)*valp, offset);
488	return 0;
489}
490
491static int access_reg(unw_addr_space_t __maybe_unused as,
492		      unw_regnum_t regnum, unw_word_t *valp,
493		      int __write, void *arg)
494{
495	struct unwind_info *ui = arg;
496	int id, ret;
497	u64 val;
498
499	/* Don't support write, I suspect we don't need it. */
500	if (__write) {
501		pr_err("unwind: access_reg w %d\n", regnum);
502		return 0;
503	}
504
505	if (!ui->sample->user_regs.regs) {
506		*valp = 0;
507		return 0;
508	}
509
510	id = libunwind__arch_reg_id(regnum);
511	if (id < 0)
512		return -EINVAL;
513
514	ret = perf_reg_value(&val, &ui->sample->user_regs, id);
515	if (ret) {
516		pr_err("unwind: can't read reg %d\n", regnum);
517		return ret;
518	}
519
520	*valp = (unw_word_t) val;
521	pr_debug("unwind: reg %d, val %lx\n", regnum, (unsigned long)*valp);
522	return 0;
523}
524
525static void put_unwind_info(unw_addr_space_t __maybe_unused as,
526			    unw_proc_info_t *pi __maybe_unused,
527			    void *arg __maybe_unused)
528{
529	pr_debug("unwind: put_unwind_info called\n");
530}
531
532static int entry(u64 ip, struct thread *thread,
533		 unwind_entry_cb_t cb, void *arg)
534{
535	struct unwind_entry e;
536	struct addr_location al;
537
538	thread__find_addr_location(thread, PERF_RECORD_MISC_USER,
539				   MAP__FUNCTION, ip, &al);
540
541	e.ip = ip;
542	e.map = al.map;
543	e.sym = al.sym;
544
545	pr_debug("unwind: %s:ip = 0x%" PRIx64 " (0x%" PRIx64 ")\n",
546		 al.sym ? al.sym->name : "''",
547		 ip,
548		 al.map ? al.map->map_ip(al.map, ip) : (u64) 0);
549
550	return cb(&e, arg);
551}
552
553static void display_error(int err)
554{
555	switch (err) {
556	case UNW_EINVAL:
557		pr_err("unwind: Only supports local.\n");
558		break;
559	case UNW_EUNSPEC:
560		pr_err("unwind: Unspecified error.\n");
561		break;
562	case UNW_EBADREG:
563		pr_err("unwind: Register unavailable.\n");
564		break;
565	default:
566		break;
567	}
568}
569
570static unw_accessors_t accessors = {
571	.find_proc_info		= find_proc_info,
572	.put_unwind_info	= put_unwind_info,
573	.get_dyn_info_list_addr	= get_dyn_info_list_addr,
574	.access_mem		= access_mem,
575	.access_reg		= access_reg,
576	.access_fpreg		= access_fpreg,
577	.resume			= resume,
578	.get_proc_name		= get_proc_name,
579};
580
581int unwind__prepare_access(struct thread *thread)
582{
583	unw_addr_space_t addr_space;
584
585	if (callchain_param.record_mode != CALLCHAIN_DWARF)
586		return 0;
587
588	addr_space = unw_create_addr_space(&accessors, 0);
589	if (!addr_space) {
590		pr_err("unwind: Can't create unwind address space.\n");
591		return -ENOMEM;
592	}
 
 
593
594	unw_set_caching_policy(addr_space, UNW_CACHE_GLOBAL);
595	thread__set_priv(thread, addr_space);
596
597	return 0;
598}
599
600void unwind__flush_access(struct thread *thread)
601{
602	unw_addr_space_t addr_space;
603
604	if (callchain_param.record_mode != CALLCHAIN_DWARF)
605		return;
606
607	addr_space = thread__priv(thread);
608	unw_flush_cache(addr_space, 0, 0);
609}
610
611void unwind__finish_access(struct thread *thread)
612{
613	unw_addr_space_t addr_space;
614
615	if (callchain_param.record_mode != CALLCHAIN_DWARF)
616		return;
617
618	addr_space = thread__priv(thread);
619	unw_destroy_addr_space(addr_space);
620}
621
622static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
623		       void *arg, int max_stack)
624{
625	u64 val;
626	unw_word_t ips[max_stack];
627	unw_addr_space_t addr_space;
628	unw_cursor_t c;
629	int ret, i = 0;
630
631	ret = perf_reg_value(&val, &ui->sample->user_regs, PERF_REG_IP);
632	if (ret)
633		return ret;
634
635	ips[i++] = (unw_word_t) val;
636
637	/*
638	 * If we need more than one entry, do the DWARF
639	 * unwind itself.
640	 */
641	if (max_stack - 1 > 0) {
642		addr_space = thread__priv(ui->thread);
643		if (addr_space == NULL)
644			return -1;
645
646		ret = unw_init_remote(&c, addr_space, ui);
647		if (ret)
648			display_error(ret);
649
650		while (!ret && (unw_step(&c) > 0) && i < max_stack) {
651			unw_get_reg(&c, UNW_REG_IP, &ips[i]);
652			++i;
653		}
654
655		max_stack = i;
656	}
657
658	/*
659	 * Display what we got based on the order setup.
660	 */
661	for (i = 0; i < max_stack && !ret; i++) {
662		int j = i;
663
664		if (callchain_param.order == ORDER_CALLER)
665			j = max_stack - i - 1;
666		ret = ips[j] ? entry(ips[j], ui->thread, cb, arg) : 0;
667	}
668
669	return ret;
670}
671
672int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
673			struct thread *thread,
674			struct perf_sample *data, int max_stack)
 
675{
676	struct unwind_info ui = {
677		.sample       = data,
678		.thread       = thread,
679		.machine      = thread->mg->machine,
680	};
681
682	if (!data->user_regs.regs)
683		return -EINVAL;
684
685	if (max_stack <= 0)
686		return -EINVAL;
687
688	return get_entries(&ui, cb, arg, max_stack);
689}