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 --- |