unwind_frame.c (b70366e5d31788650b2a5cec5cd13ea80ac7e44a) unwind_frame.c (87a6b2975f0d340c75b7488d22d61d2f98fb8abf)
1#include <linux/sched.h>
2#include <linux/sched/task.h>
3#include <linux/sched/task_stack.h>
4#include <asm/ptrace.h>
5#include <asm/bitops.h>
6#include <asm/stacktrace.h>
7#include <asm/unwind.h>
8

--- 68 unchanged lines hidden (view full) ---

77{
78 /* x86_32 regs from kernel mode are two words shorter: */
79 if (IS_ENABLED(CONFIG_X86_32) && !user_mode(regs))
80 return sizeof(*regs) - 2*sizeof(long);
81
82 return sizeof(*regs);
83}
84
1#include <linux/sched.h>
2#include <linux/sched/task.h>
3#include <linux/sched/task_stack.h>
4#include <asm/ptrace.h>
5#include <asm/bitops.h>
6#include <asm/stacktrace.h>
7#include <asm/unwind.h>
8

--- 68 unchanged lines hidden (view full) ---

77{
78 /* x86_32 regs from kernel mode are two words shorter: */
79 if (IS_ENABLED(CONFIG_X86_32) && !user_mode(regs))
80 return sizeof(*regs) - 2*sizeof(long);
81
82 return sizeof(*regs);
83}
84
85#ifdef CONFIG_X86_32
86#define GCC_REALIGN_WORDS 3
87#else
88#define GCC_REALIGN_WORDS 1
89#endif
90
85static bool is_last_task_frame(struct unwind_state *state)
86{
91static bool is_last_task_frame(struct unwind_state *state)
92{
87 unsigned long bp = (unsigned long)state->bp;
88 unsigned long regs = (unsigned long)task_pt_regs(state->task);
93 unsigned long *last_bp = (unsigned long *)task_pt_regs(state->task) - 2;
94 unsigned long *aligned_bp = last_bp - GCC_REALIGN_WORDS;
89
90 /*
91 * We have to check for the last task frame at two different locations
92 * because gcc can occasionally decide to realign the stack pointer and
95
96 /*
97 * We have to check for the last task frame at two different locations
98 * because gcc can occasionally decide to realign the stack pointer and
93 * change the offset of the stack frame by a word in the prologue of a
94 * function called by head/entry code.
99 * change the offset of the stack frame in the prologue of a function
100 * called by head/entry code. Examples:
101 *
102 * <start_secondary>:
103 * push %edi
104 * lea 0x8(%esp),%edi
105 * and $0xfffffff8,%esp
106 * pushl -0x4(%edi)
107 * push %ebp
108 * mov %esp,%ebp
109 *
110 * <x86_64_start_kernel>:
111 * lea 0x8(%rsp),%r10
112 * and $0xfffffffffffffff0,%rsp
113 * pushq -0x8(%r10)
114 * push %rbp
115 * mov %rsp,%rbp
116 *
117 * Note that after aligning the stack, it pushes a duplicate copy of
118 * the return address before pushing the frame pointer.
95 */
119 */
96 return bp == regs - FRAME_HEADER_SIZE ||
97 bp == regs - FRAME_HEADER_SIZE - sizeof(long);
120 return (state->bp == last_bp ||
121 (state->bp == aligned_bp && *(aligned_bp+1) == *(last_bp+1)));
98}
99
100/*
101 * This determines if the frame pointer actually contains an encoded pointer to
102 * pt_regs on the stack. See ENCODE_FRAME_POINTER.
103 */
104static struct pt_regs *decode_frame_pointer(unsigned long *bp)
105{

--- 195 unchanged lines hidden ---
122}
123
124/*
125 * This determines if the frame pointer actually contains an encoded pointer to
126 * pt_regs on the stack. See ENCODE_FRAME_POINTER.
127 */
128static struct pt_regs *decode_frame_pointer(unsigned long *bp)
129{

--- 195 unchanged lines hidden ---