Lines Matching +full:spare +full:- +full:regs

1 // SPDX-License-Identifier: GPL-2.0-only
68 enum regs { enum
89 /* sign-extend to 32 bits */ \
100 * stop - 1 = last entry
124 addr_prel31 = (addr - (unsigned long)start) & 0x7fffffff; in search_index()
126 while (start < stop - 1) { in search_index()
127 const struct unwind_idx *mid = start + ((stop - start) >> 1); in search_index()
133 if (addr_prel31 - ((unsigned long)mid - (unsigned long)start) < in search_index()
134 mid->addr_offset) in search_index()
138 addr_prel31 -= ((unsigned long)mid - in search_index()
144 if (likely(start->addr_offset <= addr_prel31)) in search_index()
157 const struct unwind_idx *mid = start + ((stop - start) >> 1); in unwind_find_origin()
159 if (mid->addr_offset >= 0x40000000) in unwind_find_origin()
166 pr_debug("%s -> %p\n", __func__, stop); in unwind_find_origin()
193 if (addr >= table->begin_addr && in unwind_find_idx()
194 addr < table->end_addr) { in unwind_find_idx()
195 idx = search_index(addr, table->start, in unwind_find_idx()
196 table->origin, in unwind_find_idx()
197 table->stop); in unwind_find_idx()
198 /* Move-to-front to exploit common traces */ in unwind_find_idx()
199 list_move(&table->list, &unwind_tables); in unwind_find_idx()
214 if (ctrl->entries <= 0) { in unwind_get_byte()
219 ret = (*ctrl->insn >> (ctrl->byte * 8)) & 0xff; in unwind_get_byte()
221 if (ctrl->byte == 0) { in unwind_get_byte()
222 ctrl->insn++; in unwind_get_byte()
223 ctrl->entries--; in unwind_get_byte()
224 ctrl->byte = 3; in unwind_get_byte()
226 ctrl->byte--; in unwind_get_byte()
235 if (unlikely(ctrl->check_each_pop)) in unwind_pop_register()
236 if (*vsp >= (unsigned long *)ctrl->sp_high) in unwind_pop_register()
237 return -URC_FAILURE; in unwind_pop_register()
242 ctrl->vrs[reg] = READ_ONCE_NOCHECK(*(*vsp)); in unwind_pop_register()
244 ctrl->lr_addr = *vsp; in unwind_pop_register()
253 unsigned long *vsp = (unsigned long *)ctrl->vrs[SP]; in unwind_exec_pop_subset_r4_to_r13()
256 load_sp = mask & (1 << (13 - 4)); in unwind_exec_pop_subset_r4_to_r13()
260 return -URC_FAILURE; in unwind_exec_pop_subset_r4_to_r13()
265 ctrl->vrs[SP] = (unsigned long)vsp; in unwind_exec_pop_subset_r4_to_r13()
274 unsigned long *vsp = (unsigned long *)ctrl->vrs[SP]; in unwind_exec_pop_r4_to_rN()
277 /* pop R4-R[4+bbb] */ in unwind_exec_pop_r4_to_rN()
280 return -URC_FAILURE; in unwind_exec_pop_r4_to_rN()
284 return -URC_FAILURE; in unwind_exec_pop_r4_to_rN()
286 ctrl->vrs[SP] = (unsigned long)vsp; in unwind_exec_pop_r4_to_rN()
294 unsigned long *vsp = (unsigned long *)ctrl->vrs[SP]; in unwind_exec_pop_subset_r0_to_r3()
297 /* pop R0-R3 according to mask */ in unwind_exec_pop_subset_r0_to_r3()
301 return -URC_FAILURE; in unwind_exec_pop_subset_r0_to_r3()
305 ctrl->vrs[SP] = (unsigned long)vsp; in unwind_exec_pop_subset_r0_to_r3()
321 ctrl->vrs[SP] += ((insn & 0x3f) << 2) + 4; in unwind_exec_insn()
323 ctrl->vrs[SP] -= ((insn & 0x3f) << 2) + 4; in unwind_exec_insn()
332 return -URC_FAILURE; in unwind_exec_insn()
340 ctrl->vrs[SP] = ctrl->vrs[insn & 0x0f]; in unwind_exec_insn()
346 if (ctrl->vrs[PC] == 0) in unwind_exec_insn()
347 ctrl->vrs[PC] = ctrl->vrs[LR]; in unwind_exec_insn()
349 ctrl->entries = 0; in unwind_exec_insn()
354 pr_warn("unwind: Spare encoding %04lx\n", in unwind_exec_insn()
356 return -URC_FAILURE; in unwind_exec_insn()
365 ctrl->vrs[SP] += 0x204 + (uleb128 << 2); in unwind_exec_insn()
368 return -URC_FAILURE; in unwind_exec_insn()
372 ctrl->vrs[FP], ctrl->vrs[SP], ctrl->vrs[LR], ctrl->vrs[PC]); in unwind_exec_insn()
389 sp_low = frame->sp; in unwind_frame()
390 ctrl.sp_high = ALIGN(sp_low - THREAD_SIZE, THREAD_ALIGN) in unwind_frame()
394 frame->pc, frame->lr, frame->sp); in unwind_frame()
396 idx = unwind_find_idx(frame->pc); in unwind_frame()
398 if (frame->pc && kernel_text_address(frame->pc)) in unwind_frame()
399 pr_warn("unwind: Index not found %08lx\n", frame->pc); in unwind_frame()
400 return -URC_FAILURE; in unwind_frame()
403 ctrl.vrs[FP] = frame->fp; in unwind_frame()
404 ctrl.vrs[SP] = frame->sp; in unwind_frame()
405 ctrl.vrs[LR] = frame->lr; in unwind_frame()
408 if (idx->insn == 1) in unwind_frame()
410 return -URC_FAILURE; in unwind_frame()
411 else if (frame->pc == prel31_to_addr(&idx->addr_offset)) { in unwind_frame()
420 if (frame->pc == frame->lr) in unwind_frame()
421 return -URC_FAILURE; in unwind_frame()
422 frame->pc = frame->lr; in unwind_frame()
424 } else if ((idx->insn & 0x80000000) == 0) in unwind_frame()
426 ctrl.insn = (unsigned long *)prel31_to_addr(&idx->insn); in unwind_frame()
427 else if ((idx->insn & 0xff000000) == 0x80000000) in unwind_frame()
429 ctrl.insn = &idx->insn; in unwind_frame()
432 idx->insn, idx); in unwind_frame()
433 return -URC_FAILURE; in unwind_frame()
446 return -URC_FAILURE; in unwind_frame()
451 if (prel31_to_addr(&idx->addr_offset) == (u32)&call_with_stack) { in unwind_frame()
457 sp_low = frame->fp; in unwind_frame()
458 ctrl.sp_high = ALIGN(frame->fp, THREAD_SIZE); in unwind_frame()
463 if ((ctrl.sp_high - ctrl.vrs[SP]) < sizeof(ctrl.vrs)) in unwind_frame()
469 return -URC_FAILURE; in unwind_frame()
476 if (frame->pc == ctrl.vrs[PC] && frame->sp == ctrl.vrs[SP]) in unwind_frame()
477 return -URC_FAILURE; in unwind_frame()
479 frame->fp = ctrl.vrs[FP]; in unwind_frame()
480 frame->sp = ctrl.vrs[SP]; in unwind_frame()
481 frame->lr = ctrl.vrs[LR]; in unwind_frame()
482 frame->pc = ctrl.vrs[PC]; in unwind_frame()
483 frame->lr_addr = ctrl.lr_addr; in unwind_frame()
488 void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk, in unwind_backtrace() argument
493 pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk); in unwind_backtrace()
498 if (regs) { in unwind_backtrace()
499 arm_get_current_stackframe(regs, &frame); in unwind_backtrace()
501 if (!kernel_text_address(regs->ARM_pc)) in unwind_backtrace()
502 frame.pc = regs->ARM_lr; in unwind_backtrace()
532 dump_backtrace_entry(where, frame.pc, frame.sp - 4, loglvl); in unwind_backtrace()
549 tab->start = (const struct unwind_idx *)start; in unwind_table_add()
550 tab->stop = (const struct unwind_idx *)(start + size); in unwind_table_add()
551 tab->origin = unwind_find_origin(tab->start, tab->stop); in unwind_table_add()
552 tab->begin_addr = text_addr; in unwind_table_add()
553 tab->end_addr = text_addr + text_size; in unwind_table_add()
556 list_add_tail(&tab->list, &unwind_tables); in unwind_table_add()
570 list_del(&tab->list); in unwind_table_del()