/* * Perform a binary search of the index table to find the function * with the largest address that doesn't exceed addr. */ static struct unwind_idx *find_index(uint32_t addr, vaddr_t exidx, size_t exidx_sz) { vaddr_t idx_start, idx_end; unsigned int min, mid, max; struct unwind_idx *start; struct unwind_idx *item; int32_t prel31_addr; vaddr_t func_addr; start = (struct unwind_idx *)exidx; idx_start = exidx; idx_end = exidx + exidx_sz; min = 0; max = (idx_end - idx_start) / sizeof(struct unwind_idx); while (min != max) { mid = min + (max - min + 1) / 2; item = &start[mid]; prel31_addr = expand_prel31(item->offset); func_addr = (vaddr_t)&item->offset + prel31_addr; if (func_addr <= addr) { min = mid; } else { max = mid - 1; } } return &start[min]; }
/* * Perform a binary search of the index table to find the function * with the largest address that doesn't exceed addr. */ static struct unwind_idx * find_index(uint32_t addr, int search_modules) { struct search_context sc; caddr_t idx_start, idx_end; unsigned int min, mid, max; struct unwind_idx *start; struct unwind_idx *item; int32_t prel31_addr; uint32_t func_addr; start = (struct unwind_idx *)&exidx_start; idx_start = (caddr_t)&exidx_start; idx_end = (caddr_t)&exidx_end; /* This may acquire a lock */ if (search_modules) { bzero(&sc, sizeof(sc)); sc.addr = addr; if (linker_file_foreach(module_search, &sc) != 0 && sc.exidx_start != NULL && sc.exidx_end != NULL) { start = (struct unwind_idx *)sc.exidx_start; idx_start = sc.exidx_start; idx_end = sc.exidx_end; } } min = 0; max = (idx_end - idx_start) / sizeof(struct unwind_idx); while (min != max) { mid = min + (max - min + 1) / 2; item = &start[mid]; prel31_addr = expand_prel31(item->offset); func_addr = (uint32_t)&item->offset + prel31_addr; if (func_addr <= addr) { min = mid; } else { max = mid - 1; } } return &start[min]; }