Lines Matching +full:x +full:- +full:rp
1 // SPDX-License-Identifier: GPL-2.0
5 * (c) 2002-2004 Randolph Chung <tausq@debian.org>
7 * Derived partially from the IA64 implementation. The PA-RISC
21 #include <asm/asm-offsets.h>
30 #define dbg(x...) pr_debug(x) argument
32 #define dbg(x...) argument
56 hi = table->length - 1; in find_unwind_entry_in_table()
59 mid = (hi - lo) / 2 + lo; in find_unwind_entry_in_table()
60 e = &table->table[mid]; in find_unwind_entry_in_table()
61 if (addr < e->region_start) in find_unwind_entry_in_table()
62 hi = mid - 1; in find_unwind_entry_in_table()
63 else if (addr > e->region_end) in find_unwind_entry_in_table()
86 if (addr >= table->start && in find_unwind_entry()
87 addr <= table->end) in find_unwind_entry()
90 /* Move-to-front to exploit common traces */ in find_unwind_entry()
91 list_move(&table->list, &unwind_tables); in find_unwind_entry()
108 (struct unwind_table_entry *)table_end - 1; in unwind_table_init()
110 table->name = name; in unwind_table_init()
111 table->base_addr = base_addr; in unwind_table_init()
112 table->gp = gp; in unwind_table_init()
113 table->start = base_addr + start->region_start; in unwind_table_init()
114 table->end = base_addr + end->region_end; in unwind_table_init()
115 table->table = (struct unwind_table_entry *)table_start; in unwind_table_init()
116 table->length = end - start + 1; in unwind_table_init()
117 INIT_LIST_HEAD(&table->list); in unwind_table_init()
121 start->region_end > (start+1)->region_start) { in unwind_table_init()
126 start->region_start += base_addr; in unwind_table_init()
127 start->region_end += base_addr; in unwind_table_init()
133 return ((const struct unwind_table_entry *)a)->region_start in cmp_unwind_table_entry()
134 - ((const struct unwind_table_entry *)b)->region_start; in cmp_unwind_table_entry()
141 sort(start, finish - start, sizeof(struct unwind_table_entry), in unwind_table_sort()
162 list_add_tail(&table->list, &unwind_tables); in unwind_table_add()
173 list_del(&table->list); in unwind_table_remove()
188 dbg("unwind_init: start = 0x%lx, end = 0x%lx, entries = %lu\n", in unwind_init()
190 (stop - start) / sizeof(struct unwind_table_entry)); in unwind_init()
200 printk("region 0x%x-0x%x\n", in unwind_init()
218 * function pointers aren't a pointer to the function on 64-bit. in unwind_special()
233 struct pt_regs *regs = (struct pt_regs *)(info->sp - frame_size - PT_SZ_ALGN); in unwind_special()
235 info->prev_sp = regs->gr[30]; in unwind_special()
236 info->prev_ip = regs->iaoq[0]; in unwind_special()
242 info->prev_sp = info->prev_ip = 0; in unwind_special()
250 regs = (struct pt_regs *)(info->sp - PT_SZ_ALGN); in unwind_special()
251 info->prev_sp = regs->gr[30]; in unwind_special()
252 info->prev_ip = regs->iaoq[0]; in unwind_special()
253 info->rp = regs->gr[2]; in unwind_special()
259 info->prev_sp = info->sp - CALLEE_SAVE_FRAME_SIZE; in unwind_special()
260 info->prev_ip = *(unsigned long *)(info->prev_sp - RP_OFFSET); in unwind_special()
266 info->prev_sp = *(unsigned long *)(info->sp - FRAME_SIZE - REG_SZ); in unwind_special()
267 info->prev_ip = *(unsigned long *)(info->sp - FRAME_SIZE - RP_OFFSET); in unwind_special()
282 e = find_unwind_entry(info->ip); in unwind_frame_regs()
287 (void *) info->ip); in unwind_frame_regs()
290 we are adjusting the stack correctly or extracting the rp in unwind_frame_regs()
291 correctly. The rp is checked to see if it belongs to the in unwind_frame_regs()
296 sp = info->sp & ~63; in unwind_frame_regs()
300 info->prev_sp = sp - 64; in unwind_frame_regs()
301 info->prev_ip = 0; in unwind_frame_regs()
304 if ((info->prev_sp - (unsigned long) task_stack_page(info->t)) in unwind_frame_regs()
306 info->prev_sp = 0; in unwind_frame_regs()
311 (void *)info->prev_sp - RP_OFFSET, sizeof(tmp))) in unwind_frame_regs()
313 info->prev_ip = tmp; in unwind_frame_regs()
314 sp = info->prev_sp; in unwind_frame_regs()
315 } while (!kernel_text_address(info->prev_ip)); in unwind_frame_regs()
317 info->rp = 0; in unwind_frame_regs()
320 "prev_sp=%lx prev_ip=%lx\n", info->ip, in unwind_frame_regs()
321 info->prev_sp, info->prev_ip); in unwind_frame_regs()
323 dbg("e->start = 0x%x, e->end = 0x%x, Save_SP = %d, " in unwind_frame_regs()
325 e->region_start, e->region_end, e->Save_SP, e->Save_RP, in unwind_frame_regs()
326 e->Millicode, e->Total_frame_size); in unwind_frame_regs()
328 looking_for_rp = e->Save_RP; in unwind_frame_regs()
330 for (npc = e->region_start; in unwind_frame_regs()
331 (frame_size < (e->Total_frame_size << 3) || in unwind_frame_regs()
333 npc < info->ip; in unwind_frame_regs()
340 /* ldo X(sp), sp, or stwm X,D(sp) */ in unwind_frame_regs()
342 dbg("analyzing func @ %lx, insn=%08x @ " in unwind_frame_regs()
343 "%lx, frame_size = %ld\n", info->ip, in unwind_frame_regs()
346 /* std,ma X,D(sp) */ in unwind_frame_regs()
348 dbg("analyzing func @ %lx, insn=%08x @ " in unwind_frame_regs()
349 "%lx, frame_size = %ld\n", info->ip, in unwind_frame_regs()
352 /* stw rp,-20(sp) */ in unwind_frame_regs()
355 dbg("analyzing func @ %lx, insn=stw rp," in unwind_frame_regs()
356 "-20(sp) @ %lx\n", info->ip, npc); in unwind_frame_regs()
358 /* std rp,-16(sr0,sp) */ in unwind_frame_regs()
361 dbg("analyzing func @ %lx, insn=std rp," in unwind_frame_regs()
362 "-16(sp) @ %lx\n", info->ip, npc); in unwind_frame_regs()
366 if (frame_size > e->Total_frame_size << 3) in unwind_frame_regs()
367 frame_size = e->Total_frame_size << 3; in unwind_frame_regs()
369 if (!unwind_special(info, e->region_start, frame_size)) { in unwind_frame_regs()
370 info->prev_sp = info->sp - frame_size; in unwind_frame_regs()
371 if (e->Millicode) in unwind_frame_regs()
372 info->rp = info->r31; in unwind_frame_regs()
374 info->rp = *(unsigned long *)(info->prev_sp - rpoffset); in unwind_frame_regs()
375 info->prev_ip = info->rp; in unwind_frame_regs()
376 info->rp = 0; in unwind_frame_regs()
380 "prev_ip=%lx npc=%lx\n", info->ip, info->prev_sp, in unwind_frame_regs()
381 info->prev_ip, npc); in unwind_frame_regs()
389 info->t = t; in unwind_frame_init()
390 info->sp = regs->gr[30]; in unwind_frame_init()
391 info->ip = regs->iaoq[0]; in unwind_frame_init()
392 info->rp = regs->gr[2]; in unwind_frame_init()
393 info->r31 = regs->gr[31]; in unwind_frame_init()
396 t ? (int)t->pid : -1, info->sp, info->ip); in unwind_frame_init()
401 struct pt_regs *r = &t->thread.regs; in unwind_frame_init_from_blocked_task()
408 r2->gr[30] = r->ksp; in unwind_frame_init_from_blocked_task()
409 r2->iaoq[0] = r->kpc; in unwind_frame_init_from_blocked_task()
445 if (next_frame->prev_sp == 0 || in unwind_once()
446 next_frame->prev_ip == 0) in unwind_once()
447 return -1; in unwind_once()
449 next_frame->sp = next_frame->prev_sp; in unwind_once()
450 next_frame->ip = next_frame->prev_ip; in unwind_once()
451 next_frame->prev_sp = 0; in unwind_once()
452 next_frame->prev_ip = 0; in unwind_once()
455 next_frame->t ? (int)next_frame->t->pid : -1, in unwind_once()
456 next_frame->sp, next_frame->ip); in unwind_once()
467 } while (!ret && !(info->ip & 3)); in unwind_to_user()
486 } while (info.ip && level--); in return_address()