linux/tools/perf/util/unwind-libunwind.c
<<
>>
Prefs
   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        return al.map;
 323}
 324
 325static int
 326find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
 327               int need_unwind_info, void *arg)
 328{
 329        struct unwind_info *ui = arg;
 330        struct map *map;
 331        unw_dyn_info_t di;
 332        u64 table_data, segbase, fde_count;
 333
 334        map = find_map(ip, ui);
 335        if (!map || !map->dso)
 336                return -EINVAL;
 337
 338        pr_debug("unwind: find_proc_info dso %s\n", map->dso->name);
 339
 340        /* Check the .eh_frame section for unwinding info */
 341        if (!read_unwind_spec_eh_frame(map->dso, ui->machine,
 342                                       &table_data, &segbase, &fde_count)) {
 343                memset(&di, 0, sizeof(di));
 344                di.format   = UNW_INFO_FORMAT_REMOTE_TABLE;
 345                di.start_ip = map->start;
 346                di.end_ip   = map->end;
 347                di.u.rti.segbase    = map->start + segbase;
 348                di.u.rti.table_data = map->start + table_data;
 349                di.u.rti.table_len  = fde_count * sizeof(struct table_entry)
 350                                      / sizeof(unw_word_t);
 351                return dwarf_search_unwind_table(as, ip, &di, pi,
 352                                                 need_unwind_info, arg);
 353        }
 354
 355#ifndef NO_LIBUNWIND_DEBUG_FRAME
 356        /* Check the .debug_frame section for unwinding info */
 357        if (!read_unwind_spec_debug_frame(map->dso, ui->machine, &segbase)) {
 358                int fd = dso__data_get_fd(map->dso, ui->machine);
 359                int is_exec = elf_is_exec(fd, map->dso->name);
 360                unw_word_t base = is_exec ? 0 : map->start;
 361
 362                if (fd >= 0)
 363                        dso__data_put_fd(map->dso);
 364
 365                memset(&di, 0, sizeof(di));
 366                if (dwarf_find_debug_frame(0, &di, ip, base, map->dso->name,
 367                                           map->start, map->end))
 368                        return dwarf_search_unwind_table(as, ip, &di, pi,
 369                                                         need_unwind_info, arg);
 370        }
 371#endif
 372
 373        return -EINVAL;
 374}
 375
 376static int access_fpreg(unw_addr_space_t __maybe_unused as,
 377                        unw_regnum_t __maybe_unused num,
 378                        unw_fpreg_t __maybe_unused *val,
 379                        int __maybe_unused __write,
 380                        void __maybe_unused *arg)
 381{
 382        pr_err("unwind: access_fpreg unsupported\n");
 383        return -UNW_EINVAL;
 384}
 385
 386static int get_dyn_info_list_addr(unw_addr_space_t __maybe_unused as,
 387                                  unw_word_t __maybe_unused *dil_addr,
 388                                  void __maybe_unused *arg)
 389{
 390        return -UNW_ENOINFO;
 391}
 392
 393static int resume(unw_addr_space_t __maybe_unused as,
 394                  unw_cursor_t __maybe_unused *cu,
 395                  void __maybe_unused *arg)
 396{
 397        pr_err("unwind: resume unsupported\n");
 398        return -UNW_EINVAL;
 399}
 400
 401static int
 402get_proc_name(unw_addr_space_t __maybe_unused as,
 403              unw_word_t __maybe_unused addr,
 404                char __maybe_unused *bufp, size_t __maybe_unused buf_len,
 405                unw_word_t __maybe_unused *offp, void __maybe_unused *arg)
 406{
 407        pr_err("unwind: get_proc_name unsupported\n");
 408        return -UNW_EINVAL;
 409}
 410
 411static int access_dso_mem(struct unwind_info *ui, unw_word_t addr,
 412                          unw_word_t *data)
 413{
 414        struct addr_location al;
 415        ssize_t size;
 416
 417        thread__find_addr_map(ui->thread, PERF_RECORD_MISC_USER,
 418                              MAP__FUNCTION, addr, &al);
 419        if (!al.map) {
 420                pr_debug("unwind: no map for %lx\n", (unsigned long)addr);
 421                return -1;
 422        }
 423
 424        if (!al.map->dso)
 425                return -1;
 426
 427        size = dso__data_read_addr(al.map->dso, al.map, ui->machine,
 428                                   addr, (u8 *) data, sizeof(*data));
 429
 430        return !(size == sizeof(*data));
 431}
 432
 433static int access_mem(unw_addr_space_t __maybe_unused as,
 434                      unw_word_t addr, unw_word_t *valp,
 435                      int __write, void *arg)
 436{
 437        struct unwind_info *ui = arg;
 438        struct stack_dump *stack = &ui->sample->user_stack;
 439        u64 start, end;
 440        int offset;
 441        int ret;
 442
 443        /* Don't support write, probably not needed. */
 444        if (__write || !stack || !ui->sample->user_regs.regs) {
 445                *valp = 0;
 446                return 0;
 447        }
 448
 449        ret = perf_reg_value(&start, &ui->sample->user_regs, PERF_REG_SP);
 450        if (ret)
 451                return ret;
 452
 453        end = start + stack->size;
 454
 455        /* Check overflow. */
 456        if (addr + sizeof(unw_word_t) < addr)
 457                return -EINVAL;
 458
 459        if (addr < start || addr + sizeof(unw_word_t) >= end) {
 460                ret = access_dso_mem(ui, addr, valp);
 461                if (ret) {
 462                        pr_debug("unwind: access_mem %p not inside range"
 463                                 " 0x%" PRIx64 "-0x%" PRIx64 "\n",
 464                                 (void *) addr, start, end);
 465                        *valp = 0;
 466                        return ret;
 467                }
 468                return 0;
 469        }
 470
 471        offset = addr - start;
 472        *valp  = *(unw_word_t *)&stack->data[offset];
 473        pr_debug("unwind: access_mem addr %p val %lx, offset %d\n",
 474                 (void *) addr, (unsigned long)*valp, offset);
 475        return 0;
 476}
 477
 478static int access_reg(unw_addr_space_t __maybe_unused as,
 479                      unw_regnum_t regnum, unw_word_t *valp,
 480                      int __write, void *arg)
 481{
 482        struct unwind_info *ui = arg;
 483        int id, ret;
 484        u64 val;
 485
 486        /* Don't support write, I suspect we don't need it. */
 487        if (__write) {
 488                pr_err("unwind: access_reg w %d\n", regnum);
 489                return 0;
 490        }
 491
 492        if (!ui->sample->user_regs.regs) {
 493                *valp = 0;
 494                return 0;
 495        }
 496
 497        id = libunwind__arch_reg_id(regnum);
 498        if (id < 0)
 499                return -EINVAL;
 500
 501        ret = perf_reg_value(&val, &ui->sample->user_regs, id);
 502        if (ret) {
 503                pr_err("unwind: can't read reg %d\n", regnum);
 504                return ret;
 505        }
 506
 507        *valp = (unw_word_t) val;
 508        pr_debug("unwind: reg %d, val %lx\n", regnum, (unsigned long)*valp);
 509        return 0;
 510}
 511
 512static void put_unwind_info(unw_addr_space_t __maybe_unused as,
 513                            unw_proc_info_t *pi __maybe_unused,
 514                            void *arg __maybe_unused)
 515{
 516        pr_debug("unwind: put_unwind_info called\n");
 517}
 518
 519static int entry(u64 ip, struct thread *thread,
 520                 unwind_entry_cb_t cb, void *arg)
 521{
 522        struct unwind_entry e;
 523        struct addr_location al;
 524
 525        thread__find_addr_location(thread, PERF_RECORD_MISC_USER,
 526                                   MAP__FUNCTION, ip, &al);
 527
 528        e.ip = ip;
 529        e.map = al.map;
 530        e.sym = al.sym;
 531
 532        pr_debug("unwind: %s:ip = 0x%" PRIx64 " (0x%" PRIx64 ")\n",
 533                 al.sym ? al.sym->name : "''",
 534                 ip,
 535                 al.map ? al.map->map_ip(al.map, ip) : (u64) 0);
 536
 537        return cb(&e, arg);
 538}
 539
 540static void display_error(int err)
 541{
 542        switch (err) {
 543        case UNW_EINVAL:
 544                pr_err("unwind: Only supports local.\n");
 545                break;
 546        case UNW_EUNSPEC:
 547                pr_err("unwind: Unspecified error.\n");
 548                break;
 549        case UNW_EBADREG:
 550                pr_err("unwind: Register unavailable.\n");
 551                break;
 552        default:
 553                break;
 554        }
 555}
 556
 557static unw_accessors_t accessors = {
 558        .find_proc_info         = find_proc_info,
 559        .put_unwind_info        = put_unwind_info,
 560        .get_dyn_info_list_addr = get_dyn_info_list_addr,
 561        .access_mem             = access_mem,
 562        .access_reg             = access_reg,
 563        .access_fpreg           = access_fpreg,
 564        .resume                 = resume,
 565        .get_proc_name          = get_proc_name,
 566};
 567
 568int unwind__prepare_access(struct thread *thread)
 569{
 570        unw_addr_space_t addr_space;
 571
 572        if (callchain_param.record_mode != CALLCHAIN_DWARF)
 573                return 0;
 574
 575        addr_space = unw_create_addr_space(&accessors, 0);
 576        if (!addr_space) {
 577                pr_err("unwind: Can't create unwind address space.\n");
 578                return -ENOMEM;
 579        }
 580
 581        unw_set_caching_policy(addr_space, UNW_CACHE_GLOBAL);
 582        thread__set_priv(thread, addr_space);
 583
 584        return 0;
 585}
 586
 587void unwind__flush_access(struct thread *thread)
 588{
 589        unw_addr_space_t addr_space;
 590
 591        if (callchain_param.record_mode != CALLCHAIN_DWARF)
 592                return;
 593
 594        addr_space = thread__priv(thread);
 595        unw_flush_cache(addr_space, 0, 0);
 596}
 597
 598void unwind__finish_access(struct thread *thread)
 599{
 600        unw_addr_space_t addr_space;
 601
 602        if (callchain_param.record_mode != CALLCHAIN_DWARF)
 603                return;
 604
 605        addr_space = thread__priv(thread);
 606        unw_destroy_addr_space(addr_space);
 607}
 608
 609static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
 610                       void *arg, int max_stack)
 611{
 612        unw_addr_space_t addr_space;
 613        unw_cursor_t c;
 614        int ret;
 615
 616        addr_space = thread__priv(ui->thread);
 617        if (addr_space == NULL)
 618                return -1;
 619
 620        ret = unw_init_remote(&c, addr_space, ui);
 621        if (ret)
 622                display_error(ret);
 623
 624        while (!ret && (unw_step(&c) > 0) && max_stack--) {
 625                unw_word_t ip;
 626
 627                unw_get_reg(&c, UNW_REG_IP, &ip);
 628                ret = ip ? entry(ip, ui->thread, cb, arg) : 0;
 629        }
 630
 631        return ret;
 632}
 633
 634int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
 635                        struct thread *thread,
 636                        struct perf_sample *data, int max_stack)
 637{
 638        u64 ip;
 639        struct unwind_info ui = {
 640                .sample       = data,
 641                .thread       = thread,
 642                .machine      = thread->mg->machine,
 643        };
 644        int ret;
 645
 646        if (!data->user_regs.regs)
 647                return -EINVAL;
 648
 649        ret = perf_reg_value(&ip, &data->user_regs, PERF_REG_IP);
 650        if (ret)
 651                return ret;
 652
 653        ret = entry(ip, thread, cb, arg);
 654        if (ret)
 655                return -ENOMEM;
 656
 657        return --max_stack > 0 ? get_entries(&ui, cb, arg, max_stack) : 0;
 658}
 659