linux/arch/arm/kernel/unwind.c
<<
>>
Prefs
   1/*
   2 * arch/arm/kernel/unwind.c
   3 *
   4 * Copyright (C) 2008 ARM Limited
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  14 *
  15 * You should have received a copy of the GNU General Public License
  16 * along with this program; if not, write to the Free Software
  17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18 *
  19 *
  20 * Stack unwinding support for ARM
  21 *
  22 * An ARM EABI version of gcc is required to generate the unwind
  23 * tables. For information about the structure of the unwind tables,
  24 * see "Exception Handling ABI for the ARM Architecture" at:
  25 *
  26 * http://infocenter.arm.com/help/topic/com.arm.doc.subset.swdev.abi/index.html
  27 */
  28
  29#ifndef __CHECKER__
  30#if !defined (__ARM_EABI__)
  31#warning Your compiler does not have EABI support.
  32#warning    ARM unwind is known to compile only with EABI compilers.
  33#warning    Change compiler or disable ARM_UNWIND option.
  34#elif (__GNUC__ == 4 && __GNUC_MINOR__ <= 2)
  35#warning Your compiler is too buggy; it is known to not compile ARM unwind support.
  36#warning    Change compiler or disable ARM_UNWIND option.
  37#endif
  38#endif /* __CHECKER__ */
  39
  40#include <linux/kernel.h>
  41#include <linux/init.h>
  42#include <linux/export.h>
  43#include <linux/sched.h>
  44#include <linux/slab.h>
  45#include <linux/spinlock.h>
  46#include <linux/list.h>
  47
  48#include <asm/stacktrace.h>
  49#include <asm/traps.h>
  50#include <asm/unwind.h>
  51
  52/* Dummy functions to avoid linker complaints */
  53void __aeabi_unwind_cpp_pr0(void)
  54{
  55};
  56EXPORT_SYMBOL(__aeabi_unwind_cpp_pr0);
  57
  58void __aeabi_unwind_cpp_pr1(void)
  59{
  60};
  61EXPORT_SYMBOL(__aeabi_unwind_cpp_pr1);
  62
  63void __aeabi_unwind_cpp_pr2(void)
  64{
  65};
  66EXPORT_SYMBOL(__aeabi_unwind_cpp_pr2);
  67
  68struct unwind_ctrl_block {
  69        unsigned long vrs[16];          /* virtual register set */
  70        const unsigned long *insn;      /* pointer to the current instructions word */
  71        int entries;                    /* number of entries left to interpret */
  72        int byte;                       /* current byte number in the instructions word */
  73};
  74
  75enum regs {
  76#ifdef CONFIG_THUMB2_KERNEL
  77        FP = 7,
  78#else
  79        FP = 11,
  80#endif
  81        SP = 13,
  82        LR = 14,
  83        PC = 15
  84};
  85
  86extern const struct unwind_idx __start_unwind_idx[];
  87static const struct unwind_idx *__origin_unwind_idx;
  88extern const struct unwind_idx __stop_unwind_idx[];
  89
  90static DEFINE_SPINLOCK(unwind_lock);
  91static LIST_HEAD(unwind_tables);
  92
  93/* Convert a prel31 symbol to an absolute address */
  94#define prel31_to_addr(ptr)                             \
  95({                                                      \
  96        /* sign-extend to 32 bits */                    \
  97        long offset = (((long)*(ptr)) << 1) >> 1;       \
  98        (unsigned long)(ptr) + offset;                  \
  99})
 100
 101/*
 102 * Binary search in the unwind index. The entries are
 103 * guaranteed to be sorted in ascending order by the linker.
 104 *
 105 * start = first entry
 106 * origin = first entry with positive offset (or stop if there is no such entry)
 107 * stop - 1 = last entry
 108 */
 109static const struct unwind_idx *search_index(unsigned long addr,
 110                                       const struct unwind_idx *start,
 111                                       const struct unwind_idx *origin,
 112                                       const struct unwind_idx *stop)
 113{
 114        unsigned long addr_prel31;
 115
 116        pr_debug("%s(%08lx, %p, %p, %p)\n",
 117                        __func__, addr, start, origin, stop);
 118
 119        /*
 120         * only search in the section with the matching sign. This way the
 121         * prel31 numbers can be compared as unsigned longs.
 122         */
 123        if (addr < (unsigned long)start)
 124                /* negative offsets: [start; origin) */
 125                stop = origin;
 126        else
 127                /* positive offsets: [origin; stop) */
 128                start = origin;
 129
 130        /* prel31 for address relavive to start */
 131        addr_prel31 = (addr - (unsigned long)start) & 0x7fffffff;
 132
 133        while (start < stop - 1) {
 134                const struct unwind_idx *mid = start + ((stop - start) >> 1);
 135
 136                /*
 137                 * As addr_prel31 is relative to start an offset is needed to
 138                 * make it relative to mid.
 139                 */
 140                if (addr_prel31 - ((unsigned long)mid - (unsigned long)start) <
 141                                mid->addr_offset)
 142                        stop = mid;
 143                else {
 144                        /* keep addr_prel31 relative to start */
 145                        addr_prel31 -= ((unsigned long)mid -
 146                                        (unsigned long)start);
 147                        start = mid;
 148                }
 149        }
 150
 151        if (likely(start->addr_offset <= addr_prel31))
 152                return start;
 153        else {
 154                pr_warning("unwind: Unknown symbol address %08lx\n", addr);
 155                return NULL;
 156        }
 157}
 158
 159static const struct unwind_idx *unwind_find_origin(
 160                const struct unwind_idx *start, const struct unwind_idx *stop)
 161{
 162        pr_debug("%s(%p, %p)\n", __func__, start, stop);
 163        while (start < stop) {
 164                const struct unwind_idx *mid = start + ((stop - start) >> 1);
 165
 166                if (mid->addr_offset >= 0x40000000)
 167                        /* negative offset */
 168                        start = mid + 1;
 169                else
 170                        /* positive offset */
 171                        stop = mid;
 172        }
 173        pr_debug("%s -> %p\n", __func__, stop);
 174        return stop;
 175}
 176
 177static const struct unwind_idx *unwind_find_idx(unsigned long addr)
 178{
 179        const struct unwind_idx *idx = NULL;
 180        unsigned long flags;
 181
 182        pr_debug("%s(%08lx)\n", __func__, addr);
 183
 184        if (core_kernel_text(addr)) {
 185                if (unlikely(!__origin_unwind_idx))
 186                        __origin_unwind_idx =
 187                                unwind_find_origin(__start_unwind_idx,
 188                                                __stop_unwind_idx);
 189
 190                /* main unwind table */
 191                idx = search_index(addr, __start_unwind_idx,
 192                                   __origin_unwind_idx,
 193                                   __stop_unwind_idx);
 194        } else {
 195                /* module unwind tables */
 196                struct unwind_table *table;
 197
 198                spin_lock_irqsave(&unwind_lock, flags);
 199                list_for_each_entry(table, &unwind_tables, list) {
 200                        if (addr >= table->begin_addr &&
 201                            addr < table->end_addr) {
 202                                idx = search_index(addr, table->start,
 203                                                   table->origin,
 204                                                   table->stop);
 205                                /* Move-to-front to exploit common traces */
 206                                list_move(&table->list, &unwind_tables);
 207                                break;
 208                        }
 209                }
 210                spin_unlock_irqrestore(&unwind_lock, flags);
 211        }
 212
 213        pr_debug("%s: idx = %p\n", __func__, idx);
 214        return idx;
 215}
 216
 217static unsigned long unwind_get_byte(struct unwind_ctrl_block *ctrl)
 218{
 219        unsigned long ret;
 220
 221        if (ctrl->entries <= 0) {
 222                pr_warning("unwind: Corrupt unwind table\n");
 223                return 0;
 224        }
 225
 226        ret = (*ctrl->insn >> (ctrl->byte * 8)) & 0xff;
 227
 228        if (ctrl->byte == 0) {
 229                ctrl->insn++;
 230                ctrl->entries--;
 231                ctrl->byte = 3;
 232        } else
 233                ctrl->byte--;
 234
 235        return ret;
 236}
 237
 238/*
 239 * Execute the current unwind instruction.
 240 */
 241static int unwind_exec_insn(struct unwind_ctrl_block *ctrl)
 242{
 243        unsigned long insn = unwind_get_byte(ctrl);
 244
 245        pr_debug("%s: insn = %08lx\n", __func__, insn);
 246
 247        if ((insn & 0xc0) == 0x00)
 248                ctrl->vrs[SP] += ((insn & 0x3f) << 2) + 4;
 249        else if ((insn & 0xc0) == 0x40)
 250                ctrl->vrs[SP] -= ((insn & 0x3f) << 2) + 4;
 251        else if ((insn & 0xf0) == 0x80) {
 252                unsigned long mask;
 253                unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
 254                int load_sp, reg = 4;
 255
 256                insn = (insn << 8) | unwind_get_byte(ctrl);
 257                mask = insn & 0x0fff;
 258                if (mask == 0) {
 259                        pr_warning("unwind: 'Refuse to unwind' instruction %04lx\n",
 260                                   insn);
 261                        return -URC_FAILURE;
 262                }
 263
 264                /* pop R4-R15 according to mask */
 265                load_sp = mask & (1 << (13 - 4));
 266                while (mask) {
 267                        if (mask & 1)
 268                                ctrl->vrs[reg] = *vsp++;
 269                        mask >>= 1;
 270                        reg++;
 271                }
 272                if (!load_sp)
 273                        ctrl->vrs[SP] = (unsigned long)vsp;
 274        } else if ((insn & 0xf0) == 0x90 &&
 275                   (insn & 0x0d) != 0x0d)
 276                ctrl->vrs[SP] = ctrl->vrs[insn & 0x0f];
 277        else if ((insn & 0xf0) == 0xa0) {
 278                unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
 279                int reg;
 280
 281                /* pop R4-R[4+bbb] */
 282                for (reg = 4; reg <= 4 + (insn & 7); reg++)
 283                        ctrl->vrs[reg] = *vsp++;
 284                if (insn & 0x80)
 285                        ctrl->vrs[14] = *vsp++;
 286                ctrl->vrs[SP] = (unsigned long)vsp;
 287        } else if (insn == 0xb0) {
 288                if (ctrl->vrs[PC] == 0)
 289                        ctrl->vrs[PC] = ctrl->vrs[LR];
 290                /* no further processing */
 291                ctrl->entries = 0;
 292        } else if (insn == 0xb1) {
 293                unsigned long mask = unwind_get_byte(ctrl);
 294                unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
 295                int reg = 0;
 296
 297                if (mask == 0 || mask & 0xf0) {
 298                        pr_warning("unwind: Spare encoding %04lx\n",
 299                               (insn << 8) | mask);
 300                        return -URC_FAILURE;
 301                }
 302
 303                /* pop R0-R3 according to mask */
 304                while (mask) {
 305                        if (mask & 1)
 306                                ctrl->vrs[reg] = *vsp++;
 307                        mask >>= 1;
 308                        reg++;
 309                }
 310                ctrl->vrs[SP] = (unsigned long)vsp;
 311        } else if (insn == 0xb2) {
 312                unsigned long uleb128 = unwind_get_byte(ctrl);
 313
 314                ctrl->vrs[SP] += 0x204 + (uleb128 << 2);
 315        } else {
 316                pr_warning("unwind: Unhandled instruction %02lx\n", insn);
 317                return -URC_FAILURE;
 318        }
 319
 320        pr_debug("%s: fp = %08lx sp = %08lx lr = %08lx pc = %08lx\n", __func__,
 321                 ctrl->vrs[FP], ctrl->vrs[SP], ctrl->vrs[LR], ctrl->vrs[PC]);
 322
 323        return URC_OK;
 324}
 325
 326/*
 327 * Unwind a single frame starting with *sp for the symbol at *pc. It
 328 * updates the *pc and *sp with the new values.
 329 */
 330int unwind_frame(struct stackframe *frame)
 331{
 332        unsigned long high, low;
 333        const struct unwind_idx *idx;
 334        struct unwind_ctrl_block ctrl;
 335
 336        /* only go to a higher address on the stack */
 337        low = frame->sp;
 338        high = ALIGN(low, THREAD_SIZE);
 339
 340        pr_debug("%s(pc = %08lx lr = %08lx sp = %08lx)\n", __func__,
 341                 frame->pc, frame->lr, frame->sp);
 342
 343        if (!kernel_text_address(frame->pc))
 344                return -URC_FAILURE;
 345
 346        idx = unwind_find_idx(frame->pc);
 347        if (!idx) {
 348                pr_warning("unwind: Index not found %08lx\n", frame->pc);
 349                return -URC_FAILURE;
 350        }
 351
 352        ctrl.vrs[FP] = frame->fp;
 353        ctrl.vrs[SP] = frame->sp;
 354        ctrl.vrs[LR] = frame->lr;
 355        ctrl.vrs[PC] = 0;
 356
 357        if (idx->insn == 1)
 358                /* can't unwind */
 359                return -URC_FAILURE;
 360        else if ((idx->insn & 0x80000000) == 0)
 361                /* prel31 to the unwind table */
 362                ctrl.insn = (unsigned long *)prel31_to_addr(&idx->insn);
 363        else if ((idx->insn & 0xff000000) == 0x80000000)
 364                /* only personality routine 0 supported in the index */
 365                ctrl.insn = &idx->insn;
 366        else {
 367                pr_warning("unwind: Unsupported personality routine %08lx in the index at %p\n",
 368                           idx->insn, idx);
 369                return -URC_FAILURE;
 370        }
 371
 372        /* check the personality routine */
 373        if ((*ctrl.insn & 0xff000000) == 0x80000000) {
 374                ctrl.byte = 2;
 375                ctrl.entries = 1;
 376        } else if ((*ctrl.insn & 0xff000000) == 0x81000000) {
 377                ctrl.byte = 1;
 378                ctrl.entries = 1 + ((*ctrl.insn & 0x00ff0000) >> 16);
 379        } else {
 380                pr_warning("unwind: Unsupported personality routine %08lx at %p\n",
 381                           *ctrl.insn, ctrl.insn);
 382                return -URC_FAILURE;
 383        }
 384
 385        while (ctrl.entries > 0) {
 386                int urc = unwind_exec_insn(&ctrl);
 387                if (urc < 0)
 388                        return urc;
 389                if (ctrl.vrs[SP] < low || ctrl.vrs[SP] >= high)
 390                        return -URC_FAILURE;
 391        }
 392
 393        if (ctrl.vrs[PC] == 0)
 394                ctrl.vrs[PC] = ctrl.vrs[LR];
 395
 396        /* check for infinite loop */
 397        if (frame->pc == ctrl.vrs[PC])
 398                return -URC_FAILURE;
 399
 400        frame->fp = ctrl.vrs[FP];
 401        frame->sp = ctrl.vrs[SP];
 402        frame->lr = ctrl.vrs[LR];
 403        frame->pc = ctrl.vrs[PC];
 404
 405        return URC_OK;
 406}
 407
 408void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk)
 409{
 410        struct stackframe frame;
 411        register unsigned long current_sp asm ("sp");
 412
 413        pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk);
 414
 415        if (!tsk)
 416                tsk = current;
 417
 418        if (regs) {
 419                frame.fp = regs->ARM_fp;
 420                frame.sp = regs->ARM_sp;
 421                frame.lr = regs->ARM_lr;
 422                /* PC might be corrupted, use LR in that case. */
 423                frame.pc = kernel_text_address(regs->ARM_pc)
 424                         ? regs->ARM_pc : regs->ARM_lr;
 425        } else if (tsk == current) {
 426                frame.fp = (unsigned long)__builtin_frame_address(0);
 427                frame.sp = current_sp;
 428                frame.lr = (unsigned long)__builtin_return_address(0);
 429                frame.pc = (unsigned long)unwind_backtrace;
 430        } else {
 431                /* task blocked in __switch_to */
 432                frame.fp = thread_saved_fp(tsk);
 433                frame.sp = thread_saved_sp(tsk);
 434                /*
 435                 * The function calling __switch_to cannot be a leaf function
 436                 * so LR is recovered from the stack.
 437                 */
 438                frame.lr = 0;
 439                frame.pc = thread_saved_pc(tsk);
 440        }
 441
 442        while (1) {
 443                int urc;
 444                unsigned long where = frame.pc;
 445
 446                urc = unwind_frame(&frame);
 447                if (urc < 0)
 448                        break;
 449                dump_backtrace_entry(where, frame.pc, frame.sp - 4);
 450        }
 451}
 452
 453struct unwind_table *unwind_table_add(unsigned long start, unsigned long size,
 454                                      unsigned long text_addr,
 455                                      unsigned long text_size)
 456{
 457        unsigned long flags;
 458        struct unwind_table *tab = kmalloc(sizeof(*tab), GFP_KERNEL);
 459
 460        pr_debug("%s(%08lx, %08lx, %08lx, %08lx)\n", __func__, start, size,
 461                 text_addr, text_size);
 462
 463        if (!tab)
 464                return tab;
 465
 466        tab->start = (const struct unwind_idx *)start;
 467        tab->stop = (const struct unwind_idx *)(start + size);
 468        tab->origin = unwind_find_origin(tab->start, tab->stop);
 469        tab->begin_addr = text_addr;
 470        tab->end_addr = text_addr + text_size;
 471
 472        spin_lock_irqsave(&unwind_lock, flags);
 473        list_add_tail(&tab->list, &unwind_tables);
 474        spin_unlock_irqrestore(&unwind_lock, flags);
 475
 476        return tab;
 477}
 478
 479void unwind_table_del(struct unwind_table *tab)
 480{
 481        unsigned long flags;
 482
 483        if (!tab)
 484                return;
 485
 486        spin_lock_irqsave(&unwind_lock, flags);
 487        list_del(&tab->list);
 488        spin_unlock_irqrestore(&unwind_lock, flags);
 489
 490        kfree(tab);
 491}
 492