diff options
Diffstat (limited to 'sys/contrib/ia64/libuwx/src/uwx_utable.c')
-rw-r--r-- | sys/contrib/ia64/libuwx/src/uwx_utable.c | 273 |
1 files changed, 0 insertions, 273 deletions
diff --git a/sys/contrib/ia64/libuwx/src/uwx_utable.c b/sys/contrib/ia64/libuwx/src/uwx_utable.c deleted file mode 100644 index 908a3ae..0000000 --- a/sys/contrib/ia64/libuwx/src/uwx_utable.c +++ /dev/null @@ -1,273 +0,0 @@ -/* -Copyright (c) 2003-2006 Hewlett-Packard Development Company, L.P. -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. -*/ - -#include "uwx_env.h" -#include "uwx_utable.h" -#include "uwx_swap.h" -#include "uwx_trace.h" - -/* - * uwx_utable.c - * - * This file contains the routines for searching an unwind table. - * The main entry point, uwx_search_utable(), gets the - * necessary information from the lookup ip callback's result - * vector, determines whether the table is 32-bit or 64-bit, - * then invokes the binary search routine for that format. - */ - - -/* Forward declarations */ - -int uwx_search_utable32( - struct uwx_env *env, - uint32_t ip, - uint32_t text_base, - uint32_t unwind_start, - uint32_t unwind_end, - struct uwx_utable_entry *uentry); - -int uwx_search_utable64( - struct uwx_env *env, - uint64_t ip, - uint64_t text_base, - uint64_t unwind_start, - uint64_t unwind_end, - struct uwx_utable_entry *uentry); - - -/* uwx_search_utable: Searches an unwind table for IP in current context */ - -int uwx_search_utable( - struct uwx_env *env, - uint64_t ip, - uint64_t *uvec, - struct uwx_utable_entry *uentry) -{ - uint64_t text_base; - uint64_t unwind_flags; - uint64_t unwind_start; - uint64_t unwind_end; - int keys; - int status; - - /* Get unwind table information from the result vector. */ - /* Make sure all three required values are given. */ - - keys = 0; - text_base = 0; - unwind_flags = 0; - unwind_start = 0; - unwind_end = 0; - while (*uvec != 0) { - switch ((int)*uvec++) { - case UWX_KEY_TBASE: - keys |= 1; - env->text_base = text_base = *uvec++; - break; - case UWX_KEY_UFLAGS: - unwind_flags = *uvec++; - break; - case UWX_KEY_USTART: - keys |= 2; - unwind_start = *uvec++; - break; - case UWX_KEY_UEND: - keys |= 4; - unwind_end = *uvec++; - break; - case UWX_KEY_GP: - uwx_set_reg(env, UWX_REG_GP, *uvec++); - break; - default: - return UWX_ERR_BADKEY; - } - } - if (keys != 7) - return UWX_ERR_BADKEY; - - /* Copy the unwind flags into the unwind entry. */ - /* (uwx_decode_uinfo needs to know whether it's 32-bit or 64-bit.) */ - - uentry->unwind_flags = unwind_flags; - - /* Call the appropriate binary search routine. */ - - if (unwind_flags & UNWIND_TBL_32BIT) - status = uwx_search_utable32(env, - (uint32_t) ip, - (uint32_t) text_base, - (uint32_t) unwind_start, - (uint32_t) unwind_end, - uentry); - else - status = uwx_search_utable64(env, - ip, text_base, unwind_start, unwind_end, uentry); - - return status; -} - - -/* uwx_search_utable32: Binary search of 32-bit unwind table */ - -#define COPYIN_UINFO_4(dest, src) \ - (env->remote? \ - (*env->copyin)(UWX_COPYIN_UINFO, (dest), (src), \ - WORDSZ, env->cb_token) : \ - (*(uint32_t *)(dest) = *(uint32_t *)(src), WORDSZ) ) - -#define SWIZZLE(x) (((uint64_t)((x) & 0xc0000000) << 31) | (x)) - -int uwx_search_utable32( - struct uwx_env *env, - uint32_t ip, - uint32_t text_base, - uint32_t unwind_start, - uint32_t unwind_end, - struct uwx_utable_entry *uentry) -{ - int lb; - int ub; - int mid; - int len; - uint32_t code_start; - uint32_t code_end; - uint32_t unwind_info; - - /* Since the unwind table uses segment-relative offsets, convert */ - /* the IP in the current context to a segment-relative offset. */ - - ip -= text_base; - - TRACE_T_SEARCH32(ip) - - /* Standard binary search. */ - /* Might modify this to do interpolation in the future. */ - - lb = 0; - ub = (unwind_end - unwind_start) / (3 * WORDSZ); - mid = 0; - while (ub > lb) { - mid = (lb + ub) / 2; - len = COPYIN_UINFO_4((char *)&code_start, - (uintptr_t)(unwind_start+mid*3*WORDSZ)); - len += COPYIN_UINFO_4((char *)&code_end, - (uintptr_t)(unwind_start+mid*3*WORDSZ+WORDSZ)); - if (len != 2 * WORDSZ) - return UWX_ERR_COPYIN_UTBL; - if (env->byte_swap) { - uwx_swap4(&code_start); - uwx_swap4(&code_end); - } - TRACE_T_BINSEARCH32(lb, ub, mid, code_start, code_end) - if (ip >= code_end) - lb = mid + 1; - else if (ip < code_start) - ub = mid; - else - break; - } - if (ub <= lb) - return UWX_ERR_NOUENTRY; - len = COPYIN_UINFO_4((char *)&unwind_info, - (uintptr_t)(unwind_start+mid*3*WORDSZ+2*WORDSZ)); - if (len != WORDSZ) - return UWX_ERR_COPYIN_UTBL; - if (env->byte_swap) - uwx_swap4(&unwind_info); - uentry->ptr_size = WORDSZ; - uentry->code_start = SWIZZLE(text_base + code_start); - uentry->code_end = SWIZZLE(text_base + code_end); - uentry->unwind_info = SWIZZLE(text_base + unwind_info); - return UWX_OK; -} - - -/* uwx_search_utable64: Binary search of 64-bit unwind table */ - -#define COPYIN_UINFO_8(dest, src) \ - (env->remote? \ - (*env->copyin)(UWX_COPYIN_UINFO, (dest), (src), \ - DWORDSZ, env->cb_token) : \ - (*(uint64_t *)(intptr_t)(dest) = *(uint64_t *)(intptr_t)(src), DWORDSZ) ) - -int uwx_search_utable64( - struct uwx_env *env, - uint64_t ip, - uint64_t text_base, - uint64_t unwind_start, - uint64_t unwind_end, - struct uwx_utable_entry *uentry) -{ - int lb; - int ub; - int mid; - int len; - uint64_t code_start; - uint64_t code_end; - uint64_t unwind_info; - - /* Since the unwind table uses segment-relative offsets, convert */ - /* the IP in the current context to a segment-relative offset. */ - - ip -= text_base; - - /* Standard binary search. */ - /* Might modify this to do interpolation in the future. */ - - lb = 0; - ub = (unwind_end - unwind_start) / (3 * DWORDSZ); - mid = 0; - while (ub > lb) { - mid = (lb + ub) / 2; - len = COPYIN_UINFO_8((char *)&code_start, unwind_start+mid*3*DWORDSZ); - len += COPYIN_UINFO_8((char *)&code_end, - unwind_start+mid*3*DWORDSZ+DWORDSZ); - if (len != 2 * DWORDSZ) - return UWX_ERR_COPYIN_UTBL; - if (env->byte_swap) { - uwx_swap8(&code_start); - uwx_swap8(&code_end); - } - if (ip >= code_end) - lb = mid + 1; - else if (ip < code_start) - ub = mid; - else - break; - } - if (ub <= lb) - return UWX_ERR_NOUENTRY; - len = COPYIN_UINFO_8((char *)&unwind_info, - unwind_start+mid*3*DWORDSZ+2*DWORDSZ); - if (len != DWORDSZ) - return UWX_ERR_COPYIN_UTBL; - if (env->byte_swap) - uwx_swap8(&unwind_info); - uentry->ptr_size = DWORDSZ; - uentry->code_start = text_base + code_start; - uentry->code_end = text_base + code_end; - uentry->unwind_info = text_base + unwind_info; - return UWX_OK; -} |