1 // SPDX-License-Identifier: GPL-2.0
3 * Kernel unwinding support
5 * (c) 2002-2004 Randolph Chung <tausq@debian.org>
7 * Derived partially from the IA64 implementation. The PA-RISC
8 * Runtime Architecture Document is also a useful reference to
9 * understand what is happening here
12 #include <linux/kernel.h>
13 #include <linux/init.h>
14 #include <linux/sched.h>
15 #include <linux/slab.h>
16 #include <linux/sort.h>
18 #include <linux/uaccess.h>
19 #include <asm/assembly.h>
20 #include <asm/asm-offsets.h>
21 #include <asm/ptrace.h>
23 #include <asm/unwind.h>
24 #include <asm/switch_to.h>
25 #include <asm/sections.h>
29 #define dbg(x...) pr_debug(x)
34 #define KERNEL_START (KERNEL_BINARY_TEXT_START)
36 extern struct unwind_table_entry __start___unwind[];
37 extern struct unwind_table_entry __stop___unwind[];
39 static DEFINE_SPINLOCK(unwind_lock);
41 * the kernel unwind block is not dynamically allocated so that
42 * we can call unwind_init as early in the bootup process as
43 * possible (before the slab allocator is initialized)
45 static struct unwind_table kernel_unwind_table __read_mostly;
46 static LIST_HEAD(unwind_tables);
48 static inline const struct unwind_table_entry *
49 find_unwind_entry_in_table(const struct unwind_table *table, unsigned long addr)
51 const struct unwind_table_entry *e = NULL;
52 unsigned long lo, hi, mid;
55 hi = table->length - 1;
58 mid = (hi - lo) / 2 + lo;
59 e = &table->table[mid];
60 if (addr < e->region_start)
62 else if (addr > e->region_end)
71 static const struct unwind_table_entry *
72 find_unwind_entry(unsigned long addr)
74 struct unwind_table *table;
75 const struct unwind_table_entry *e = NULL;
77 if (addr >= kernel_unwind_table.start &&
78 addr <= kernel_unwind_table.end)
79 e = find_unwind_entry_in_table(&kernel_unwind_table, addr);
83 spin_lock_irqsave(&unwind_lock, flags);
84 list_for_each_entry(table, &unwind_tables, list) {
85 if (addr >= table->start &&
87 e = find_unwind_entry_in_table(table, addr);
89 /* Move-to-front to exploit common traces */
90 list_move(&table->list, &unwind_tables);
94 spin_unlock_irqrestore(&unwind_lock, flags);
101 unwind_table_init(struct unwind_table *table, const char *name,
102 unsigned long base_addr, unsigned long gp,
103 void *table_start, void *table_end)
105 struct unwind_table_entry *start = table_start;
106 struct unwind_table_entry *end =
107 (struct unwind_table_entry *)table_end - 1;
110 table->base_addr = base_addr;
112 table->start = base_addr + start->region_start;
113 table->end = base_addr + end->region_end;
114 table->table = (struct unwind_table_entry *)table_start;
115 table->length = end - start + 1;
116 INIT_LIST_HEAD(&table->list);
118 for (; start <= end; start++) {
120 start->region_end > (start+1)->region_start) {
121 pr_warn("Out of order unwind entry! %px and %px\n",
125 start->region_start += base_addr;
126 start->region_end += base_addr;
130 static int cmp_unwind_table_entry(const void *a, const void *b)
132 return ((const struct unwind_table_entry *)a)->region_start
133 - ((const struct unwind_table_entry *)b)->region_start;
137 unwind_table_sort(struct unwind_table_entry *start,
138 struct unwind_table_entry *finish)
140 sort(start, finish - start, sizeof(struct unwind_table_entry),
141 cmp_unwind_table_entry, NULL);
144 struct unwind_table *
145 unwind_table_add(const char *name, unsigned long base_addr,
147 void *start, void *end)
149 struct unwind_table *table;
151 struct unwind_table_entry *s = (struct unwind_table_entry *)start;
152 struct unwind_table_entry *e = (struct unwind_table_entry *)end;
154 unwind_table_sort(s, e);
156 table = kmalloc(sizeof(struct unwind_table), GFP_USER);
159 unwind_table_init(table, name, base_addr, gp, start, end);
160 spin_lock_irqsave(&unwind_lock, flags);
161 list_add_tail(&table->list, &unwind_tables);
162 spin_unlock_irqrestore(&unwind_lock, flags);
167 void unwind_table_remove(struct unwind_table *table)
171 spin_lock_irqsave(&unwind_lock, flags);
172 list_del(&table->list);
173 spin_unlock_irqrestore(&unwind_lock, flags);
178 /* Called from setup_arch to import the kernel unwind info */
179 int __init unwind_init(void)
182 register unsigned long gp __asm__ ("r27");
184 start = (long)&__start___unwind[0];
185 stop = (long)&__stop___unwind[0];
187 dbg("unwind_init: start = 0x%lx, end = 0x%lx, entries = %lu\n",
189 (stop - start) / sizeof(struct unwind_table_entry));
191 unwind_table_init(&kernel_unwind_table, "kernel", KERNEL_START,
193 &__start___unwind[0], &__stop___unwind[0]);
197 for (i = 0; i < 10; i++)
199 printk("region 0x%x-0x%x\n",
200 __start___unwind[i].region_start,
201 __start___unwind[i].region_end);
208 static bool pc_is_kernel_fn(unsigned long pc, void *fn)
210 return (unsigned long)dereference_kernel_function_descriptor(fn) == pc;
213 static int unwind_special(struct unwind_frame_info *info, unsigned long pc, int frame_size)
216 * We have to use void * instead of a function pointer, because
217 * function pointers aren't a pointer to the function on 64-bit.
218 * Make them const so the compiler knows they live in .text
219 * Note: We could use dereference_kernel_function_descriptor()
220 * instead but we want to keep it simple here.
222 extern void * const handle_interruption;
223 extern void * const ret_from_kernel_thread;
224 extern void * const syscall_exit;
225 extern void * const intr_return;
226 extern void * const _switch_to_ret;
227 #ifdef CONFIG_IRQSTACKS
228 extern void * const _call_on_stack;
229 #endif /* CONFIG_IRQSTACKS */
231 if (pc_is_kernel_fn(pc, handle_interruption)) {
232 struct pt_regs *regs = (struct pt_regs *)(info->sp - frame_size - PT_SZ_ALGN);
233 dbg("Unwinding through handle_interruption()\n");
234 info->prev_sp = regs->gr[30];
235 info->prev_ip = regs->iaoq[0];
239 if (pc_is_kernel_fn(pc, ret_from_kernel_thread) ||
240 pc_is_kernel_fn(pc, syscall_exit)) {
241 info->prev_sp = info->prev_ip = 0;
245 if (pc_is_kernel_fn(pc, intr_return)) {
246 struct pt_regs *regs;
248 dbg("Found intr_return()\n");
249 regs = (struct pt_regs *)(info->sp - PT_SZ_ALGN);
250 info->prev_sp = regs->gr[30];
251 info->prev_ip = regs->iaoq[0];
252 info->rp = regs->gr[2];
256 if (pc_is_kernel_fn(pc, _switch_to) ||
257 pc_is_kernel_fn(pc, _switch_to_ret)) {
258 info->prev_sp = info->sp - CALLEE_SAVE_FRAME_SIZE;
259 info->prev_ip = *(unsigned long *)(info->prev_sp - RP_OFFSET);
263 #ifdef CONFIG_IRQSTACKS
264 if (pc_is_kernel_fn(pc, _call_on_stack)) {
265 info->prev_sp = *(unsigned long *)(info->sp - FRAME_SIZE - REG_SZ);
266 info->prev_ip = *(unsigned long *)(info->sp - FRAME_SIZE - RP_OFFSET);
273 static void unwind_frame_regs(struct unwind_frame_info *info)
275 const struct unwind_table_entry *e;
279 int looking_for_rp, rpoffset = 0;
281 e = find_unwind_entry(info->ip);
285 dbg("Cannot find unwind entry for %pS; forced unwinding\n",
288 /* Since we are doing the unwinding blind, we don't know if
289 we are adjusting the stack correctly or extracting the rp
290 correctly. The rp is checked to see if it belongs to the
291 kernel text section, if not we assume we don't have a
292 correct stack frame and we continue to unwind the stack.
293 This is not quite correct, and will fail for loadable
299 info->prev_sp = sp - 64;
302 /* The stack is at the end inside the thread_union
303 * struct. If we reach data, we have reached the
304 * beginning of the stack and should stop unwinding. */
305 if (info->prev_sp >= (unsigned long) task_thread_info(info->t) &&
306 info->prev_sp < ((unsigned long) task_thread_info(info->t)
312 if (get_user(tmp, (unsigned long *)(info->prev_sp - RP_OFFSET)))
316 } while (!kernel_text_address(info->prev_ip));
320 dbg("analyzing func @ %lx with no unwind info, setting "
321 "prev_sp=%lx prev_ip=%lx\n", info->ip,
322 info->prev_sp, info->prev_ip);
324 dbg("e->start = 0x%x, e->end = 0x%x, Save_SP = %d, "
325 "Save_RP = %d, Millicode = %d size = %u\n",
326 e->region_start, e->region_end, e->Save_SP, e->Save_RP,
327 e->Millicode, e->Total_frame_size);
329 looking_for_rp = e->Save_RP;
331 for (npc = e->region_start;
332 (frame_size < (e->Total_frame_size << 3) ||
337 insn = *(unsigned int *)npc;
339 if ((insn & 0xffffc001) == 0x37de0000 ||
340 (insn & 0xffe00001) == 0x6fc00000) {
341 /* ldo X(sp), sp, or stwm X,D(sp) */
342 frame_size += (insn & 0x3fff) >> 1;
343 dbg("analyzing func @ %lx, insn=%08x @ "
344 "%lx, frame_size = %ld\n", info->ip,
345 insn, npc, frame_size);
346 } else if ((insn & 0xffe00009) == 0x73c00008) {
348 frame_size += ((insn >> 4) & 0x3ff) << 3;
349 dbg("analyzing func @ %lx, insn=%08x @ "
350 "%lx, frame_size = %ld\n", info->ip,
351 insn, npc, frame_size);
352 } else if (insn == 0x6bc23fd9) {
356 dbg("analyzing func @ %lx, insn=stw rp,"
357 "-20(sp) @ %lx\n", info->ip, npc);
358 } else if (insn == 0x0fc212c1) {
359 /* std rp,-16(sr0,sp) */
362 dbg("analyzing func @ %lx, insn=std rp,"
363 "-16(sp) @ %lx\n", info->ip, npc);
367 if (frame_size > e->Total_frame_size << 3)
368 frame_size = e->Total_frame_size << 3;
370 if (!unwind_special(info, e->region_start, frame_size)) {
371 info->prev_sp = info->sp - frame_size;
373 info->rp = info->r31;
375 info->rp = *(unsigned long *)(info->prev_sp - rpoffset);
376 info->prev_ip = info->rp;
380 dbg("analyzing func @ %lx, setting prev_sp=%lx "
381 "prev_ip=%lx npc=%lx\n", info->ip, info->prev_sp,
386 void unwind_frame_init(struct unwind_frame_info *info, struct task_struct *t,
387 struct pt_regs *regs)
389 memset(info, 0, sizeof(struct unwind_frame_info));
391 info->sp = regs->gr[30];
392 info->ip = regs->iaoq[0];
393 info->rp = regs->gr[2];
394 info->r31 = regs->gr[31];
396 dbg("(%d) Start unwind from sp=%08lx ip=%08lx\n",
397 t ? (int)t->pid : -1, info->sp, info->ip);
400 void unwind_frame_init_from_blocked_task(struct unwind_frame_info *info, struct task_struct *t)
402 struct pt_regs *r = &t->thread.regs;
405 r2 = kmalloc(sizeof(struct pt_regs), GFP_ATOMIC);
410 r2->iaoq[0] = r->kpc;
411 unwind_frame_init(info, t, r2);
415 #define get_parisc_stackpointer() ({ \
417 __asm__("copy %%r30, %0" : "=r"(sp)); \
421 void unwind_frame_init_task(struct unwind_frame_info *info,
422 struct task_struct *task, struct pt_regs *regs)
424 task = task ? task : current;
426 if (task == current) {
430 memset(&r, 0, sizeof(r));
431 r.iaoq[0] = _THIS_IP_;
433 r.gr[30] = get_parisc_stackpointer();
436 unwind_frame_init(info, task, regs);
438 unwind_frame_init_from_blocked_task(info, task);
442 int unwind_once(struct unwind_frame_info *next_frame)
444 unwind_frame_regs(next_frame);
446 if (next_frame->prev_sp == 0 ||
447 next_frame->prev_ip == 0)
450 next_frame->sp = next_frame->prev_sp;
451 next_frame->ip = next_frame->prev_ip;
452 next_frame->prev_sp = 0;
453 next_frame->prev_ip = 0;
455 dbg("(%d) Continue unwind to sp=%08lx ip=%08lx\n",
456 next_frame->t ? (int)next_frame->t->pid : -1,
457 next_frame->sp, next_frame->ip);
462 int unwind_to_user(struct unwind_frame_info *info)
467 ret = unwind_once(info);
468 } while (!ret && !(info->ip & 3));
473 unsigned long return_address(unsigned int level)
475 struct unwind_frame_info info;
477 /* initialize unwind info */
478 unwind_frame_init_task(&info, current, NULL);
483 if (unwind_once(&info) < 0 || info.ip == 0)
485 if (!kernel_text_address(info.ip))
487 } while (info.ip && level--);