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
20 #include <asm/asm-offsets.h>
27 #define dbg(x...) pr_debug(x) argument
29 #define dbg(x...) argument
53 hi = table->length - 1; in find_unwind_entry_in_table()
56 mid = (hi - lo) / 2 + lo; in find_unwind_entry_in_table()
57 e = &table->table[mid]; in find_unwind_entry_in_table()
58 if (addr < e->region_start) in find_unwind_entry_in_table()
59 hi = mid - 1; in find_unwind_entry_in_table()
60 else if (addr > e->region_end) in find_unwind_entry_in_table()
83 if (addr >= table->start && in find_unwind_entry()
84 addr <= table->end) in find_unwind_entry()
87 /* Move-to-front to exploit common traces */ in find_unwind_entry()
88 list_move(&table->list, &unwind_tables); in find_unwind_entry()
105 (struct unwind_table_entry *)table_end - 1; in unwind_table_init()
107 table->name = name; in unwind_table_init()
108 table->base_addr = base_addr; in unwind_table_init()
109 table->gp = gp; in unwind_table_init()
110 table->start = base_addr + start->region_start; in unwind_table_init()
111 table->end = base_addr + end->region_end; in unwind_table_init()
112 table->table = (struct unwind_table_entry *)table_start; in unwind_table_init()
113 table->length = end - start + 1; in unwind_table_init()
114 INIT_LIST_HEAD(&table->list); in unwind_table_init()
118 start->region_end > (start+1)->region_start) { in unwind_table_init()
123 start->region_start += base_addr; in unwind_table_init()
124 start->region_end += base_addr; in unwind_table_init()
130 return ((const struct unwind_table_entry *)a)->region_start in cmp_unwind_table_entry()
131 - ((const struct unwind_table_entry *)b)->region_start; in cmp_unwind_table_entry()
138 sort(start, finish - start, sizeof(struct unwind_table_entry), in unwind_table_sort()
159 list_add_tail(&table->list, &unwind_tables); in unwind_table_add()
170 list_del(&table->list); in unwind_table_remove()
185 dbg("unwind_init: start = 0x%lx, end = 0x%lx, entries = %lu\n", in unwind_init()
187 (stop - start) / sizeof(struct unwind_table_entry)); in unwind_init()
197 printk("region 0x%x-0x%x\n", in unwind_init()
210 * function pointers aren't a pointer to the function on 64-bit. in unwind_special()
225 struct pt_regs *regs = (struct pt_regs *)(info->sp - frame_size - PT_SZ_ALGN); in unwind_special()
227 info->prev_sp = regs->gr[30]; in unwind_special()
228 info->prev_ip = regs->iaoq[0]; in unwind_special()
234 info->prev_sp = info->prev_ip = 0; in unwind_special()
242 regs = (struct pt_regs *)(info->sp - PT_SZ_ALGN); in unwind_special()
243 info->prev_sp = regs->gr[30]; in unwind_special()
244 info->prev_ip = regs->iaoq[0]; in unwind_special()
245 info->rp = regs->gr[2]; in unwind_special()
250 info->prev_sp = info->sp - CALLEE_SAVE_FRAME_SIZE; in unwind_special()
251 info->prev_ip = *(unsigned long *)(info->prev_sp - RP_OFFSET); in unwind_special()
257 info->prev_sp = *(unsigned long *)(info->sp - FRAME_SIZE - REG_SZ); in unwind_special()
258 info->prev_ip = *(unsigned long *)(info->sp - FRAME_SIZE - RP_OFFSET); in unwind_special()
274 e = find_unwind_entry(info->ip); in unwind_frame_regs()
279 (void *) info->ip); in unwind_frame_regs()
282 we are adjusting the stack correctly or extracting the rp in unwind_frame_regs()
283 correctly. The rp is checked to see if it belongs to the in unwind_frame_regs()
288 sp = info->sp & ~63; in unwind_frame_regs()
292 info->prev_sp = sp - 64; in unwind_frame_regs()
293 info->prev_ip = 0; in unwind_frame_regs()
298 if (info->prev_sp >= (unsigned long) task_thread_info(info->t) && in unwind_frame_regs()
299 info->prev_sp < ((unsigned long) task_thread_info(info->t) in unwind_frame_regs()
301 info->prev_sp = 0; in unwind_frame_regs()
305 if (get_user(tmp, (unsigned long *)(info->prev_sp - RP_OFFSET))) in unwind_frame_regs()
307 info->prev_ip = tmp; in unwind_frame_regs()
308 sp = info->prev_sp; in unwind_frame_regs()
309 } while (!kernel_text_address(info->prev_ip)); in unwind_frame_regs()
311 info->rp = 0; in unwind_frame_regs()
314 "prev_sp=%lx prev_ip=%lx\n", info->ip, in unwind_frame_regs()
315 info->prev_sp, info->prev_ip); in unwind_frame_regs()
317 dbg("e->start = 0x%x, e->end = 0x%x, Save_SP = %d, " in unwind_frame_regs()
319 e->region_start, e->region_end, e->Save_SP, e->Save_RP, in unwind_frame_regs()
320 e->Millicode, e->Total_frame_size); in unwind_frame_regs()
322 looking_for_rp = e->Save_RP; in unwind_frame_regs()
324 for (npc = e->region_start; in unwind_frame_regs()
325 (frame_size < (e->Total_frame_size << 3) || in unwind_frame_regs()
327 npc < info->ip; in unwind_frame_regs()
334 /* ldo X(sp), sp, or stwm X,D(sp) */ in unwind_frame_regs()
336 dbg("analyzing func @ %lx, insn=%08x @ " in unwind_frame_regs()
337 "%lx, frame_size = %ld\n", info->ip, in unwind_frame_regs()
340 /* std,ma 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 /* stw rp,-20(sp) */ in unwind_frame_regs()
349 dbg("analyzing func @ %lx, insn=stw rp," in unwind_frame_regs()
350 "-20(sp) @ %lx\n", info->ip, npc); in unwind_frame_regs()
352 /* std rp,-16(sr0,sp) */ in unwind_frame_regs()
355 dbg("analyzing func @ %lx, insn=std rp," in unwind_frame_regs()
356 "-16(sp) @ %lx\n", info->ip, npc); in unwind_frame_regs()
360 if (frame_size > e->Total_frame_size << 3) in unwind_frame_regs()
361 frame_size = e->Total_frame_size << 3; in unwind_frame_regs()
363 if (!unwind_special(info, e->region_start, frame_size)) { in unwind_frame_regs()
364 info->prev_sp = info->sp - frame_size; in unwind_frame_regs()
365 if (e->Millicode) in unwind_frame_regs()
366 info->rp = info->r31; in unwind_frame_regs()
368 info->rp = *(unsigned long *)(info->prev_sp - rpoffset); in unwind_frame_regs()
369 info->prev_ip = info->rp; in unwind_frame_regs()
370 info->rp = 0; in unwind_frame_regs()
374 "prev_ip=%lx npc=%lx\n", info->ip, info->prev_sp, in unwind_frame_regs()
375 info->prev_ip, npc); in unwind_frame_regs()
383 info->t = t; in unwind_frame_init()
384 info->sp = regs->gr[30]; in unwind_frame_init()
385 info->ip = regs->iaoq[0]; in unwind_frame_init()
386 info->rp = regs->gr[2]; in unwind_frame_init()
387 info->r31 = regs->gr[31]; in unwind_frame_init()
390 t ? (int)t->pid : -1, info->sp, info->ip); in unwind_frame_init()
395 struct pt_regs *r = &t->thread.regs; in unwind_frame_init_from_blocked_task()
402 r2->gr[30] = r->ksp; in unwind_frame_init_from_blocked_task()
403 r2->iaoq[0] = r->kpc; in unwind_frame_init_from_blocked_task()
439 if (next_frame->prev_sp == 0 || in unwind_once()
440 next_frame->prev_ip == 0) in unwind_once()
441 return -1; in unwind_once()
443 next_frame->sp = next_frame->prev_sp; in unwind_once()
444 next_frame->ip = next_frame->prev_ip; in unwind_once()
445 next_frame->prev_sp = 0; in unwind_once()
446 next_frame->prev_ip = 0; in unwind_once()
449 next_frame->t ? (int)next_frame->t->pid : -1, in unwind_once()
450 next_frame->sp, next_frame->ip); in unwind_once()
461 } while (!ret && !(info->ip & 3)); in unwind_to_user()
480 } while (info.ip && level--); in return_address()