Deleted Added
full compact
uwx_self.c (129059) uwx_self.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:

--- 7 unchanged lines hidden (view full) ---

18NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22OTHER DEALINGS IN THE SOFTWARE.
23*/
24
25#include <stdlib.h>
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:

--- 7 unchanged lines hidden (view full) ---

18NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22OTHER DEALINGS IN THE SOFTWARE.
23*/
24
25#include <stdlib.h>
26#include <string.h>
26#include <crt0.h>
27#include <dlfcn.h>
28#include <sys/uc_access.h>
29
30#include "uwx_env.h"
31#include "uwx_context.h"
32#include "uwx_trace.h"
33#include "uwx_self.h"
27#include <crt0.h>
28#include <dlfcn.h>
29#include <sys/uc_access.h>
30
31#include "uwx_env.h"
32#include "uwx_context.h"
33#include "uwx_trace.h"
34#include "uwx_self.h"
35#include "uwx_self_info.h"
34
35#define UWX_ABI_HPUX_SIGCONTEXT 0x0101 /* abi = HP-UX, context = 1 */
36
36
37#define UWX_ABI_HPUX_SIGCONTEXT 0x0101 /* abi = HP-UX, context = 1 */
38
37struct uwx_self_info {
38 struct uwx_env *env;
39 ucontext_t *ucontext;
40 uint64_t bspstore;
41 uint64_t rvec[10];
42 uint64_t sendsig_start;
43 uint64_t sendsig_end;
44 alloc_cb allocate_cb;
45 free_cb free_cb;
46 int trace;
47};
39void uwx_free_load_module_cache(struct uwx_self_info *info);
48
40
49struct uwx_self_info *uwx_self_init_info(struct uwx_env *env)
41int uwx_self_init_info_block(struct uwx_env *env, struct uwx_self_info *info)
50{
42{
51 struct uwx_self_info *info;
52
53 if (env->allocate_cb == 0)
54 info = (struct uwx_self_info *)
55 malloc(sizeof(struct uwx_self_info));
56 else
57 info = (struct uwx_self_info *)
58 (*env->allocate_cb)(sizeof(struct uwx_self_info));
59 if (info == 0)
60 return 0;
61
62 info->env = env;
63 info->ucontext = 0;
64 info->bspstore = 0;
65 info->sendsig_start = __load_info->li_sendsig_txt;
66 info->sendsig_end = __load_info->li_sendsig_txt +
67 __load_info->li_sendsig_tsz;
43 info->env = env;
44 info->ucontext = 0;
45 info->bspstore = 0;
46 info->sendsig_start = __load_info->li_sendsig_txt;
47 info->sendsig_end = __load_info->li_sendsig_txt +
48 __load_info->li_sendsig_tsz;
68 info->allocate_cb = env->allocate_cb;
69 info->free_cb = env->free_cb;
49 info->on_heap = 0;
70 info->trace = env->trace;
50 info->trace = env->trace;
51 info->load_module_cache = NULL;
52
53 return UWX_OK;
54}
55
56struct uwx_self_info *uwx_self_init_info(struct uwx_env *env)
57{
58 struct uwx_self_info *info;
59
60 info = (struct uwx_self_info *)
61 (*env->allocate_cb)(sizeof(struct uwx_self_info));
62 if (info == 0)
63 return 0;
64
65 uwx_self_init_info_block(env, info);
66 info->on_heap = 1;
71 return info;
72}
73
74int uwx_self_free_info(struct uwx_self_info *info)
75{
67 return info;
68}
69
70int uwx_self_free_info(struct uwx_self_info *info)
71{
76 if (info->free_cb == 0)
77 free((void *)info);
78 else
79 (*info->free_cb)((void *)info);
72 int i;
73
74 if (info->load_module_cache != NULL)
75 uwx_free_load_module_cache(info);
76 if (info->on_heap)
77 (*info->env->free_cb)((void *)info);
80 return UWX_OK;
81}
82
83int uwx_self_init_from_sigcontext(
84 struct uwx_env *env,
85 struct uwx_self_info *info,
86 ucontext_t *ucontext)
87{

--- 4 unchanged lines hidden (view full) ---

92 uint64_t bsp;
93 uint64_t cfm;
94 unsigned int nat;
95 uint64_t ec;
96 int adj;
97
98 info->ucontext = ucontext;
99 status = __uc_get_reason(ucontext, &reason);
78 return UWX_OK;
79}
80
81int uwx_self_init_from_sigcontext(
82 struct uwx_env *env,
83 struct uwx_self_info *info,
84 ucontext_t *ucontext)
85{

--- 4 unchanged lines hidden (view full) ---

90 uint64_t bsp;
91 uint64_t cfm;
92 unsigned int nat;
93 uint64_t ec;
94 int adj;
95
96 info->ucontext = ucontext;
97 status = __uc_get_reason(ucontext, &reason);
98 if (status != 0)
99 return UWX_ERR_UCACCESS;
100 status = __uc_get_ip(ucontext, &ip);
100 status = __uc_get_ip(ucontext, &ip);
101 if (status != 0)
102 return UWX_ERR_UCACCESS;
101 status = __uc_get_grs(ucontext, 12, 1, &sp, &nat);
103 status = __uc_get_grs(ucontext, 12, 1, &sp, &nat);
104 if (status != 0)
105 return UWX_ERR_UCACCESS;
102 status = __uc_get_cfm(ucontext, &cfm);
106 status = __uc_get_cfm(ucontext, &cfm);
107 if (status != 0)
108 return UWX_ERR_UCACCESS;
103#ifdef NEW_UC_GET_AR
104 status = __uc_get_ar_bsp(ucontext, &bsp);
109#ifdef NEW_UC_GET_AR
110 status = __uc_get_ar_bsp(ucontext, &bsp);
111 if (status != 0)
112 return UWX_ERR_UCACCESS;
105 status = __uc_get_ar_bspstore(ucontext, &info->bspstore);
113 status = __uc_get_ar_bspstore(ucontext, &info->bspstore);
114 if (status != 0)
115 return UWX_ERR_UCACCESS;
106 status = __uc_get_ar_ec(ucontext, &ec);
116 status = __uc_get_ar_ec(ucontext, &ec);
117 if (status != 0)
118 return UWX_ERR_UCACCESS;
107#else
108 status = __uc_get_ar(ucontext, 17, &bsp);
119#else
120 status = __uc_get_ar(ucontext, 17, &bsp);
121 if (status != 0)
122 return UWX_ERR_UCACCESS;
109 status = __uc_get_ar(ucontext, 18, &info->bspstore);
123 status = __uc_get_ar(ucontext, 18, &info->bspstore);
124 if (status != 0)
125 return UWX_ERR_UCACCESS;
110 status = __uc_get_ar(ucontext, 66, &ec);
126 status = __uc_get_ar(ucontext, 66, &ec);
127 if (status != 0)
128 return UWX_ERR_UCACCESS;
111#endif
112 /* The returned bsp needs to be adjusted. */
113 /* For interrupt frames, where bsp was advanced by a cover */
114 /* instruction, subtract sof (size of frame). For non-interrupt */
115 /* frames, where bsp was advanced by br.call, subtract sol */
116 /* (size of locals). */
117 if (reason != 0)
118 adj = (unsigned int)cfm & 0x7f; /* interrupt frame */

--- 12 unchanged lines hidden (view full) ---

131 int abi_context;
132 int status;
133 uint64_t ucontext;
134
135 abi_context = uwx_get_abi_context_code(env);
136 if (abi_context != UWX_ABI_HPUX_SIGCONTEXT)
137 return UWX_SELF_ERR_BADABICONTEXT;
138 status = uwx_get_reg(env, UWX_REG_GR(32), (uint64_t *)&ucontext);
129#endif
130 /* The returned bsp needs to be adjusted. */
131 /* For interrupt frames, where bsp was advanced by a cover */
132 /* instruction, subtract sof (size of frame). For non-interrupt */
133 /* frames, where bsp was advanced by br.call, subtract sol */
134 /* (size of locals). */
135 if (reason != 0)
136 adj = (unsigned int)cfm & 0x7f; /* interrupt frame */

--- 12 unchanged lines hidden (view full) ---

149 int abi_context;
150 int status;
151 uint64_t ucontext;
152
153 abi_context = uwx_get_abi_context_code(env);
154 if (abi_context != UWX_ABI_HPUX_SIGCONTEXT)
155 return UWX_SELF_ERR_BADABICONTEXT;
156 status = uwx_get_reg(env, UWX_REG_GR(32), (uint64_t *)&ucontext);
139 if (status != 0)
157 if (status != UWX_OK)
140 return status;
158 return status;
141 return uwx_self_init_from_sigcontext(env, info, (ucontext_t *)ucontext);
159 return uwx_self_init_from_sigcontext(env, info,
160 (ucontext_t *)(intptr_t)ucontext);
142}
143
144int uwx_self_copyin(
145 int request,
146 char *loc,
147 uint64_t rem,
148 int len,
149 intptr_t tok)

--- 9 unchanged lines hidden (view full) ---

159
160 dp = (uint64_t *) loc;
161
162 switch (request) {
163 case UWX_COPYIN_UINFO:
164 case UWX_COPYIN_MSTACK:
165 if (len == 4) {
166 wp = (unsigned long *) loc;
161}
162
163int uwx_self_copyin(
164 int request,
165 char *loc,
166 uint64_t rem,
167 int len,
168 intptr_t tok)

--- 9 unchanged lines hidden (view full) ---

178
179 dp = (uint64_t *) loc;
180
181 switch (request) {
182 case UWX_COPYIN_UINFO:
183 case UWX_COPYIN_MSTACK:
184 if (len == 4) {
185 wp = (unsigned long *) loc;
167 *wp = *(unsigned long *)rem;
186 *wp = *(unsigned long *)(intptr_t)rem;
168 TRACE_SELF_COPYIN4(rem, len, wp)
169 status = 0;
170 }
171 else if (len == 8) {
187 TRACE_SELF_COPYIN4(rem, len, wp)
188 status = 0;
189 }
190 else if (len == 8) {
172 *dp = *(uint64_t *)rem;
191 *dp = *(uint64_t *)(intptr_t)rem;
173 TRACE_SELF_COPYIN8(rem, len, dp)
174 status = 0;
175 }
176 break;
177 case UWX_COPYIN_RSTACK:
178 if (len == 8) {
179 if (info->ucontext == 0 && rem == (info->bspstore | 0x1f8)) {
180 *dp = info->env->context.special[UWX_REG_AR_RNAT];
181 status = 0;
182 }
183 else if (info->ucontext == 0 || rem < info->bspstore) {
192 TRACE_SELF_COPYIN8(rem, len, dp)
193 status = 0;
194 }
195 break;
196 case UWX_COPYIN_RSTACK:
197 if (len == 8) {
198 if (info->ucontext == 0 && rem == (info->bspstore | 0x1f8)) {
199 *dp = info->env->context.special[UWX_REG_AR_RNAT];
200 status = 0;
201 }
202 else if (info->ucontext == 0 || rem < info->bspstore) {
184 *dp = *(uint64_t *)rem;
203 *dp = *(uint64_t *)(intptr_t)rem;
185 TRACE_SELF_COPYIN8(rem, len, dp)
186 status = 0;
187 }
188 else {
189 status = __uc_get_rsebs(info->ucontext,
204 TRACE_SELF_COPYIN8(rem, len, dp)
205 status = 0;
206 }
207 else {
208 status = __uc_get_rsebs(info->ucontext,
190 (uint64_t *)rem, 1, dp);
209 (uint64_t *)(intptr_t)rem, 1, dp);
191 }
192 }
193 break;
194 case UWX_COPYIN_REG:
195 regid = (int)rem;
196 if (info->ucontext != 0) {
197 if (len == 8) {
198 if (rem == UWX_REG_PREDS)

--- 26 unchanged lines hidden (view full) ---

225 }
226 break;
227 }
228 if (status != 0)
229 return 0;
230 return len;
231}
232
210 }
211 }
212 break;
213 case UWX_COPYIN_REG:
214 regid = (int)rem;
215 if (info->ucontext != 0) {
216 if (len == 8) {
217 if (rem == UWX_REG_PREDS)

--- 26 unchanged lines hidden (view full) ---

244 }
245 break;
246 }
247 if (status != 0)
248 return 0;
249 return len;
250}
251
252#define MODULE_CACHE_SIZE 4
233
253
254struct load_module_cache {
255 int clock;
256 char *names[MODULE_CACHE_SIZE];
257 struct load_module_desc descs[MODULE_CACHE_SIZE];
258 struct uwx_symbol_cache *symbol_cache;
259};
260
261void uwx_free_load_module_cache(struct uwx_self_info *info)
262{
263 int i;
264
265 for (i = 0; i < MODULE_CACHE_SIZE; i++) {
266 if (info->load_module_cache->names[i] != NULL)
267 (*info->env->free_cb)((void *)info->load_module_cache->names[i]);
268 }
269
270 if (info->load_module_cache->symbol_cache != NULL)
271 uwx_release_symbol_cache(info->env,
272 info->load_module_cache->symbol_cache);
273
274 (*info->env->free_cb)((void *)info->load_module_cache);
275}
276
277struct load_module_desc *uwx_get_modinfo(
278 struct uwx_self_info *info,
279 uint64_t ip,
280 char **module_name_p)
281{
282 int i;
283 UINT64 handle;
284 struct load_module_cache *cache;
285 struct load_module_desc *desc;
286 char *module_name;
287
288 cache = info->load_module_cache;
289 if (cache == NULL) {
290 cache = (struct load_module_cache *)
291 (*info->env->allocate_cb)(sizeof(struct load_module_cache));
292 if (cache == NULL)
293 return NULL;
294 for (i = 0; i < MODULE_CACHE_SIZE; i++) {
295 desc = &cache->descs[i];
296 desc->text_base = 0;
297 desc->text_size = 0;
298 cache->names[i] = NULL;
299 }
300 cache->clock = 0;
301 cache->symbol_cache = NULL;
302 info->load_module_cache = cache;
303 }
304 for (i = 0; i < MODULE_CACHE_SIZE; i++) {
305 desc = &cache->descs[i];
306 if (ip >= desc->text_base && ip < desc->text_base + desc->text_size)
307 break;
308 }
309 if (i >= MODULE_CACHE_SIZE) {
310 i = cache->clock;
311 cache->clock = (cache->clock + 1) % MODULE_CACHE_SIZE;
312 desc = &cache->descs[i];
313 handle = dlmodinfo(ip, desc, sizeof(*desc), 0, 0, 0);
314 if (handle == 0)
315 return NULL;
316 if (cache->names[i] != NULL)
317 (*info->env->free_cb)(cache->names[i]);
318 cache->names[i] = NULL;
319 }
320 if (module_name_p != NULL) {
321 if (cache->names[i] == NULL) {
322 module_name = dlgetname(desc, sizeof(*desc), 0, 0, 0);
323 if (module_name != NULL) {
324 cache->names[i] = (char *)
325 (*info->env->allocate_cb)(strlen(module_name)+1);
326 if (cache->names[i] != NULL)
327 strcpy(cache->names[i], module_name);
328 }
329 }
330 *module_name_p = cache->names[i];
331 }
332 return desc;
333}
334
234int uwx_self_lookupip(
235 int request,
236 uint64_t ip,
237 intptr_t tok,
238 uint64_t **resultp)
239{
240 struct uwx_self_info *info = (struct uwx_self_info *) tok;
241 UINT64 handle;
335int uwx_self_lookupip(
336 int request,
337 uint64_t ip,
338 intptr_t tok,
339 uint64_t **resultp)
340{
341 struct uwx_self_info *info = (struct uwx_self_info *) tok;
342 UINT64 handle;
242 struct load_module_desc desc;
343 struct load_module_desc *desc;
243 uint64_t *unwind_base;
244 uint64_t *rvec;
344 uint64_t *unwind_base;
345 uint64_t *rvec;
346 char *module_name;
347 char *func_name;
348 uint64_t offset;
245 int i;
349 int i;
350 int status;
246
247 if (request == UWX_LKUP_LOOKUP) {
248 TRACE_SELF_LOOKUP(ip)
249 if (ip >= info->sendsig_start && ip < info->sendsig_end) {
250 i = 0;
251 rvec = info->rvec;
252 rvec[i++] = UWX_KEY_CONTEXT;
253 rvec[i++] = UWX_ABI_HPUX_SIGCONTEXT;
351
352 if (request == UWX_LKUP_LOOKUP) {
353 TRACE_SELF_LOOKUP(ip)
354 if (ip >= info->sendsig_start && ip < info->sendsig_end) {
355 i = 0;
356 rvec = info->rvec;
357 rvec[i++] = UWX_KEY_CONTEXT;
358 rvec[i++] = UWX_ABI_HPUX_SIGCONTEXT;
359 rvec[i++] = UWX_KEY_END;
254 rvec[i++] = 0;
360 rvec[i++] = 0;
255 rvec[i++] = 0;
256 *resultp = rvec;
257 return UWX_LKUP_FDESC;
258 }
259 else {
361 *resultp = rvec;
362 return UWX_LKUP_FDESC;
363 }
364 else {
260 handle = dlmodinfo(ip, &desc, sizeof(desc), 0, 0, 0);
261 if (handle == 0)
365 desc = uwx_get_modinfo(info, ip, NULL);
366 if (desc == NULL)
262 return UWX_LKUP_ERR;
367 return UWX_LKUP_ERR;
263 unwind_base = (uint64_t *) desc.unwind_base;
264 TRACE_SELF_LOOKUP_DESC(desc.text_base, unwind_base)
368 unwind_base = (uint64_t *) (intptr_t) desc->unwind_base;
369 TRACE_SELF_LOOKUP_DESC(desc->text_base,
370 desc->linkage_ptr, unwind_base)
265 i = 0;
266 rvec = info->rvec;
267 rvec[i++] = UWX_KEY_TBASE;
371 i = 0;
372 rvec = info->rvec;
373 rvec[i++] = UWX_KEY_TBASE;
268 rvec[i++] = desc.text_base;
374 rvec[i++] = desc->text_base;
269 rvec[i++] = UWX_KEY_UFLAGS;
270 rvec[i++] = unwind_base[0];
271 rvec[i++] = UWX_KEY_USTART;
375 rvec[i++] = UWX_KEY_UFLAGS;
376 rvec[i++] = unwind_base[0];
377 rvec[i++] = UWX_KEY_USTART;
272 rvec[i++] = desc.text_base + unwind_base[1];
378 rvec[i++] = desc->text_base + unwind_base[1];
273 rvec[i++] = UWX_KEY_UEND;
379 rvec[i++] = UWX_KEY_UEND;
274 rvec[i++] = desc.text_base + unwind_base[2];
380 rvec[i++] = desc->text_base + unwind_base[2];
381 rvec[i++] = UWX_KEY_GP;
382 rvec[i++] = desc->linkage_ptr;
383 rvec[i++] = UWX_KEY_END;
275 rvec[i++] = 0;
384 rvec[i++] = 0;
276 rvec[i++] = 0;
277 *resultp = rvec;
278 return UWX_LKUP_UTABLE;
279 }
280 }
281 else if (request == UWX_LKUP_FREE) {
282 return 0;
283 }
385 *resultp = rvec;
386 return UWX_LKUP_UTABLE;
387 }
388 }
389 else if (request == UWX_LKUP_FREE) {
390 return 0;
391 }
392 else if (request == UWX_LKUP_MODULE) {
393 desc = uwx_get_modinfo(info, ip, &module_name);
394 if (desc == NULL)
395 return UWX_LKUP_ERR;
396 if (module_name == NULL)
397 return UWX_LKUP_ERR;
398 i = 0;
399 rvec = info->rvec;
400 rvec[i++] = UWX_KEY_MODULE;
401 rvec[i++] = (uint64_t)(intptr_t)module_name;
402 rvec[i++] = UWX_KEY_TBASE;
403 rvec[i++] = desc->text_base;
404 rvec[i++] = UWX_KEY_END;
405 rvec[i++] = 0;
406 *resultp = rvec;
407 return UWX_LKUP_SYMINFO;
408 }
409 else if (request == UWX_LKUP_SYMBOLS) {
410 rvec = *resultp;
411 for (i = 0; rvec[i] != UWX_KEY_END; i += 2) {
412 if (rvec[i] == UWX_KEY_FUNCSTART)
413 ip = rvec[i+1];
414 }
415 desc = uwx_get_modinfo(info, ip, &module_name);
416 if (desc == NULL)
417 return UWX_LKUP_ERR;
418 if (module_name == NULL)
419 return UWX_LKUP_ERR;
420 status = uwx_find_symbol(info->env,
421 &info->load_module_cache->symbol_cache,
422 module_name, ip - desc->text_base,
423 &func_name, &offset);
424 i = 0;
425 rvec = info->rvec;
426 rvec[i++] = UWX_KEY_MODULE;
427 rvec[i++] = (uint64_t)(intptr_t)module_name;
428 rvec[i++] = UWX_KEY_TBASE;
429 rvec[i++] = desc->text_base;
430 if (status == UWX_OK) {
431 rvec[i++] = UWX_KEY_FUNC;
432 rvec[i++] = (uint64_t)(intptr_t)func_name;
433 rvec[i++] = UWX_KEY_FUNCSTART;
434 rvec[i++] = ip - offset;
435 }
436 rvec[i++] = UWX_KEY_END;
437 rvec[i++] = 0;
438 *resultp = rvec;
439 return UWX_LKUP_SYMINFO;
440 }
441 return UWX_LKUP_ERR;
284}
442}