arch/arm/lib/backtrace-clang.S

Source file repositories/reference/linux-study-clean/arch/arm/lib/backtrace-clang.S

File Facts

System
Linux kernel
Corpus path
arch/arm/lib/backtrace-clang.S
Extension
.S
Size
7226 bytes
Lines
231
Domain
Architecture Layer
Bucket
arch/arm
Inferred role
Architecture Layer: arch/arm
Status
atlas-only

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

#include <linux/kern_levels.h>
#include <linux/linkage.h>
#include <asm/assembler.h>
		.text

/* fp is 0 or stack frame */

#define frame	r4
#define sv_fp	r5
#define sv_pc	r6
#define mask	r7
#define sv_lr	r8
#define loglvl	r9

ENTRY(c_backtrace)

#if !defined(CONFIG_FRAME_POINTER) || !defined(CONFIG_PRINTK)
		ret	lr
ENDPROC(c_backtrace)
#else


/*
 * Clang does not store pc or sp in function prologues so we don't know exactly
 * where the function starts.
 *
 * We can treat the current frame's lr as the saved pc and the preceding
 * frame's lr as the current frame's lr, but we can't trace the most recent
 * call.  Inserting a false stack frame allows us to reference the function
 * called last in the stacktrace.
 *
 * If the call instruction was a bl we can look at the callers branch
 * instruction to calculate the saved pc.  We can recover the pc in most cases,
 * but in cases such as calling function pointers we cannot. In this case,
 * default to using the lr. This will be some address in the function, but will
 * not be the function start.
 *
 * Unfortunately due to the stack frame layout we can't dump r0 - r3, but these
 * are less frequently saved.
 *
 * Stack frame layout:
 * 		<larger addresses>
 * 		saved lr
 * 	frame=> saved fp
 * 		optionally saved caller registers (r4 - r10)
 * 		optionally saved arguments (r0 - r3)
 * 		<top of stack frame>
 * 		<smaller addresses>
 *
 * Functions start with the following code sequence:
 * corrected pc =>  stmfd sp!, {..., fp, lr}
 *		add fp, sp, #x
 *		stmfd sp!, {r0 - r3} (optional)
 *
 *
 *
 *
 *
 *
 * The diagram below shows an example stack setup for dump_stack.
 *
 * The frame for c_backtrace has pointers to the code of dump_stack. This is
 * why the frame of c_backtrace is used to for the pc calculation of
 * dump_stack. This is why we must move back a frame to print dump_stack.
 *
 * The stored locals for dump_stack are in dump_stack's frame. This means that
 * to fully print dump_stack's frame we need both the frame for dump_stack (for
 * locals) and the frame that was called by dump_stack (for pc).
 *
 * To print locals we must know where the function start is. If we read the

Annotation

Implementation Notes