Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Post mortem Dwarf CFI based unwinding on top of regs and stack dumps.
0004  *
0005  * Lots of this code have been borrowed or heavily inspired from parts of
0006  * the libunwind 0.99 code which are (amongst other contributors I may have
0007  * forgotten):
0008  *
0009  * Copyright (C) 2002-2007 Hewlett-Packard Co
0010  *  Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
0011  *
0012  * And the bugs have been added by:
0013  *
0014  * Copyright (C) 2010, Frederic Weisbecker <fweisbec@gmail.com>
0015  * Copyright (C) 2012, Jiri Olsa <jolsa@redhat.com>
0016  *
0017  */
0018 
0019 #include <elf.h>
0020 #include <errno.h>
0021 #include <gelf.h>
0022 #include <fcntl.h>
0023 #include <inttypes.h>
0024 #include <string.h>
0025 #include <unistd.h>
0026 #include <sys/mman.h>
0027 #include <linux/list.h>
0028 #include <linux/zalloc.h>
0029 #ifndef REMOTE_UNWIND_LIBUNWIND
0030 #include <libunwind.h>
0031 #include <libunwind-ptrace.h>
0032 #endif
0033 #include "callchain.h"
0034 #include "thread.h"
0035 #include "session.h"
0036 #include "perf_regs.h"
0037 #include "unwind.h"
0038 #include "map.h"
0039 #include "symbol.h"
0040 #include "debug.h"
0041 #include "asm/bug.h"
0042 #include "dso.h"
0043 
0044 extern int
0045 UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
0046                     unw_word_t ip,
0047                     unw_dyn_info_t *di,
0048                     unw_proc_info_t *pi,
0049                     int need_unwind_info, void *arg);
0050 
0051 #define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table)
0052 
0053 extern int
0054 UNW_OBJ(dwarf_find_debug_frame) (int found, unw_dyn_info_t *di_debug,
0055                  unw_word_t ip,
0056                  unw_word_t segbase,
0057                  const char *obj_name, unw_word_t start,
0058                  unw_word_t end);
0059 
0060 #define dwarf_find_debug_frame UNW_OBJ(dwarf_find_debug_frame)
0061 
0062 #define DW_EH_PE_FORMAT_MASK    0x0f    /* format of the encoded value */
0063 #define DW_EH_PE_APPL_MASK  0x70    /* how the value is to be applied */
0064 
0065 /* Pointer-encoding formats: */
0066 #define DW_EH_PE_omit       0xff
0067 #define DW_EH_PE_ptr        0x00    /* pointer-sized unsigned value */
0068 #define DW_EH_PE_udata4     0x03    /* unsigned 32-bit value */
0069 #define DW_EH_PE_udata8     0x04    /* unsigned 64-bit value */
0070 #define DW_EH_PE_sdata4     0x0b    /* signed 32-bit value */
0071 #define DW_EH_PE_sdata8     0x0c    /* signed 64-bit value */
0072 
0073 /* Pointer-encoding application: */
0074 #define DW_EH_PE_absptr     0x00    /* absolute value */
0075 #define DW_EH_PE_pcrel      0x10    /* rel. to addr. of encoded value */
0076 
0077 /*
0078  * The following are not documented by LSB v1.3, yet they are used by
0079  * GCC, presumably they aren't documented by LSB since they aren't
0080  * used on Linux:
0081  */
0082 #define DW_EH_PE_funcrel    0x40    /* start-of-procedure-relative */
0083 #define DW_EH_PE_aligned    0x50    /* aligned pointer */
0084 
0085 /* Flags intentionally not handled, since they're not needed:
0086  * #define DW_EH_PE_indirect      0x80
0087  * #define DW_EH_PE_uleb128       0x01
0088  * #define DW_EH_PE_udata2        0x02
0089  * #define DW_EH_PE_sleb128       0x09
0090  * #define DW_EH_PE_sdata2        0x0a
0091  * #define DW_EH_PE_textrel       0x20
0092  * #define DW_EH_PE_datarel       0x30
0093  */
0094 
0095 struct unwind_info {
0096     struct perf_sample  *sample;
0097     struct machine      *machine;
0098     struct thread       *thread;
0099     bool             best_effort;
0100 };
0101 
0102 #define dw_read(ptr, type, end) ({  \
0103     type *__p = (type *) ptr;   \
0104     type  __v;          \
0105     if ((__p + 1) > (type *) end)   \
0106         return -EINVAL;     \
0107     __v = *__p++;           \
0108     ptr = (typeof(ptr)) __p;    \
0109     __v;                \
0110     })
0111 
0112 static int __dw_read_encoded_value(u8 **p, u8 *end, u64 *val,
0113                    u8 encoding)
0114 {
0115     u8 *cur = *p;
0116     *val = 0;
0117 
0118     switch (encoding) {
0119     case DW_EH_PE_omit:
0120         *val = 0;
0121         goto out;
0122     case DW_EH_PE_ptr:
0123         *val = dw_read(cur, unsigned long, end);
0124         goto out;
0125     default:
0126         break;
0127     }
0128 
0129     switch (encoding & DW_EH_PE_APPL_MASK) {
0130     case DW_EH_PE_absptr:
0131         break;
0132     case DW_EH_PE_pcrel:
0133         *val = (unsigned long) cur;
0134         break;
0135     default:
0136         return -EINVAL;
0137     }
0138 
0139     if ((encoding & 0x07) == 0x00)
0140         encoding |= DW_EH_PE_udata4;
0141 
0142     switch (encoding & DW_EH_PE_FORMAT_MASK) {
0143     case DW_EH_PE_sdata4:
0144         *val += dw_read(cur, s32, end);
0145         break;
0146     case DW_EH_PE_udata4:
0147         *val += dw_read(cur, u32, end);
0148         break;
0149     case DW_EH_PE_sdata8:
0150         *val += dw_read(cur, s64, end);
0151         break;
0152     case DW_EH_PE_udata8:
0153         *val += dw_read(cur, u64, end);
0154         break;
0155     default:
0156         return -EINVAL;
0157     }
0158 
0159  out:
0160     *p = cur;
0161     return 0;
0162 }
0163 
0164 #define dw_read_encoded_value(ptr, end, enc) ({         \
0165     u64 __v;                        \
0166     if (__dw_read_encoded_value(&ptr, end, &__v, enc)) {    \
0167         return -EINVAL;                                 \
0168     }                                                       \
0169     __v;                                                    \
0170     })
0171 
0172 static int elf_section_address_and_offset(int fd, const char *name, u64 *address, u64 *offset)
0173 {
0174     Elf *elf;
0175     GElf_Ehdr ehdr;
0176     GElf_Shdr shdr;
0177     int ret = -1;
0178 
0179     elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
0180     if (elf == NULL)
0181         return -1;
0182 
0183     if (gelf_getehdr(elf, &ehdr) == NULL)
0184         goto out_err;
0185 
0186     if (!elf_section_by_name(elf, &ehdr, &shdr, name, NULL))
0187         goto out_err;
0188 
0189     *address = shdr.sh_addr;
0190     *offset = shdr.sh_offset;
0191     ret = 0;
0192 out_err:
0193     elf_end(elf);
0194     return ret;
0195 }
0196 
0197 #ifndef NO_LIBUNWIND_DEBUG_FRAME
0198 static u64 elf_section_offset(int fd, const char *name)
0199 {
0200     u64 address, offset = 0;
0201 
0202     if (elf_section_address_and_offset(fd, name, &address, &offset))
0203         return 0;
0204 
0205     return offset;
0206 }
0207 #endif
0208 
0209 static u64 elf_base_address(int fd)
0210 {
0211     Elf *elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
0212     GElf_Phdr phdr;
0213     u64 retval = 0;
0214     size_t i, phdrnum = 0;
0215 
0216     if (elf == NULL)
0217         return 0;
0218     (void)elf_getphdrnum(elf, &phdrnum);
0219     /* PT_LOAD segments are sorted by p_vaddr, so the first has the minimum p_vaddr. */
0220     for (i = 0; i < phdrnum; i++) {
0221         if (gelf_getphdr(elf, i, &phdr) && phdr.p_type == PT_LOAD) {
0222             retval = phdr.p_vaddr & -getpagesize();
0223             break;
0224         }
0225     }
0226 
0227     elf_end(elf);
0228     return retval;
0229 }
0230 
0231 #ifndef NO_LIBUNWIND_DEBUG_FRAME
0232 static int elf_is_exec(int fd, const char *name)
0233 {
0234     Elf *elf;
0235     GElf_Ehdr ehdr;
0236     int retval = 0;
0237 
0238     elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
0239     if (elf == NULL)
0240         return 0;
0241     if (gelf_getehdr(elf, &ehdr) == NULL)
0242         goto out;
0243 
0244     retval = (ehdr.e_type == ET_EXEC);
0245 
0246 out:
0247     elf_end(elf);
0248     pr_debug("unwind: elf_is_exec(%s): %d\n", name, retval);
0249     return retval;
0250 }
0251 #endif
0252 
0253 struct table_entry {
0254     u32 start_ip_offset;
0255     u32 fde_offset;
0256 };
0257 
0258 struct eh_frame_hdr {
0259     unsigned char version;
0260     unsigned char eh_frame_ptr_enc;
0261     unsigned char fde_count_enc;
0262     unsigned char table_enc;
0263 
0264     /*
0265      * The rest of the header is variable-length and consists of the
0266      * following members:
0267      *
0268      *  encoded_t eh_frame_ptr;
0269      *  encoded_t fde_count;
0270      */
0271 
0272     /* A single encoded pointer should not be more than 8 bytes. */
0273     u64 enc[2];
0274 
0275     /*
0276      * struct {
0277      *    encoded_t start_ip;
0278      *    encoded_t fde_addr;
0279      * } binary_search_table[fde_count];
0280      */
0281     char data[];
0282 } __packed;
0283 
0284 static int unwind_spec_ehframe(struct dso *dso, struct machine *machine,
0285                    u64 offset, u64 *table_data_offset, u64 *fde_count)
0286 {
0287     struct eh_frame_hdr hdr;
0288     u8 *enc = (u8 *) &hdr.enc;
0289     u8 *end = (u8 *) &hdr.data;
0290     ssize_t r;
0291 
0292     r = dso__data_read_offset(dso, machine, offset,
0293                   (u8 *) &hdr, sizeof(hdr));
0294     if (r != sizeof(hdr))
0295         return -EINVAL;
0296 
0297     /* We dont need eh_frame_ptr, just skip it. */
0298     dw_read_encoded_value(enc, end, hdr.eh_frame_ptr_enc);
0299 
0300     *fde_count  = dw_read_encoded_value(enc, end, hdr.fde_count_enc);
0301     *table_data_offset = enc - (u8 *) &hdr;
0302     return 0;
0303 }
0304 
0305 static int read_unwind_spec_eh_frame(struct dso *dso, struct unwind_info *ui,
0306                      u64 *table_data, u64 *segbase,
0307                      u64 *fde_count)
0308 {
0309     struct map *map;
0310     u64 base_addr = UINT64_MAX;
0311     int ret, fd;
0312 
0313     if (dso->data.eh_frame_hdr_offset == 0) {
0314         fd = dso__data_get_fd(dso, ui->machine);
0315         if (fd < 0)
0316             return -EINVAL;
0317 
0318         /* Check the .eh_frame section for unwinding info */
0319         ret = elf_section_address_and_offset(fd, ".eh_frame_hdr",
0320                              &dso->data.eh_frame_hdr_addr,
0321                              &dso->data.eh_frame_hdr_offset);
0322         dso->data.elf_base_addr = elf_base_address(fd);
0323         dso__data_put_fd(dso);
0324         if (ret || dso->data.eh_frame_hdr_offset == 0)
0325             return -EINVAL;
0326     }
0327 
0328     maps__for_each_entry(ui->thread->maps, map) {
0329         if (map->dso == dso && map->start < base_addr)
0330             base_addr = map->start;
0331     }
0332     base_addr -= dso->data.elf_base_addr;
0333     /* Address of .eh_frame_hdr */
0334     *segbase = base_addr + dso->data.eh_frame_hdr_addr;
0335     ret = unwind_spec_ehframe(dso, ui->machine, dso->data.eh_frame_hdr_offset,
0336                    table_data, fde_count);
0337     if (ret)
0338         return ret;
0339     /* binary_search_table offset plus .eh_frame_hdr address */
0340     *table_data += *segbase;
0341     return 0;
0342 }
0343 
0344 #ifndef NO_LIBUNWIND_DEBUG_FRAME
0345 static int read_unwind_spec_debug_frame(struct dso *dso,
0346                     struct machine *machine, u64 *offset)
0347 {
0348     int fd;
0349     u64 ofs = dso->data.debug_frame_offset;
0350 
0351     /* debug_frame can reside in:
0352      *  - dso
0353      *  - debug pointed by symsrc_filename
0354      *  - gnu_debuglink, which doesn't necessary
0355      *    has to be pointed by symsrc_filename
0356      */
0357     if (ofs == 0) {
0358         fd = dso__data_get_fd(dso, machine);
0359         if (fd >= 0) {
0360             ofs = elf_section_offset(fd, ".debug_frame");
0361             dso__data_put_fd(dso);
0362         }
0363 
0364         if (ofs <= 0) {
0365             fd = open(dso->symsrc_filename, O_RDONLY);
0366             if (fd >= 0) {
0367                 ofs = elf_section_offset(fd, ".debug_frame");
0368                 close(fd);
0369             }
0370         }
0371 
0372         if (ofs <= 0) {
0373             char *debuglink = malloc(PATH_MAX);
0374             int ret = 0;
0375 
0376             ret = dso__read_binary_type_filename(
0377                 dso, DSO_BINARY_TYPE__DEBUGLINK,
0378                 machine->root_dir, debuglink, PATH_MAX);
0379             if (!ret) {
0380                 fd = open(debuglink, O_RDONLY);
0381                 if (fd >= 0) {
0382                     ofs = elf_section_offset(fd,
0383                             ".debug_frame");
0384                     close(fd);
0385                 }
0386             }
0387             if (ofs > 0) {
0388                 if (dso->symsrc_filename != NULL) {
0389                     pr_warning(
0390                         "%s: overwrite symsrc(%s,%s)\n",
0391                             __func__,
0392                             dso->symsrc_filename,
0393                             debuglink);
0394                     zfree(&dso->symsrc_filename);
0395                 }
0396                 dso->symsrc_filename = debuglink;
0397             } else {
0398                 free(debuglink);
0399             }
0400         }
0401 
0402         dso->data.debug_frame_offset = ofs;
0403     }
0404 
0405     *offset = ofs;
0406     if (*offset)
0407         return 0;
0408 
0409     return -EINVAL;
0410 }
0411 #endif
0412 
0413 static struct map *find_map(unw_word_t ip, struct unwind_info *ui)
0414 {
0415     struct addr_location al;
0416     return thread__find_map(ui->thread, PERF_RECORD_MISC_USER, ip, &al);
0417 }
0418 
0419 static int
0420 find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
0421            int need_unwind_info, void *arg)
0422 {
0423     struct unwind_info *ui = arg;
0424     struct map *map;
0425     unw_dyn_info_t di;
0426     u64 table_data, segbase, fde_count;
0427     int ret = -EINVAL;
0428 
0429     map = find_map(ip, ui);
0430     if (!map || !map->dso)
0431         return -EINVAL;
0432 
0433     pr_debug("unwind: find_proc_info dso %s\n", map->dso->name);
0434 
0435     /* Check the .eh_frame section for unwinding info */
0436     if (!read_unwind_spec_eh_frame(map->dso, ui,
0437                        &table_data, &segbase, &fde_count)) {
0438         memset(&di, 0, sizeof(di));
0439         di.format   = UNW_INFO_FORMAT_REMOTE_TABLE;
0440         di.start_ip = map->start;
0441         di.end_ip   = map->end;
0442         di.u.rti.segbase    = segbase;
0443         di.u.rti.table_data = table_data;
0444         di.u.rti.table_len  = fde_count * sizeof(struct table_entry)
0445                       / sizeof(unw_word_t);
0446         ret = dwarf_search_unwind_table(as, ip, &di, pi,
0447                         need_unwind_info, arg);
0448     }
0449 
0450 #ifndef NO_LIBUNWIND_DEBUG_FRAME
0451     /* Check the .debug_frame section for unwinding info */
0452     if (ret < 0 &&
0453         !read_unwind_spec_debug_frame(map->dso, ui->machine, &segbase)) {
0454         int fd = dso__data_get_fd(map->dso, ui->machine);
0455         int is_exec = elf_is_exec(fd, map->dso->name);
0456         unw_word_t base = is_exec ? 0 : map->start;
0457         const char *symfile;
0458 
0459         if (fd >= 0)
0460             dso__data_put_fd(map->dso);
0461 
0462         symfile = map->dso->symsrc_filename ?: map->dso->name;
0463 
0464         memset(&di, 0, sizeof(di));
0465         if (dwarf_find_debug_frame(0, &di, ip, base, symfile,
0466                        map->start, map->end))
0467             return dwarf_search_unwind_table(as, ip, &di, pi,
0468                              need_unwind_info, arg);
0469     }
0470 #endif
0471 
0472     return ret;
0473 }
0474 
0475 static int access_fpreg(unw_addr_space_t __maybe_unused as,
0476             unw_regnum_t __maybe_unused num,
0477             unw_fpreg_t __maybe_unused *val,
0478             int __maybe_unused __write,
0479             void __maybe_unused *arg)
0480 {
0481     pr_err("unwind: access_fpreg unsupported\n");
0482     return -UNW_EINVAL;
0483 }
0484 
0485 static int get_dyn_info_list_addr(unw_addr_space_t __maybe_unused as,
0486                   unw_word_t __maybe_unused *dil_addr,
0487                   void __maybe_unused *arg)
0488 {
0489     return -UNW_ENOINFO;
0490 }
0491 
0492 static int resume(unw_addr_space_t __maybe_unused as,
0493           unw_cursor_t __maybe_unused *cu,
0494           void __maybe_unused *arg)
0495 {
0496     pr_err("unwind: resume unsupported\n");
0497     return -UNW_EINVAL;
0498 }
0499 
0500 static int
0501 get_proc_name(unw_addr_space_t __maybe_unused as,
0502           unw_word_t __maybe_unused addr,
0503         char __maybe_unused *bufp, size_t __maybe_unused buf_len,
0504         unw_word_t __maybe_unused *offp, void __maybe_unused *arg)
0505 {
0506     pr_err("unwind: get_proc_name unsupported\n");
0507     return -UNW_EINVAL;
0508 }
0509 
0510 static int access_dso_mem(struct unwind_info *ui, unw_word_t addr,
0511               unw_word_t *data)
0512 {
0513     struct map *map;
0514     ssize_t size;
0515 
0516     map = find_map(addr, ui);
0517     if (!map) {
0518         pr_debug("unwind: no map for %lx\n", (unsigned long)addr);
0519         return -1;
0520     }
0521 
0522     if (!map->dso)
0523         return -1;
0524 
0525     size = dso__data_read_addr(map->dso, map, ui->machine,
0526                    addr, (u8 *) data, sizeof(*data));
0527 
0528     return !(size == sizeof(*data));
0529 }
0530 
0531 static int access_mem(unw_addr_space_t __maybe_unused as,
0532               unw_word_t addr, unw_word_t *valp,
0533               int __write, void *arg)
0534 {
0535     struct unwind_info *ui = arg;
0536     struct stack_dump *stack = &ui->sample->user_stack;
0537     u64 start, end;
0538     int offset;
0539     int ret;
0540 
0541     /* Don't support write, probably not needed. */
0542     if (__write || !stack || !ui->sample->user_regs.regs) {
0543         *valp = 0;
0544         return 0;
0545     }
0546 
0547     ret = perf_reg_value(&start, &ui->sample->user_regs,
0548                  LIBUNWIND__ARCH_REG_SP);
0549     if (ret)
0550         return ret;
0551 
0552     end = start + stack->size;
0553 
0554     /* Check overflow. */
0555     if (addr + sizeof(unw_word_t) < addr)
0556         return -EINVAL;
0557 
0558     if (addr < start || addr + sizeof(unw_word_t) >= end) {
0559         ret = access_dso_mem(ui, addr, valp);
0560         if (ret) {
0561             pr_debug("unwind: access_mem %p not inside range"
0562                  " 0x%" PRIx64 "-0x%" PRIx64 "\n",
0563                  (void *) (uintptr_t) addr, start, end);
0564             *valp = 0;
0565             return ret;
0566         }
0567         return 0;
0568     }
0569 
0570     offset = addr - start;
0571     *valp  = *(unw_word_t *)&stack->data[offset];
0572     pr_debug("unwind: access_mem addr %p val %lx, offset %d\n",
0573          (void *) (uintptr_t) addr, (unsigned long)*valp, offset);
0574     return 0;
0575 }
0576 
0577 static int access_reg(unw_addr_space_t __maybe_unused as,
0578               unw_regnum_t regnum, unw_word_t *valp,
0579               int __write, void *arg)
0580 {
0581     struct unwind_info *ui = arg;
0582     int id, ret;
0583     u64 val;
0584 
0585     /* Don't support write, I suspect we don't need it. */
0586     if (__write) {
0587         pr_err("unwind: access_reg w %d\n", regnum);
0588         return 0;
0589     }
0590 
0591     if (!ui->sample->user_regs.regs) {
0592         *valp = 0;
0593         return 0;
0594     }
0595 
0596     id = LIBUNWIND__ARCH_REG_ID(regnum);
0597     if (id < 0)
0598         return -EINVAL;
0599 
0600     ret = perf_reg_value(&val, &ui->sample->user_regs, id);
0601     if (ret) {
0602         if (!ui->best_effort)
0603             pr_err("unwind: can't read reg %d\n", regnum);
0604         return ret;
0605     }
0606 
0607     *valp = (unw_word_t) val;
0608     pr_debug("unwind: reg %d, val %lx\n", regnum, (unsigned long)*valp);
0609     return 0;
0610 }
0611 
0612 static void put_unwind_info(unw_addr_space_t __maybe_unused as,
0613                 unw_proc_info_t *pi __maybe_unused,
0614                 void *arg __maybe_unused)
0615 {
0616     pr_debug("unwind: put_unwind_info called\n");
0617 }
0618 
0619 static int entry(u64 ip, struct thread *thread,
0620          unwind_entry_cb_t cb, void *arg)
0621 {
0622     struct unwind_entry e;
0623     struct addr_location al;
0624 
0625     e.ms.sym = thread__find_symbol(thread, PERF_RECORD_MISC_USER, ip, &al);
0626     e.ip     = ip;
0627     e.ms.map = al.map;
0628     e.ms.maps = al.maps;
0629 
0630     pr_debug("unwind: %s:ip = 0x%" PRIx64 " (0x%" PRIx64 ")\n",
0631          al.sym ? al.sym->name : "''",
0632          ip,
0633          al.map ? al.map->map_ip(al.map, ip) : (u64) 0);
0634 
0635     return cb(&e, arg);
0636 }
0637 
0638 static void display_error(int err)
0639 {
0640     switch (err) {
0641     case UNW_EINVAL:
0642         pr_err("unwind: Only supports local.\n");
0643         break;
0644     case UNW_EUNSPEC:
0645         pr_err("unwind: Unspecified error.\n");
0646         break;
0647     case UNW_EBADREG:
0648         pr_err("unwind: Register unavailable.\n");
0649         break;
0650     default:
0651         break;
0652     }
0653 }
0654 
0655 static unw_accessors_t accessors = {
0656     .find_proc_info     = find_proc_info,
0657     .put_unwind_info    = put_unwind_info,
0658     .get_dyn_info_list_addr = get_dyn_info_list_addr,
0659     .access_mem     = access_mem,
0660     .access_reg     = access_reg,
0661     .access_fpreg       = access_fpreg,
0662     .resume         = resume,
0663     .get_proc_name      = get_proc_name,
0664 };
0665 
0666 static int _unwind__prepare_access(struct maps *maps)
0667 {
0668     maps->addr_space = unw_create_addr_space(&accessors, 0);
0669     if (!maps->addr_space) {
0670         pr_err("unwind: Can't create unwind address space.\n");
0671         return -ENOMEM;
0672     }
0673 
0674     unw_set_caching_policy(maps->addr_space, UNW_CACHE_GLOBAL);
0675     return 0;
0676 }
0677 
0678 static void _unwind__flush_access(struct maps *maps)
0679 {
0680     unw_flush_cache(maps->addr_space, 0, 0);
0681 }
0682 
0683 static void _unwind__finish_access(struct maps *maps)
0684 {
0685     unw_destroy_addr_space(maps->addr_space);
0686 }
0687 
0688 static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
0689                void *arg, int max_stack)
0690 {
0691     u64 val;
0692     unw_word_t ips[max_stack];
0693     unw_addr_space_t addr_space;
0694     unw_cursor_t c;
0695     int ret, i = 0;
0696 
0697     ret = perf_reg_value(&val, &ui->sample->user_regs,
0698                  LIBUNWIND__ARCH_REG_IP);
0699     if (ret)
0700         return ret;
0701 
0702     ips[i++] = (unw_word_t) val;
0703 
0704     /*
0705      * If we need more than one entry, do the DWARF
0706      * unwind itself.
0707      */
0708     if (max_stack - 1 > 0) {
0709         WARN_ONCE(!ui->thread, "WARNING: ui->thread is NULL");
0710         addr_space = ui->thread->maps->addr_space;
0711 
0712         if (addr_space == NULL)
0713             return -1;
0714 
0715         ret = unw_init_remote(&c, addr_space, ui);
0716         if (ret && !ui->best_effort)
0717             display_error(ret);
0718 
0719         while (!ret && (unw_step(&c) > 0) && i < max_stack) {
0720             unw_get_reg(&c, UNW_REG_IP, &ips[i]);
0721 
0722             /*
0723              * Decrement the IP for any non-activation frames.
0724              * this is required to properly find the srcline
0725              * for caller frames.
0726              * See also the documentation for dwfl_frame_pc(),
0727              * which this code tries to replicate.
0728              */
0729             if (unw_is_signal_frame(&c) <= 0)
0730                 --ips[i];
0731 
0732             ++i;
0733         }
0734 
0735         max_stack = i;
0736     }
0737 
0738     /*
0739      * Display what we got based on the order setup.
0740      */
0741     for (i = 0; i < max_stack && !ret; i++) {
0742         int j = i;
0743 
0744         if (callchain_param.order == ORDER_CALLER)
0745             j = max_stack - i - 1;
0746         ret = ips[j] ? entry(ips[j], ui->thread, cb, arg) : 0;
0747     }
0748 
0749     return ret;
0750 }
0751 
0752 static int _unwind__get_entries(unwind_entry_cb_t cb, void *arg,
0753             struct thread *thread,
0754             struct perf_sample *data, int max_stack,
0755             bool best_effort)
0756 {
0757     struct unwind_info ui = {
0758         .sample       = data,
0759         .thread       = thread,
0760         .machine      = thread->maps->machine,
0761         .best_effort  = best_effort
0762     };
0763 
0764     if (!data->user_regs.regs)
0765         return -EINVAL;
0766 
0767     if (max_stack <= 0)
0768         return -EINVAL;
0769 
0770     return get_entries(&ui, cb, arg, max_stack);
0771 }
0772 
0773 static struct unwind_libunwind_ops
0774 _unwind_libunwind_ops = {
0775     .prepare_access = _unwind__prepare_access,
0776     .flush_access   = _unwind__flush_access,
0777     .finish_access  = _unwind__finish_access,
0778     .get_entries    = _unwind__get_entries,
0779 };
0780 
0781 #ifndef REMOTE_UNWIND_LIBUNWIND
0782 struct unwind_libunwind_ops *
0783 local_unwind_libunwind_ops = &_unwind_libunwind_ops;
0784 #endif