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>
31 #define dbg(x...) pr_debug(x) argument
33 #define dbg(x...) do { } while (0) argument
57 hi = table->length - 1; in find_unwind_entry_in_table()
60 mid = (hi - lo) / 2 + lo; in find_unwind_entry_in_table()
61 e = &table->table[mid]; in find_unwind_entry_in_table()
62 if (addr < e->region_start) in find_unwind_entry_in_table()
63 hi = mid - 1; in find_unwind_entry_in_table()
64 else if (addr > e->region_end) in find_unwind_entry_in_table()
87 if (addr >= table->start && in find_unwind_entry()
88 addr <= table->end) in find_unwind_entry()
91 /* Move-to-front to exploit common traces */ in find_unwind_entry()
92 list_move(&table->list, &unwind_tables); in find_unwind_entry()
109 (struct unwind_table_entry *)table_end - 1; in unwind_table_init()
111 table->name = name; in unwind_table_init()
112 table->base_addr = base_addr; in unwind_table_init()
113 table->gp = gp; in unwind_table_init()
114 table->start = base_addr + start->region_start; in unwind_table_init()
115 table->end = base_addr + end->region_end; in unwind_table_init()
116 table->table = (struct unwind_table_entry *)table_start; in unwind_table_init()
117 table->length = end - start + 1; in unwind_table_init()
118 INIT_LIST_HEAD(&table->list); in unwind_table_init()
122 start->region_end > (start+1)->region_start) { in unwind_table_init()
127 start->region_start += base_addr; in unwind_table_init()
128 start->region_end += base_addr; in unwind_table_init()
134 return ((const struct unwind_table_entry *)a)->region_start in cmp_unwind_table_entry()
135 - ((const struct unwind_table_entry *)b)->region_start; in cmp_unwind_table_entry()
142 sort(start, finish - start, sizeof(struct unwind_table_entry), in unwind_table_sort()
163 list_add_tail(&table->list, &unwind_tables); in unwind_table_add()
174 list_del(&table->list); in unwind_table_remove()
189 dbg("unwind_init: start = 0x%lx, end = 0x%lx, entries = %lu\n", in unwind_init()
191 (stop - start) / sizeof(struct unwind_table_entry)); in unwind_init()
201 printk("region 0x%x-0x%x\n", in unwind_init()
219 * function pointers aren't a pointer to the function on 64-bit. in unwind_special()
235 struct pt_regs *regs = (struct pt_regs *)(info->sp - frame_size - PT_SZ_ALGN); in unwind_special()
237 info->prev_sp = regs->gr[30]; in unwind_special()
238 info->prev_ip = regs->iaoq[0]; in unwind_special()
244 info->prev_sp = info->prev_ip = 0; in unwind_special()
252 regs = (struct pt_regs *)(info->sp - PT_SZ_ALGN); in unwind_special()
253 info->prev_sp = regs->gr[30]; in unwind_special()
254 info->prev_ip = regs->iaoq[0]; in unwind_special()
255 info->rp = regs->gr[2]; in unwind_special()
261 info->prev_sp = info->sp - CALLEE_SAVE_FRAME_SIZE; in unwind_special()
262 info->prev_ip = *(unsigned long *)(info->prev_sp - RP_OFFSET); in unwind_special()
268 info->prev_sp = *(unsigned long *)(info->sp - FRAME_SIZE - REG_SZ); in unwind_special()
269 info->prev_ip = *(unsigned long *)(info->sp - FRAME_SIZE - RP_OFFSET); in unwind_special()
284 e = find_unwind_entry(info->ip); in unwind_frame_regs()
289 (void *) info->ip); in unwind_frame_regs()
292 we are adjusting the stack correctly or extracting the rp in unwind_frame_regs()
293 correctly. The rp is checked to see if it belongs to the in unwind_frame_regs()
298 sp = info->sp & ~63; in unwind_frame_regs()
302 info->prev_sp = sp - 64; in unwind_frame_regs()
303 info->prev_ip = 0; in unwind_frame_regs()
306 if ((info->prev_sp - (unsigned long) task_stack_page(info->t)) in unwind_frame_regs()
308 info->prev_sp = 0; in unwind_frame_regs()
313 (void *)info->prev_sp - RP_OFFSET, sizeof(tmp))) in unwind_frame_regs()
315 info->prev_ip = tmp; in unwind_frame_regs()
316 sp = info->prev_sp; in unwind_frame_regs()
317 } while (!kernel_text_address(info->prev_ip)); in unwind_frame_regs()
319 info->rp = 0; in unwind_frame_regs()
322 "prev_sp=%lx prev_ip=%lx\n", info->ip, in unwind_frame_regs()
323 info->prev_sp, info->prev_ip); in unwind_frame_regs()
325 dbg("e->start = 0x%x, e->end = 0x%x, Save_SP = %d, " in unwind_frame_regs()
327 e->region_start, e->region_end, e->Save_SP, e->Save_RP, in unwind_frame_regs()
328 e->Millicode, e->Total_frame_size); in unwind_frame_regs()
330 looking_for_rp = e->Save_RP; in unwind_frame_regs()
332 for (npc = e->region_start; in unwind_frame_regs()
333 (frame_size < (e->Total_frame_size << 3) || in unwind_frame_regs()
335 npc < info->ip; in unwind_frame_regs()
342 /* ldo X(sp), sp, or stwm X,D(sp) */ in unwind_frame_regs()
344 dbg("analyzing func @ %lx, insn=%08x @ " in unwind_frame_regs()
345 "%lx, frame_size = %ld\n", info->ip, in unwind_frame_regs()
348 /* std,ma X,D(sp) */ in unwind_frame_regs()
350 dbg("analyzing func @ %lx, insn=%08x @ " in unwind_frame_regs()
351 "%lx, frame_size = %ld\n", info->ip, in unwind_frame_regs()
354 /* stw rp,-20(sp) */ in unwind_frame_regs()
357 dbg("analyzing func @ %lx, insn=stw rp," in unwind_frame_regs()
358 "-20(sp) @ %lx\n", info->ip, npc); in unwind_frame_regs()
360 /* std rp,-16(sr0,sp) */ in unwind_frame_regs()
363 dbg("analyzing func @ %lx, insn=std rp," in unwind_frame_regs()
364 "-16(sp) @ %lx\n", info->ip, npc); in unwind_frame_regs()
368 if (frame_size > e->Total_frame_size << 3) in unwind_frame_regs()
369 frame_size = e->Total_frame_size << 3; in unwind_frame_regs()
371 if (!unwind_special(info, e->region_start, frame_size)) { in unwind_frame_regs()
372 info->prev_sp = info->sp - frame_size; in unwind_frame_regs()
373 if (e->Millicode) in unwind_frame_regs()
374 info->rp = info->r31; in unwind_frame_regs()
376 info->rp = *(unsigned long *)(info->prev_sp - rpoffset); in unwind_frame_regs()
377 info->prev_ip = info->rp; in unwind_frame_regs()
378 info->rp = 0; in unwind_frame_regs()
382 "prev_ip=%lx npc=%lx\n", info->ip, info->prev_sp, in unwind_frame_regs()
383 info->prev_ip, npc); in unwind_frame_regs()
391 info->t = t; in unwind_frame_init()
392 info->sp = regs->gr[30]; in unwind_frame_init()
393 info->ip = regs->iaoq[0]; in unwind_frame_init()
394 info->rp = regs->gr[2]; in unwind_frame_init()
395 info->r31 = regs->gr[31]; in unwind_frame_init()
398 t ? (int)t->pid : -1, info->sp, info->ip); in unwind_frame_init()
403 struct pt_regs *r = &t->thread.regs; in unwind_frame_init_from_blocked_task()
410 r2->gr[30] = r->ksp; in unwind_frame_init_from_blocked_task()
411 r2->iaoq[0] = r->kpc; in unwind_frame_init_from_blocked_task()
447 if (next_frame->prev_sp == 0 || in unwind_once()
448 next_frame->prev_ip == 0) in unwind_once()
449 return -1; in unwind_once()
451 next_frame->sp = next_frame->prev_sp; in unwind_once()
452 next_frame->ip = next_frame->prev_ip; in unwind_once()
453 next_frame->prev_sp = 0; in unwind_once()
454 next_frame->prev_ip = 0; in unwind_once()
457 next_frame->t ? (int)next_frame->t->pid : -1, in unwind_once()
458 next_frame->sp, next_frame->ip); in unwind_once()
469 } while (!ret && !(info->ip & 3)); in unwind_to_user()
488 } while (info.ip && level--); in return_address()