Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | /* * linux/arch/arm/lib/backtrace.S * * Copyright (C) 1995, 1996 Russell King * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * 27/03/03 Ian Molton Clean up CONFIG_CPU * */ #include <linux/config.h> #include <linux/linkage.h> #include <asm/assembler.h> .text @ fp is 0 or stack frame #define frame r4 #define next r5 #define save r6 #define mask r7 #define offset r8 ENTRY(__backtrace) mov r1, #0x10 mov r0, fp ENTRY(c_backtrace) #ifndef CONFIG_FRAME_POINTER mov pc, lr #else stmfd sp!, {r4 - r8, lr} @ Save an extra register so we have a location... tst r1, #0x10 @ 26 or 32-bit? moveq mask, #0xfc000003 movne mask, #0 tst mask, r0 movne r0, #0 movs frame, r0 1: moveq r0, #-2 LOADREGS(eqfd, sp!, {r4 - r8, pc}) 2: stmfd sp!, {pc} @ calculate offset of PC in STMIA instruction ldr r0, [sp], #4 adr r1, 2b - 4 sub offset, r0, r1 3: tst frame, mask @ Check for address exceptions... bne 1b 1001: ldr next, [frame, #-12] @ get fp 1002: ldr r2, [frame, #-4] @ get lr 1003: ldr r3, [frame, #0] @ get pc sub save, r3, offset @ Correct PC for prefetching bic save, save, mask 1004: ldr r1, [save, #0] @ get instruction at function mov r1, r1, lsr #10 ldr r3, .Ldsi+4 teq r1, r3 subeq save, save, #4 mov r0, save bic r1, r2, mask bl dump_backtrace_entry ldr r0, [frame, #-8] @ get sp sub r0, r0, #4 1005: ldr r1, [save, #4] @ get instruction at function+4 mov r3, r1, lsr #10 ldr r2, .Ldsi+4 teq r3, r2 @ Check for stmia sp!, {args} addeq save, save, #4 @ next instruction bleq .Ldumpstm sub r0, frame, #16 1006: ldr r1, [save, #4] @ Get 'stmia sp!, {rlist, fp, ip, lr, pc}' instruction mov r3, r1, lsr #10 ldr r2, .Ldsi teq r3, r2 bleq .Ldumpstm /* * A zero next framepointer means we're done. */ teq next, #0 LOADREGS(eqfd, sp!, {r4 - r8, pc}) /* * The next framepointer must be above the * current framepointer. */ cmp next, frame mov frame, next bhi 3b b 1007f /* * Fixup for LDMDB */ .section .fixup,"ax" .align 0 1007: ldr r0, =.Lbad mov r1, frame bl printk LOADREGS(fd, sp!, {r4 - r8, pc}) .ltorg .previous .section __ex_table,"a" .align 3 .long 1001b, 1007b .long 1002b, 1007b .long 1003b, 1007b .long 1004b, 1007b .long 1005b, 1007b .long 1006b, 1007b .previous #define instr r4 #define reg r5 #define stack r6 .Ldumpstm: stmfd sp!, {instr, reg, stack, r7, lr} mov stack, r0 mov instr, r1 mov reg, #9 mov r7, #0 1: mov r3, #1 tst instr, r3, lsl reg beq 2f add r7, r7, #1 teq r7, #4 moveq r7, #0 moveq r3, #'\n' movne r3, #' ' ldr r2, [stack], #-4 mov r1, reg adr r0, .Lfp bl printk 2: subs reg, reg, #1 bpl 1b teq r7, #0 adrne r0, .Lcr blne printk mov r0, stack LOADREGS(fd, sp!, {instr, reg, stack, r7, pc}) .Lfp: .asciz " r%d = %08X%c" .Lcr: .asciz "\n" .Lbad: .asciz "Backtrace aborted due to bad frame pointer <%p>\n" .align .Ldsi: .word 0x00e92dd8 >> 2 .word 0x00e92d00 >> 2 #endif |