uwx_utable.c (129059) | uwx_utable.c (160157) |
---|---|
1/* | 1/* |
2Copyright (c) 2003 Hewlett-Packard Development Company, L.P. | 2Copyright (c) 2003-2006 Hewlett-Packard Development Company, L.P. |
3Permission is hereby granted, free of charge, to any person 4obtaining a copy of this software and associated documentation 5files (the "Software"), to deal in the Software without 6restriction, including without limitation the rights to use, 7copy, modify, merge, publish, distribute, sublicense, and/or sell 8copies of the Software, and to permit persons to whom the 9Software is furnished to do so, subject to the following 10conditions: --- 60 unchanged lines hidden (view full) --- 71 uint64_t unwind_end; 72 int keys; 73 int status; 74 75 /* Get unwind table information from the result vector. */ 76 /* Make sure all three required values are given. */ 77 78 keys = 0; | 3Permission is hereby granted, free of charge, to any person 4obtaining a copy of this software and associated documentation 5files (the "Software"), to deal in the Software without 6restriction, including without limitation the rights to use, 7copy, modify, merge, publish, distribute, sublicense, and/or sell 8copies of the Software, and to permit persons to whom the 9Software is furnished to do so, subject to the following 10conditions: --- 60 unchanged lines hidden (view full) --- 71 uint64_t unwind_end; 72 int keys; 73 int status; 74 75 /* Get unwind table information from the result vector. */ 76 /* Make sure all three required values are given. */ 77 78 keys = 0; |
79 text_base = 0; | |
80 unwind_flags = 0; | 79 unwind_flags = 0; |
81 unwind_start = 0; 82 unwind_end = 0; | |
83 while (*uvec != 0) { 84 switch ((int)*uvec++) { 85 case UWX_KEY_TBASE: 86 keys |= 1; | 80 while (*uvec != 0) { 81 switch ((int)*uvec++) { 82 case UWX_KEY_TBASE: 83 keys |= 1; |
87 text_base = *uvec++; | 84 env->text_base = text_base = *uvec++; |
88 break; 89 case UWX_KEY_UFLAGS: 90 unwind_flags = *uvec++; 91 break; 92 case UWX_KEY_USTART: 93 keys |= 2; 94 unwind_start = *uvec++; 95 break; 96 case UWX_KEY_UEND: 97 keys |= 4; 98 unwind_end = *uvec++; 99 break; | 85 break; 86 case UWX_KEY_UFLAGS: 87 unwind_flags = *uvec++; 88 break; 89 case UWX_KEY_USTART: 90 keys |= 2; 91 unwind_start = *uvec++; 92 break; 93 case UWX_KEY_UEND: 94 keys |= 4; 95 unwind_end = *uvec++; 96 break; |
97 case UWX_KEY_GP: 98 uwx_set_reg(env, UWX_REG_GP, *uvec++); 99 break; |
|
100 default: 101 return UWX_ERR_BADKEY; 102 } 103 } 104 if (keys != 7) 105 return UWX_ERR_BADKEY; 106 107 /* Copy the unwind flags into the unwind entry. */ --- 21 unchanged lines hidden (view full) --- 129/* uwx_search_utable32: Binary search of 32-bit unwind table */ 130 131#define COPYIN_UINFO_4(dest, src) \ 132 (env->remote? \ 133 (*env->copyin)(UWX_COPYIN_UINFO, (dest), (src), \ 134 WORDSZ, env->cb_token) : \ 135 (*(uint32_t *)(dest) = *(uint32_t *)(src), WORDSZ) ) 136 | 100 default: 101 return UWX_ERR_BADKEY; 102 } 103 } 104 if (keys != 7) 105 return UWX_ERR_BADKEY; 106 107 /* Copy the unwind flags into the unwind entry. */ --- 21 unchanged lines hidden (view full) --- 129/* uwx_search_utable32: Binary search of 32-bit unwind table */ 130 131#define COPYIN_UINFO_4(dest, src) \ 132 (env->remote? \ 133 (*env->copyin)(UWX_COPYIN_UINFO, (dest), (src), \ 134 WORDSZ, env->cb_token) : \ 135 (*(uint32_t *)(dest) = *(uint32_t *)(src), WORDSZ) ) 136 |
137#define SWIZZLE(x) (((uint64_t)((x) & 0xc0000000) << 31) | (x)) 138 |
|
137int uwx_search_utable32( 138 struct uwx_env *env, 139 uint32_t ip, 140 uint32_t text_base, 141 uint32_t unwind_start, 142 uint32_t unwind_end, 143 struct uwx_utable_entry *uentry) 144{ | 139int uwx_search_utable32( 140 struct uwx_env *env, 141 uint32_t ip, 142 uint32_t text_base, 143 uint32_t unwind_start, 144 uint32_t unwind_end, 145 struct uwx_utable_entry *uentry) 146{ |
147 int status; |
|
145 int lb; 146 int ub; 147 int mid; 148 int len; 149 uint32_t code_start; 150 uint32_t code_end; 151 uint32_t unwind_info; 152 --- 4 unchanged lines hidden (view full) --- 157 158 TRACE_T_SEARCH32(ip) 159 160 /* Standard binary search. */ 161 /* Might modify this to do interpolation in the future. */ 162 163 lb = 0; 164 ub = (unwind_end - unwind_start) / (3 * WORDSZ); | 148 int lb; 149 int ub; 150 int mid; 151 int len; 152 uint32_t code_start; 153 uint32_t code_end; 154 uint32_t unwind_info; 155 --- 4 unchanged lines hidden (view full) --- 160 161 TRACE_T_SEARCH32(ip) 162 163 /* Standard binary search. */ 164 /* Might modify this to do interpolation in the future. */ 165 166 lb = 0; 167 ub = (unwind_end - unwind_start) / (3 * WORDSZ); |
165 mid = 0; | |
166 while (ub > lb) { 167 mid = (lb + ub) / 2; | 168 while (ub > lb) { 169 mid = (lb + ub) / 2; |
168 len = COPYIN_UINFO_4((char *)&code_start, 169 (uintptr_t)(unwind_start+mid*3*WORDSZ)); | 170 len = COPYIN_UINFO_4((char *)&code_start, unwind_start+mid*3*WORDSZ); |
170 len += COPYIN_UINFO_4((char *)&code_end, | 171 len += COPYIN_UINFO_4((char *)&code_end, |
171 (uintptr_t)(unwind_start+mid*3*WORDSZ+WORDSZ)); | 172 unwind_start+mid*3*WORDSZ+WORDSZ); |
172 if (len != 2 * WORDSZ) 173 return UWX_ERR_COPYIN_UTBL; 174 if (env->byte_swap) { 175 uwx_swap4(&code_start); 176 uwx_swap4(&code_end); 177 } 178 TRACE_T_BINSEARCH32(lb, ub, mid, code_start, code_end) 179 if (ip >= code_end) 180 lb = mid + 1; 181 else if (ip < code_start) 182 ub = mid; 183 else 184 break; 185 } 186 if (ub <= lb) 187 return UWX_ERR_NOUENTRY; 188 len = COPYIN_UINFO_4((char *)&unwind_info, | 173 if (len != 2 * WORDSZ) 174 return UWX_ERR_COPYIN_UTBL; 175 if (env->byte_swap) { 176 uwx_swap4(&code_start); 177 uwx_swap4(&code_end); 178 } 179 TRACE_T_BINSEARCH32(lb, ub, mid, code_start, code_end) 180 if (ip >= code_end) 181 lb = mid + 1; 182 else if (ip < code_start) 183 ub = mid; 184 else 185 break; 186 } 187 if (ub <= lb) 188 return UWX_ERR_NOUENTRY; 189 len = COPYIN_UINFO_4((char *)&unwind_info, |
189 (uintptr_t)(unwind_start+mid*3*WORDSZ+2*WORDSZ)); | 190 unwind_start+mid*3*WORDSZ+2*WORDSZ); |
190 if (len != WORDSZ) 191 return UWX_ERR_COPYIN_UTBL; 192 if (env->byte_swap) 193 uwx_swap4(&unwind_info); | 191 if (len != WORDSZ) 192 return UWX_ERR_COPYIN_UTBL; 193 if (env->byte_swap) 194 uwx_swap4(&unwind_info); |
194 uentry->code_start = text_base + code_start; 195 uentry->code_end = text_base + code_end; 196 uentry->unwind_info = text_base + unwind_info; | 195 uentry->ptr_size = WORDSZ; 196 uentry->code_start = SWIZZLE(text_base + code_start); 197 uentry->code_end = SWIZZLE(text_base + code_end); 198 uentry->unwind_info = SWIZZLE(text_base + unwind_info); |
197 return UWX_OK; 198} 199 200 201/* uwx_search_utable64: Binary search of 64-bit unwind table */ 202 203#define COPYIN_UINFO_8(dest, src) \ 204 (env->remote? \ | 199 return UWX_OK; 200} 201 202 203/* uwx_search_utable64: Binary search of 64-bit unwind table */ 204 205#define COPYIN_UINFO_8(dest, src) \ 206 (env->remote? \ |
205 (*env->copyin)(UWX_COPYIN_UINFO, (dest), (src), \ | 207 (*env->copyin)(UWX_COPYIN_UINFO, (dest), (src), \ |
206 DWORDSZ, env->cb_token) : \ | 208 DWORDSZ, env->cb_token) : \ |
207 (*(uint64_t *)(dest) = *(uint64_t *)(src), DWORDSZ) ) | 209 (*(uint64_t *)(intptr_t)(dest) = *(uint64_t *)(intptr_t)(src), DWORDSZ) ) |
208 209int uwx_search_utable64( 210 struct uwx_env *env, 211 uint64_t ip, 212 uint64_t text_base, 213 uint64_t unwind_start, 214 uint64_t unwind_end, 215 struct uwx_utable_entry *uentry) 216{ | 210 211int uwx_search_utable64( 212 struct uwx_env *env, 213 uint64_t ip, 214 uint64_t text_base, 215 uint64_t unwind_start, 216 uint64_t unwind_end, 217 struct uwx_utable_entry *uentry) 218{ |
219 int status; |
|
217 int lb; 218 int ub; 219 int mid; 220 int len; 221 uint64_t code_start; 222 uint64_t code_end; 223 uint64_t unwind_info; 224 225 /* Since the unwind table uses segment-relative offsets, convert */ 226 /* the IP in the current context to a segment-relative offset. */ 227 228 ip -= text_base; 229 230 /* Standard binary search. */ 231 /* Might modify this to do interpolation in the future. */ 232 233 lb = 0; 234 ub = (unwind_end - unwind_start) / (3 * DWORDSZ); | 220 int lb; 221 int ub; 222 int mid; 223 int len; 224 uint64_t code_start; 225 uint64_t code_end; 226 uint64_t unwind_info; 227 228 /* Since the unwind table uses segment-relative offsets, convert */ 229 /* the IP in the current context to a segment-relative offset. */ 230 231 ip -= text_base; 232 233 /* Standard binary search. */ 234 /* Might modify this to do interpolation in the future. */ 235 236 lb = 0; 237 ub = (unwind_end - unwind_start) / (3 * DWORDSZ); |
235 mid = 0; | |
236 while (ub > lb) { 237 mid = (lb + ub) / 2; 238 len = COPYIN_UINFO_8((char *)&code_start, unwind_start+mid*3*DWORDSZ); 239 len += COPYIN_UINFO_8((char *)&code_end, 240 unwind_start+mid*3*DWORDSZ+DWORDSZ); 241 if (len != 2 * DWORDSZ) 242 return UWX_ERR_COPYIN_UTBL; 243 if (env->byte_swap) { --- 10 unchanged lines hidden (view full) --- 254 if (ub <= lb) 255 return UWX_ERR_NOUENTRY; 256 len = COPYIN_UINFO_8((char *)&unwind_info, 257 unwind_start+mid*3*DWORDSZ+2*DWORDSZ); 258 if (len != DWORDSZ) 259 return UWX_ERR_COPYIN_UTBL; 260 if (env->byte_swap) 261 uwx_swap8(&unwind_info); | 238 while (ub > lb) { 239 mid = (lb + ub) / 2; 240 len = COPYIN_UINFO_8((char *)&code_start, unwind_start+mid*3*DWORDSZ); 241 len += COPYIN_UINFO_8((char *)&code_end, 242 unwind_start+mid*3*DWORDSZ+DWORDSZ); 243 if (len != 2 * DWORDSZ) 244 return UWX_ERR_COPYIN_UTBL; 245 if (env->byte_swap) { --- 10 unchanged lines hidden (view full) --- 256 if (ub <= lb) 257 return UWX_ERR_NOUENTRY; 258 len = COPYIN_UINFO_8((char *)&unwind_info, 259 unwind_start+mid*3*DWORDSZ+2*DWORDSZ); 260 if (len != DWORDSZ) 261 return UWX_ERR_COPYIN_UTBL; 262 if (env->byte_swap) 263 uwx_swap8(&unwind_info); |
264 uentry->ptr_size = DWORDSZ; |
|
262 uentry->code_start = text_base + code_start; 263 uentry->code_end = text_base + code_end; 264 uentry->unwind_info = text_base + unwind_info; 265 return UWX_OK; 266} | 265 uentry->code_start = text_base + code_start; 266 uentry->code_end = text_base + code_end; 267 uentry->unwind_info = text_base + unwind_info; 268 return UWX_OK; 269} |