Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.12 145 lines 3.0 kB view raw
1/* 2 * linux/arch/arm26/lib/backtrace.S 3 * 4 * Copyright (C) 1995, 1996 Russell King 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#include <linux/config.h> 11#include <linux/linkage.h> 12#include <asm/assembler.h> 13 .text 14 15@ fp is 0 or stack frame 16 17#define frame r4 18#define next r5 19#define save r6 20#define mask r7 21#define offset r8 22 23ENTRY(__backtrace) 24 mov r1, #0x10 25 mov r0, fp 26 27ENTRY(c_backtrace) 28 29#ifdef CONFIG_NO_FRAME_POINTER 30 mov pc, lr 31#else 32 33 stmfd sp!, {r4 - r8, lr} @ Save an extra register so we have a location... 34 mov mask, #0xfc000003 35 tst mask, r0 36 movne r0, #0 37 movs frame, r0 381: moveq r0, #-2 39 LOADREGS(eqfd, sp!, {r4 - r8, pc}) 40 412: stmfd sp!, {pc} @ calculate offset of PC in STMIA instruction 42 ldr r0, [sp], #4 43 adr r1, 2b - 4 44 sub offset, r0, r1 45 463: tst frame, mask @ Check for address exceptions... 47 bne 1b 48 491001: ldr next, [frame, #-12] @ get fp 501002: ldr r2, [frame, #-4] @ get lr 511003: ldr r3, [frame, #0] @ get pc 52 sub save, r3, offset @ Correct PC for prefetching 53 bic save, save, mask 541004: ldr r1, [save, #0] @ get instruction at function 55 mov r1, r1, lsr #10 56 ldr r3, .Ldsi+4 57 teq r1, r3 58 subeq save, save, #4 59 adr r0, .Lfe 60 mov r1, save 61 bic r2, r2, mask 62 bl printk @ print pc and link register 63 64 ldr r0, [frame, #-8] @ get sp 65 sub r0, r0, #4 661005: ldr r1, [save, #4] @ get instruction at function+4 67 mov r3, r1, lsr #10 68 ldr r2, .Ldsi+4 69 teq r3, r2 @ Check for stmia sp!, {args} 70 addeq save, save, #4 @ next instruction 71 bleq .Ldumpstm 72 73 sub r0, frame, #16 741006: ldr r1, [save, #4] @ Get 'stmia sp!, {rlist, fp, ip, lr, pc}' instruction 75 mov r3, r1, lsr #10 76 ldr r2, .Ldsi 77 teq r3, r2 78 bleq .Ldumpstm 79 80 teq frame, next 81 movne frame, next 82 teqne frame, #0 83 bne 3b 84 LOADREGS(fd, sp!, {r4 - r8, pc}) 85 86/* 87 * Fixup for LDMDB 88 */ 89 .section .fixup,"ax" 90 .align 0 911007: ldr r0, =.Lbad 92 mov r1, frame 93 bl printk 94 LOADREGS(fd, sp!, {r4 - r8, pc}) 95 .ltorg 96 .previous 97 98 .section __ex_table,"a" 99 .align 3 100 .long 1001b, 1007b 101 .long 1002b, 1007b 102 .long 1003b, 1007b 103 .long 1004b, 1007b 104 .long 1005b, 1007b 105 .long 1006b, 1007b 106 .previous 107 108#define instr r4 109#define reg r5 110#define stack r6 111 112.Ldumpstm: stmfd sp!, {instr, reg, stack, r7, lr} 113 mov stack, r0 114 mov instr, r1 115 mov reg, #9 116 mov r7, #0 1171: mov r3, #1 118 tst instr, r3, lsl reg 119 beq 2f 120 add r7, r7, #1 121 teq r7, #4 122 moveq r7, #0 123 moveq r3, #'\n' 124 movne r3, #' ' 125 ldr r2, [stack], #-4 126 mov r1, reg 127 adr r0, .Lfp 128 bl printk 1292: subs reg, reg, #1 130 bpl 1b 131 teq r7, #0 132 adrne r0, .Lcr 133 blne printk 134 mov r0, stack 135 LOADREGS(fd, sp!, {instr, reg, stack, r7, pc}) 136 137.Lfe: .asciz "Function entered at [<%p>] from [<%p>]\n" 138.Lfp: .asciz " r%d = %08X%c" 139.Lcr: .asciz "\n" 140.Lbad: .asciz "Backtrace aborted due to bad frame pointer <%p>\n" 141 .align 142.Ldsi: .word 0x00e92dd8 >> 2 143 .word 0x00e92d00 >> 2 144 145#endif