arch/x86/kernel/unwind_frame.c
Source file repositories/reference/linux-study-clean/arch/x86/kernel/unwind_frame.c
File Facts
- System
- Linux kernel
- Corpus path
arch/x86/kernel/unwind_frame.c- Extension
.c- Size
- 11517 bytes
- Lines
- 420
- Domain
- Architecture Layer
- Bucket
- arch/x86
- Inferred role
- Architecture Layer: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/sched.hlinux/sched/task.hlinux/sched/task_stack.hlinux/interrupt.hasm/sections.hasm/ptrace.hasm/bitops.hasm/stacktrace.hasm/unwind.h
Detected Declarations
function unwind_get_return_addressfunction unwind_dumpfunction in_entry_codefunction is_last_framefunction is_last_aligned_framefunction is_last_ftrace_framefunction is_last_task_framefunction functionfunction unwind_next_framefunction __unwind_startexport unwind_get_return_addressexport unwind_next_frameexport __unwind_start
Annotated Snippet
if (zero) {
if (!prev_zero)
printk_deferred("%p: %0*x ...\n",
sp, BITS_PER_LONG/4, 0);
continue;
}
printk_deferred("%p: %0*lx (%pB)\n",
sp, BITS_PER_LONG/4, word, (void *)word);
}
}
}
static bool in_entry_code(unsigned long ip)
{
char *addr = (char *)ip;
return addr >= __entry_text_start && addr < __entry_text_end;
}
static inline unsigned long *last_frame(struct unwind_state *state)
{
return (unsigned long *)task_pt_regs(state->task) - 2;
}
static bool is_last_frame(struct unwind_state *state)
{
return state->bp == last_frame(state);
}
#ifdef CONFIG_X86_32
#define GCC_REALIGN_WORDS 3
#else
#define GCC_REALIGN_WORDS 1
#endif
static inline unsigned long *last_aligned_frame(struct unwind_state *state)
{
return last_frame(state) - GCC_REALIGN_WORDS;
}
static bool is_last_aligned_frame(struct unwind_state *state)
{
unsigned long *last_bp = last_frame(state);
unsigned long *aligned_bp = last_aligned_frame(state);
/*
* GCC can occasionally decide to realign the stack pointer and change
* the offset of the stack frame in the prologue of a function called
* by head/entry code. Examples:
*
* <start_secondary>:
* push %edi
* lea 0x8(%esp),%edi
* and $0xfffffff8,%esp
* pushl -0x4(%edi)
* push %ebp
* mov %esp,%ebp
*
* <x86_64_start_kernel>:
* lea 0x8(%rsp),%r10
* and $0xfffffffffffffff0,%rsp
* pushq -0x8(%r10)
* push %rbp
* mov %rsp,%rbp
*
* After aligning the stack, it pushes a duplicate copy of the return
* address before pushing the frame pointer.
*/
return (state->bp == aligned_bp && *(aligned_bp + 1) == *(last_bp + 1));
}
static bool is_last_ftrace_frame(struct unwind_state *state)
{
unsigned long *last_bp = last_frame(state);
unsigned long *last_ftrace_bp = last_bp - 3;
/*
* When unwinding from an ftrace handler of a function called by entry
* code, the stack layout of the last frame is:
*
* bp
* parent ret addr
* bp
* function ret addr
* parent ret addr
* pt_regs
* -----------------
*/
return (state->bp == last_ftrace_bp &&
Annotation
- Immediate include surface: `linux/sched.h`, `linux/sched/task.h`, `linux/sched/task_stack.h`, `linux/interrupt.h`, `asm/sections.h`, `asm/ptrace.h`, `asm/bitops.h`, `asm/stacktrace.h`.
- Detected declarations: `function unwind_get_return_address`, `function unwind_dump`, `function in_entry_code`, `function is_last_frame`, `function is_last_aligned_frame`, `function is_last_ftrace_frame`, `function is_last_task_frame`, `function function`, `function unwind_next_frame`, `function __unwind_start`.
- Atlas domain: Architecture Layer / arch/x86.
- Implementation status: integration implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.