Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /* SPDX-License-Identifier: GPL-2.0-only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *  linux/arch/arm/lib/backtrace-clang.S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *  Copyright (C) 2019 Nathan Huckleberry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/kern_levels.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/linkage.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <asm/assembler.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 		.text
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) /* fp is 0 or stack frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #define frame	r4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #define sv_fp	r5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #define sv_pc	r6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #define mask	r7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #define sv_lr	r8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #define loglvl	r9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) ENTRY(c_backtrace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #if !defined(CONFIG_FRAME_POINTER) || !defined(CONFIG_PRINTK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 		ret	lr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) ENDPROC(c_backtrace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  * Clang does not store pc or sp in function prologues so we don't know exactly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  * where the function starts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  * We can treat the current frame's lr as the saved pc and the preceding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  * frame's lr as the current frame's lr, but we can't trace the most recent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  * call.  Inserting a false stack frame allows us to reference the function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  * called last in the stacktrace.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  * If the call instruction was a bl we can look at the callers branch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  * instruction to calculate the saved pc.  We can recover the pc in most cases,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  * but in cases such as calling function pointers we cannot. In this case,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  * default to using the lr. This will be some address in the function, but will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)  * not be the function start.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45)  * Unfortunately due to the stack frame layout we can't dump r0 - r3, but these
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46)  * are less frequently saved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)  * Stack frame layout:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)  * 		<larger addresses>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)  * 		saved lr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51)  * 	frame=> saved fp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)  * 		optionally saved caller registers (r4 - r10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)  * 		optionally saved arguments (r0 - r3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)  * 		<top of stack frame>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)  * 		<smaller addresses>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)  * Functions start with the following code sequence:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58)  * corrected pc =>  stmfd sp!, {..., fp, lr}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)  *		add fp, sp, #x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60)  *		stmfd sp!, {r0 - r3} (optional)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)  * The diagram below shows an example stack setup for dump_stack.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69)  * The frame for c_backtrace has pointers to the code of dump_stack. This is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70)  * why the frame of c_backtrace is used to for the pc calculation of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)  * dump_stack. This is why we must move back a frame to print dump_stack.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)  * The stored locals for dump_stack are in dump_stack's frame. This means that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)  * to fully print dump_stack's frame we need both the frame for dump_stack (for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75)  * locals) and the frame that was called by dump_stack (for pc).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77)  * To print locals we must know where the function start is. If we read the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78)  * function prologue opcodes we can determine which variables are stored in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79)  * stack frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81)  * To find the function start of dump_stack we can look at the stored LR of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82)  * show_stack. It points at the instruction directly after the bl dump_stack.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83)  * We can then read the offset from the bl opcode to determine where the branch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84)  * takes us.  The address calculated must be the start of dump_stack.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86)  * c_backtrace frame           dump_stack:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87)  * {[LR]    }  ============|   ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88)  * {[FP]    }  =======|    |   bl c_backtrace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)  *                    |    |=> ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)  * {[R4-R10]}         |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)  * {[R0-R3] }         |        show_stack:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92)  * dump_stack frame   |        ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93)  * {[LR]    } =============|   bl dump_stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94)  * {[FP]    } <=======|    |=> ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95)  * {[R4-R10]}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96)  * {[R0-R3] }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		stmfd	sp!, {r4 - r9, fp, lr}	@ Save an extra register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 						@ to ensure 8 byte alignment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		movs	frame, r0		@ if frame pointer is zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		beq	no_frame		@ we have no stack frames
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		mov	loglvl, r2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		tst	r1, #0x10		@ 26 or 32-bit mode?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		moveq	mask, #0xfc000003
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		movne	mask, #0		@ mask for 32-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)  * Switches the current frame to be the frame for dump_stack.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		add	frame, sp, #24		@ switch to false frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) for_each_frame:	tst	frame, mask		@ Check for address exceptions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		bne	no_frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)  * sv_fp is the stack frame with the locals for the current considered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)  * function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)  * sv_pc is the saved lr frame the frame above. This is a pointer to a code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)  * address within the current considered function, but it is not the function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)  * start. This value gets updated to be the function start later if it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)  * possible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 1001:		ldr	sv_pc, [frame, #4]	@ get saved 'pc'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 1002:		ldr	sv_fp, [frame, #0]	@ get saved fp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		teq	sv_fp, mask		@ make sure next frame exists
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		beq	no_frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)  * sv_lr is the lr from the function that called the current function. This is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)  * a pointer to a code address in the current function's caller.  sv_lr-4 is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)  * the instruction used to call the current function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)  * This sv_lr can be used to calculate the function start if the function was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)  * called using a bl instruction. If the function start can be recovered sv_pc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)  * is overwritten with the function start.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)  * If the current function was called using a function pointer we cannot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)  * recover the function start and instead continue with sv_pc as an arbitrary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)  * value within the current function. If this is the case we cannot print
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)  * registers for the current function, but the stacktrace is still printed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)  * properly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 1003:		ldr	sv_lr, [sv_fp, #4]	@ get saved lr from next frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		ldr	r0, [sv_lr, #-4]	@ get call instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		ldr	r3, .Lopcode+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		and	r2, r3, r0		@ is this a bl call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		teq	r2, r3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		bne	finished_setup		@ give up if it's not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		and	r0, #0xffffff		@ get call offset 24-bit int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		lsl	r0, r0, #8		@ sign extend offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		asr	r0, r0, #8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		ldr	sv_pc, [sv_fp, #4]	@ get lr address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		add	sv_pc, sv_pc, #-4	@ get call instruction address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		add	sv_pc, sv_pc, #8	@ take care of prefetch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		add	sv_pc, sv_pc, r0, lsl #2@ find function start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) finished_setup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		bic	sv_pc, sv_pc, mask	@ mask PC/LR for the mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)  * Print the function (sv_pc) and where it was called from (sv_lr).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 1004:		mov	r0, sv_pc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		mov	r1, sv_lr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 		mov	r2, frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		bic	r1, r1, mask		@ mask PC/LR for the mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		mov	r3, loglvl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		bl	dump_backtrace_entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)  * Test if the function start is a stmfd instruction to determine which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)  * registers were stored in the function prologue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)  * If we could not recover the sv_pc because we were called through a function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)  * pointer the comparison will fail and no registers will print. Unwinding will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)  * continue as if there had been no registers stored in this frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 1005:		ldr	r1, [sv_pc, #0]		@ if stmfd sp!, {..., fp, lr}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		ldr	r3, .Lopcode		@ instruction exists,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		teq	r3, r1, lsr #11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		ldr	r0, [frame]		@ locals are stored in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 						@ the preceding frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 		subeq	r0, r0, #4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 		mov	r2, loglvl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 		bleq	dump_backtrace_stm	@ dump saved registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)  * If we are out of frames or if the next frame is invalid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 		teq	sv_fp, #0		@ zero saved fp means
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 		beq	no_frame		@ no further frames
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 		cmp	sv_fp, frame		@ next frame must be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		mov	frame, sv_fp		@ above the current frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		bhi	for_each_frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 1006:		adr	r0, .Lbad
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		mov	r1, loglvl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 		mov	r2, frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 		bl	printk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) no_frame:	ldmfd	sp!, {r4 - r9, fp, pc}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) ENDPROC(c_backtrace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		.pushsection __ex_table,"a"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 		.align	3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		.long	1001b, 1006b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		.long	1002b, 1006b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		.long	1003b, 1006b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		.long	1004b, 1006b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 		.long   1005b, 1006b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		.popsection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) .Lbad:		.asciz	"%sBacktrace aborted due to bad frame pointer <%p>\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		.align
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) .Lopcode:	.word	0xe92d4800 >> 11	@ stmfd sp!, {... fp, lr}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		.word	0x0b000000		@ bl if these bits are set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) #endif