cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

unwind-libunwind-local.c (18563B)


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