Lines Matching +full:early +full:- +full:to +full:- +full:mid
2 * Copyright 2013-2014 Andrew Turner.
3 * Copyright 2013-2014 Ian Lepore.
4 * Copyright 2013-2014 Rui Paulo.
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
47 * The ARM EABI specifies how to perform the frame unwinding in the
48 * Exception Handling ABI for the ARM Architecture document. To perform
49 * the unwind we need to know the initial frame pointer, stack pointer,
51 * index table that points to the function the program counter is within.
52 * This gives us either a list of three instructions to process, a 31-bit
53 * relative offset to a table of instructions, or a value telling us
56 * When we have the instructions to process we need to decode them
58 * patterns to encode that steps to take to update the stack pointer and
59 * link register to the correct values at the start of the function.
62 /* A special case when we are unable to unwind past this function */
101 * To unwind the stack through the code in a loaded module, we need to access
102 * the module's exidx unwind data. To locate that data, one must search the
108 * function calls into this code to pass along the unwind info, which we save
111 * Because we have to help stack(9) gather stack info at any time, including in
113 * to walk the kernel's list of linker_file structs, because doing so requires
116 * synthesize at init time). New entries are added to the end of this list as
118 * cleared out in-place to mark them as unused. That means the code doing stack
120 * structure of the list never changes in a way that would cause the walker to
123 * A cleared-out entry on the list has module start=UINTPTR_MAX and end=0, so
125 * We also don't have to worry about races where we look up the unwind info just
126 * before a module is unloaded and try to access it concurrently with or just
128 * execution leads through a now-unloaded module, and that's already well into
129 * undefined-behavior territory.
141 link; /* Link to next entry */
146 * Hide ugly casting in somewhat-less-ugly macros.
147 * CADDR - cast a pointer or number to caddr_t.
148 * UADDR - cast a pointer or number to uintptr_t.
155 * module_start/end addresses are set to values that cannot match any real
162 info->module_start = UINTPTR_MAX; in clear_module_info()
163 info->module_end = 0; in clear_module_info()
178 info->exidx_start = UADDR(lf->exidx_addr); in populate_module_info()
179 info->exidx_end = UADDR(lf->exidx_addr) + lf->exidx_size; in populate_module_info()
180 info->module_start = UADDR(lf->address); in populate_module_info()
181 info->module_end = UADDR(lf->address) + lf->size; in populate_module_info()
185 * Create a new empty module_info entry and add it to the tail of the list.
201 * zero), then we're looking for an empty item to reuse, which is indicated by
202 * module_start being set to UINTPTR_MAX in the entry.
210 if ((addr >= info->module_start && addr < info->module_end) || in find_module_info()
211 (addr == 0 && info->module_start == UINTPTR_MAX)) in find_module_info()
230 if (lf->exidx_size == 0) in unwind_module_loaded()
234 * Find an unused entry in the existing list to reuse. If we don't find in unwind_module_loaded()
236 * place the module_list is modified. Adding a new entry to the list in unwind_module_loaded()
239 * to prevent its module list from being modified, so we don't have to in unwind_module_loaded()
258 if (lf->exidx_size == 0) in unwind_module_unloaded()
265 if ((info = find_module_info(UADDR(lf->address))) == NULL) { in unwind_module_unloaded()
267 lf->filename); in unwind_module_unloaded()
274 * Initialization must run fairly early, as soon as malloc(9) is available, and
278 * the unwind tables might be stripped, so instead we have to use the
290 thekernel.size = UADDR(&_end) - UADDR(&_start); in module_info_init()
292 thekernel.exidx_size = UADDR(&_exidx_end) - UADDR(&_exidx_start); in module_info_init()
299 /* Expand a 31-bit signed value to a 32-bit signed value */
308 * Perform a binary search of the index table to find the function
315 unsigned int min, mid, max; in find_index() local
326 max = (info->exidx_end - info->exidx_start) / sizeof(struct unwind_idx); in find_index()
327 start = (struct unwind_idx *)CADDR(info->exidx_start); in find_index()
330 mid = min + (max - min + 1) / 2; in find_index()
332 item = &start[mid]; in find_index()
334 prel31_addr = expand_prel31(item->offset); in find_index()
335 func_addr = (uint32_t)&item->offset + prel31_addr; in find_index()
338 min = mid; in find_index()
340 max = mid - 1; in find_index()
354 insn = (*state->insn) >> (state->byte * 8); in unwind_exec_read_byte()
357 if (state->byte == 0) { in unwind_exec_read_byte()
358 state->byte = 3; in unwind_exec_read_byte()
359 state->insn++; in unwind_exec_read_byte()
360 state->entries--; in unwind_exec_read_byte()
362 state->byte--; in unwind_exec_read_byte()
373 uint32_t *vsp = (uint32_t *)state->registers[SP]; in unwind_exec_insn()
377 if (state->entries == 0) in unwind_exec_insn()
384 state->registers[SP] += ((insn & INSN_VSP_SIZE_MASK) << 2) + 4; in unwind_exec_insn()
387 state->registers[SP] -= ((insn & INSN_VSP_SIZE_MASK) << 2) + 4; in unwind_exec_insn()
396 /* We have a refuse to unwind instruction */ in unwind_exec_insn()
413 state->registers[reg] = *vsp++; in unwind_exec_insn()
414 state->update_mask |= 1 << reg; in unwind_exec_insn()
426 state->registers[SP] = in unwind_exec_insn()
427 state->registers[insn & INSN_STD_DATA_MASK]; in unwind_exec_insn()
432 /* Read how many registers to load */ in unwind_exec_insn()
446 state->registers[reg] = *vsp++; in unwind_exec_insn()
447 state->update_mask |= 1 << reg; in unwind_exec_insn()
454 state->registers[14] = *vsp++; in unwind_exec_insn()
459 state->entries = 0; in unwind_exec_insn()
480 state->registers[reg] = *vsp++; in unwind_exec_insn()
481 state->update_mask |= 1 << reg; in unwind_exec_insn()
491 state->registers[SP] += 0x204 + (uleb128 << 2); in unwind_exec_insn()
494 /* We hit a new instruction that needs to be implemented */ in unwind_exec_insn()
502 state->registers[SP] = (uint32_t)vsp; in unwind_exec_insn()
507 state->registers[FP], state->registers[SP], state->registers[LR], in unwind_exec_insn()
508 state->registers[PC]); in unwind_exec_insn()
520 /* Set PC to a known value */ in unwind_tab()
521 state->registers[PC] = 0; in unwind_tab()
524 entry = *state->insn & ENTRY_MASK; in unwind_tab()
527 state->byte = 2; in unwind_tab()
528 state->entries = 1; in unwind_tab()
530 state->byte = 1; in unwind_tab()
531 state->entries = ((*state->insn >> 16) & 0xFF) + 1; in unwind_tab()
539 while (state->entries > 0) { in unwind_tab()
547 if (state->registers[PC] == 0) { in unwind_tab()
548 state->registers[PC] = state->registers[LR]; in unwind_tab()
553 if (state->start_pc != state->registers[PC]) in unwind_tab()
554 state->update_mask |= 1 << PC; in unwind_tab()
565 * made to remove it after this new code has proven itself for a while.
573 state->update_mask = 0; in unwind_stack_one()
576 state->start_pc = state->registers[PC]; in unwind_stack_one()
578 /* Find the item to run */ in unwind_stack_one()
579 index = find_index(state->start_pc); in unwind_stack_one()
580 if (index == NULL || index->insn == EXIDX_CANTUNWIND) in unwind_stack_one()
583 if (index->insn & (1U << 31)) { in unwind_stack_one()
585 state->insn = &index->insn; in unwind_stack_one()
587 /* A prel31 offset to the unwind table */ in unwind_stack_one()
588 state->insn = (uint32_t *) in unwind_stack_one()
589 ((uintptr_t)&index->insn + in unwind_stack_one()
590 expand_prel31(index->insn)); in unwind_stack_one()
593 /* Run the unwind function, return its finished/not-finished status. */ in unwind_stack_one()