Line data Source code
1 : /* src/vm/jit/patcher-common.cpp - architecture independent code patching stuff
2 :
3 : Copyright (C) 1996-2013
4 : CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 : Copyright (C) 2008 Theobroma Systems Ltd.
6 :
7 : This file is part of CACAO.
8 :
9 : This program is free software; you can redistribute it and/or
10 : modify it under the terms of the GNU General Public License as
11 : published by the Free Software Foundation; either version 2, or (at
12 : your option) any later version.
13 :
14 : This program is distributed in the hope that it will be useful, but
15 : WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : General Public License for more details.
18 :
19 : You should have received a copy of the GNU General Public License
20 : along with this program; if not, write to the Free Software
21 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 : 02110-1301, USA.
23 :
24 : */
25 :
26 :
27 : #include "config.h"
28 :
29 : #include <cassert>
30 : #include <stdint.h>
31 : #include <inttypes.h>
32 :
33 : #include <algorithm>
34 : #include <functional>
35 :
36 : #include "codegen.hpp" /* for PATCHER_NOPS */
37 : #include "md.hpp"
38 : #include "trap.hpp"
39 :
40 : #include "native/native.hpp"
41 :
42 : #include "toolbox/list.hpp"
43 : #include "toolbox/logging.hpp" /* XXX remove me! */
44 :
45 : #include "vm/breakpoint.hpp"
46 : #include "vm/exceptions.hpp"
47 : #include "vm/hook.hpp"
48 : #include "vm/initialize.hpp"
49 : #include "vm/options.hpp"
50 : #include "vm/os.hpp"
51 : #include "vm/resolve.hpp"
52 : #include "vm/vm.hpp"
53 :
54 : #include "vm/jit/code.hpp"
55 : #include "vm/jit/codegen-common.hpp"
56 : #include "vm/jit/disass.hpp"
57 : #include "vm/jit/jit.hpp"
58 : #include "vm/jit/patcher-common.hpp"
59 :
60 : STAT_DECLARE_VAR(int,size_patchref,0)
61 :
62 : /* patcher_function_list *******************************************************
63 :
64 : This is a list which maps patcher function pointers to the according
65 : names of the patcher functions. It is only usefull for debugging
66 : purposes.
67 :
68 : *******************************************************************************/
69 :
70 : #if !defined(NDEBUG)
71 : typedef struct patcher_function_list_t {
72 : functionptr patcher;
73 : const char* name;
74 : } patcher_function_list_t;
75 :
76 : static patcher_function_list_t patcher_function_list[] = {
77 : { PATCHER_initialize_class, "initialize_class" },
78 : #ifdef ENABLE_VERIFIER
79 : { PATCHER_resolve_class, "resolve_class" },
80 : #endif /* ENABLE_VERIFIER */
81 : { PATCHER_resolve_native_function, "resolve_native_function" },
82 : { PATCHER_invokestatic_special, "invokestatic_special" },
83 : { PATCHER_invokevirtual, "invokevirtual" },
84 : { PATCHER_invokeinterface, "invokeinterface" },
85 : { PATCHER_breakpoint, "breakpoint" },
86 : { NULL, "-UNKNOWN PATCHER FUNCTION-" }
87 : };
88 : #endif
89 :
90 :
91 : /* patcher_list_create *********************************************************
92 :
93 : Creates an empty patcher list for the given codeinfo.
94 :
95 : *******************************************************************************/
96 :
97 105324 : void patcher_list_create(codeinfo *code)
98 : {
99 105324 : code->patchers = new LockedList<patchref_t>();
100 105324 : }
101 :
102 :
103 : /* patcher_list_reset **********************************************************
104 :
105 : Resets the patcher list inside a codeinfo. This is usefull when
106 : resetting a codeinfo for recompiling.
107 :
108 : *******************************************************************************/
109 :
110 37 : void patcher_list_reset(codeinfo *code)
111 : {
112 : STATISTICS(size_patchref -= sizeof(patchref_t) * code->patchers->size());
113 :
114 : // Free all elements of the list.
115 37 : code->patchers->clear();
116 37 : }
117 :
118 : /* patcher_list_free ***********************************************************
119 :
120 : Frees the patcher list and all its entries for the given codeinfo.
121 :
122 : *******************************************************************************/
123 :
124 37 : void patcher_list_free(codeinfo *code)
125 : {
126 : // Free all elements of the list.
127 37 : patcher_list_reset(code);
128 :
129 : // Free the list itself.
130 37 : delete code->patchers;
131 37 : }
132 :
133 :
134 : /**
135 : * Find an entry inside the patcher list for the given codeinfo by
136 : * specifying the program counter of the patcher position.
137 : *
138 : * NOTE: Caller should hold the patcher list lock or maintain
139 : * exclusive access otherwise.
140 : *
141 : * @param pc Program counter to find.
142 : *
143 : * @return Pointer to patcher.
144 : */
145 :
146 : struct foo : public std::binary_function<patchref_t, void*, bool> {
147 5755676 : bool operator() (const patchref_t& pr, const void* pc) const
148 : {
149 5755676 : return (pr.mpc == (uintptr_t) pc);
150 : }
151 : };
152 :
153 213670 : static patchref_t* patcher_list_find(codeinfo* code, void* pc)
154 : {
155 : // Search for a patcher with the given PC.
156 213670 : List<patchref_t>::iterator it = std::find_if(code->patchers->begin(), code->patchers->end(), std::bind2nd(foo(), pc));
157 :
158 213670 : if (it == code->patchers->end())
159 142523 : return NULL;
160 :
161 71147 : return &(*it);
162 : }
163 :
164 :
165 : /**
166 : * Show the content of the whole patcher reference list for
167 : * debugging purposes.
168 : *
169 : * @param code The codeinfo containing the patcher list.
170 : */
171 : #if !defined(NDEBUG)
172 0 : void patcher_list_show(codeinfo *code)
173 : {
174 0 : for (List<patchref_t>::iterator it = code->patchers->begin(); it != code->patchers->end(); it++) {
175 0 : patchref_t& pr = *it;
176 :
177 : // Lookup name in patcher function list.
178 : patcher_function_list_t* l;
179 0 : for (l = patcher_function_list; l->patcher != NULL; l++)
180 0 : if (l->patcher == pr.patcher)
181 0 : break;
182 :
183 : // Display information about patcher.
184 0 : printf("\tpatcher");
185 0 : printf(" pc:0x%016"PRIxPTR, pr.mpc);
186 0 : printf(" datap:0x%016"PRIxPTR, pr.datap);
187 0 : printf(" ref:0x%016"PRIxPTR, (uintptr_t) pr.ref);
188 : #if PATCHER_CALL_SIZE == 4
189 : printf(" mcode:%08"PRIx32, (uint32_t) pr.mcode);
190 : #elif PATCHER_CALL_SIZE == 2
191 0 : printf(" mcode:%04"PRIx16, (uint16_t) pr.mcode);
192 : #else
193 : # error Unknown PATCHER_CALL_SIZE
194 : #endif
195 0 : printf(" type:%s\n", l->name);
196 :
197 : // Display machine code of patched position.
198 : #if 0 && defined(ENABLE_DISASSEMBLER)
199 : printf("\t\tcurrent -> ");
200 : disassinstr((uint8_t*) pr.mpc);
201 : printf("\t\tapplied -> ");
202 : disassinstr((uint8_t*) &(pr.mcode));
203 : #endif
204 : }
205 0 : }
206 : #endif
207 :
208 :
209 : /* patcher_add_patch_ref *******************************************************
210 :
211 : Appends a new patcher reference to the list of patching positions.
212 :
213 : Returns a pointer to the newly created patchref_t.
214 :
215 : *******************************************************************************/
216 :
217 142523 : patchref_t *patcher_add_patch_ref(jitdata *jd, functionptr patcher, void* ref, s4 disp)
218 : {
219 142523 : codegendata *cd = jd->cd;
220 142523 : codeinfo *code = jd->code;
221 :
222 : #if defined(ALIGN_PATCHER_TRAP)
223 142523 : emit_patcher_alignment(cd);
224 : #endif
225 :
226 142523 : int32_t patchmpc = cd->mcodeptr - cd->mcodebase;
227 :
228 : #if !defined(NDEBUG)
229 142523 : if (patcher_list_find(code, (void*) (intptr_t) patchmpc) != NULL)
230 0 : os::abort("patcher_add_patch_ref: different patchers at same position.");
231 : #endif
232 :
233 : #if defined(USES_PATCHABLE_MEMORY_BARRIER)
234 142523 : PATCHER_NOPS;
235 : #endif
236 :
237 : // Set patcher information (mpc is resolved later).
238 : patchref_t pr;
239 :
240 142523 : pr.mpc = patchmpc;
241 142523 : pr.datap = 0;
242 142523 : pr.disp = disp;
243 142523 : pr.disp_mb = 0;
244 142523 : pr.patch_align = 0;
245 142523 : pr.patcher = patcher;
246 142523 : pr.ref = ref;
247 142523 : pr.mcode = 0;
248 142523 : pr.done = false;
249 :
250 : // Store patcher in the list (NOTE: structure is copied).
251 142523 : code->patchers->push_back(pr);
252 :
253 : STATISTICS(size_patchref += sizeof(patchref_t));
254 :
255 : #if defined(ENABLE_JIT) && (defined(__I386__) || defined(__SPARC_64__) || defined(__X86_64__))
256 :
257 : /* XXX We can remove that when we don't use UD2 anymore on i386
258 : and x86_64. */
259 :
260 : /* On some architectures the patcher stub call instruction might
261 : be longer than the actual instruction generated. On this
262 : architectures we store the last patcher call position and after
263 : the basic block code generation is completed, we check the
264 : range and maybe generate some nop's. */
265 : /* The nops are generated in codegen_emit in each codegen */
266 :
267 142523 : cd->lastmcodeptr = cd->mcodeptr + PATCHER_CALL_SIZE;
268 : #endif
269 :
270 142523 : return &code->patchers->back();
271 : }
272 :
273 :
274 : /**
275 : * Resolve all patchers in the current JIT run.
276 : *
277 : * @param jd JIT data-structure
278 : */
279 99456 : void patcher_resolve(jitdata* jd)
280 : {
281 : // Get required compiler data.
282 99456 : codeinfo* code = jd->code;
283 :
284 241979 : for (List<patchref_t>::iterator it = code->patchers->begin(); it != code->patchers->end(); it++) {
285 142523 : patchref_t& pr = *it;
286 :
287 142523 : pr.mpc += (intptr_t) code->entrypoint;
288 142523 : pr.datap = (intptr_t) (pr.disp + code->entrypoint);
289 : }
290 99456 : }
291 :
292 :
293 : /**
294 : * Check if the patcher is already patched. This is done by comparing
295 : * the machine instruction.
296 : *
297 : * @param pr Patcher structure.
298 : *
299 : * @return true if patched, false otherwise.
300 : */
301 1 : bool patcher_is_patched(patchref_t* pr)
302 : {
303 : // Validate the instruction at the patching position is the same
304 : // instruction as the patcher structure contains.
305 1 : uint32_t mcode = *((uint32_t*) pr->mpc);
306 :
307 : #if PATCHER_CALL_SIZE == 4
308 : if (mcode != pr->mcode) {
309 : #elif PATCHER_CALL_SIZE == 2
310 1 : if ((uint16_t) mcode != (uint16_t) pr->mcode) {
311 : #else
312 : #error Unknown PATCHER_CALL_SIZE
313 : #endif
314 : // The code differs.
315 0 : return false;
316 : }
317 :
318 1 : return true;
319 : }
320 :
321 :
322 : /**
323 : *
324 : */
325 1 : bool patcher_is_patched_at(void* pc)
326 : {
327 1 : codeinfo* code = code_find_codeinfo_for_pc(pc);
328 :
329 : // Get the patcher for the given PC.
330 1 : patchref_t* pr = patcher_list_find(code, pc);
331 :
332 1 : if (pr == NULL) {
333 : // The given PC is not a patcher position.
334 0 : return false;
335 : }
336 :
337 : // Validate the instruction.
338 1 : return patcher_is_patched(pr);
339 : }
340 :
341 :
342 : /* patcher_handler *************************************************************
343 :
344 : Handles the request to patch JIT code at the given patching
345 : position. This function is normally called by the signal
346 : handler.
347 :
348 : NOTE: The patcher list lock is used to maintain exclusive
349 : access of the patched position (in fact of the whole code).
350 : After patching has suceeded, the patcher reference should be
351 : removed from the patcher list to avoid double patching.
352 :
353 : *******************************************************************************/
354 :
355 : #if !defined(NDEBUG)
356 : /* XXX this indent is not thread safe! */
357 : /* XXX if you want it thread safe, place patcher_depth in threadobject! */
358 : static int patcher_depth = 0;
359 : #define TRACE_PATCHER_INDENT for (i=0; i<patcher_depth; i++) printf("\t")
360 : #endif /* !defined(NDEBUG) */
361 :
362 71146 : bool patcher_handler(u1 *pc)
363 : {
364 : codeinfo *code;
365 : patchref_t *pr;
366 : bool result;
367 : #if !defined(NDEBUG)
368 : patcher_function_list_t *l;
369 : int i;
370 : #endif
371 :
372 : /* define the patcher function */
373 :
374 : bool (*patcher_function)(patchref_t *);
375 :
376 : /* search the codeinfo for the given PC */
377 :
378 71146 : code = code_find_codeinfo_for_pc(pc);
379 71146 : assert(code);
380 :
381 : // Enter a mutex on the patcher list.
382 71146 : code->patchers->lock();
383 :
384 : /* search the patcher information for the given PC */
385 :
386 71146 : pr = patcher_list_find(code, pc);
387 :
388 71146 : if (pr == NULL)
389 0 : os::abort("patcher_handler: Unable to find patcher reference.");
390 :
391 71146 : if (pr->done) {
392 : #if !defined(NDEBUG)
393 5 : if (opt_DebugPatcher) {
394 0 : log_println("patcher_handler: double-patching detected!");
395 : }
396 : #endif
397 5 : code->patchers->unlock();
398 5 : return true;
399 : }
400 :
401 : #if !defined(NDEBUG)
402 71141 : if (opt_DebugPatcher) {
403 0 : for (l = patcher_function_list; l->patcher != NULL; l++)
404 0 : if (l->patcher == pr->patcher)
405 0 : break;
406 :
407 0 : TRACE_PATCHER_INDENT; printf("patching in "); method_print(code->m); printf(" at %p\n", (void *) pr->mpc);
408 0 : TRACE_PATCHER_INDENT; printf("\tpatcher function = %s <%p>\n", l->name, (void *) (intptr_t) pr->patcher);
409 :
410 0 : TRACE_PATCHER_INDENT;
411 0 : printf("\tmachine code before = ");
412 :
413 : # if defined(ENABLE_DISASSEMBLER)
414 : disassinstr((u1*) (void*) pr->mpc);
415 : # else
416 0 : printf("%x at %p (disassembler disabled)\n", *((uint32_t*) pr->mpc), (void*) pr->mpc);
417 : # endif
418 :
419 0 : patcher_depth++;
420 0 : assert(patcher_depth > 0);
421 : }
422 : #endif
423 :
424 : /* cast the passed function to a patcher function */
425 :
426 71141 : patcher_function = (bool (*)(patchref_t *)) (ptrint) pr->patcher;
427 :
428 : /* call the proper patcher function */
429 :
430 71141 : result = (patcher_function)(pr);
431 :
432 : #if !defined(NDEBUG)
433 71141 : if (opt_DebugPatcher) {
434 0 : assert(patcher_depth > 0);
435 0 : patcher_depth--;
436 :
437 0 : TRACE_PATCHER_INDENT;
438 0 : printf("\tmachine code after = ");
439 :
440 : # if defined(ENABLE_DISASSEMBLER)
441 : disassinstr((u1*) (void*) pr->mpc);
442 : # else
443 0 : printf("%x at %p (disassembler disabled)\n", *((uint32_t*) pr->mpc), (void*) pr->mpc);
444 : # endif
445 :
446 0 : if (result == false) {
447 0 : TRACE_PATCHER_INDENT; printf("\tPATCHER EXCEPTION!\n");
448 : }
449 : }
450 : #endif
451 :
452 : // Check return value and mangle the pending exception.
453 71141 : if (result == false)
454 13 : resolve_handle_pending_exception(true);
455 :
456 : // XXX This is only preliminary to prevent double-patching.
457 : else
458 71128 : pr->done = true;
459 :
460 71141 : code->patchers->unlock();
461 :
462 71141 : return result;
463 : }
464 :
465 :
466 : /* patcher_initialize_class ****************************************************
467 :
468 : Initalizes a given classinfo pointer.
469 : This function does not patch any data.
470 :
471 : *******************************************************************************/
472 :
473 723 : bool patcher_initialize_class(patchref_t *pr)
474 : {
475 : classinfo *c;
476 :
477 : /* get stuff from the patcher reference */
478 :
479 723 : c = (classinfo *) pr->ref;
480 :
481 : /* check if the class is initialized */
482 :
483 723 : if (!(c->state & CLASS_INITIALIZED))
484 296 : if (!initialize_class(c))
485 0 : return false;
486 :
487 : /* patch back original code */
488 :
489 723 : patcher_patch_code(pr);
490 :
491 723 : return true;
492 : }
493 :
494 :
495 : /* patcher_resolve_class *******************************************************
496 :
497 : Resolves a given unresolved class reference.
498 : This function does not patch any data.
499 :
500 : *******************************************************************************/
501 :
502 : #ifdef ENABLE_VERIFIER
503 2990 : bool patcher_resolve_class(patchref_t *pr)
504 : {
505 : unresolved_class *uc;
506 :
507 : /* get stuff from the patcher reference */
508 :
509 2990 : uc = (unresolved_class *) pr->ref;
510 :
511 : /* resolve the class and check subtype constraints */
512 :
513 2990 : if (!resolve_class_eager_no_access_check(uc))
514 3 : return false;
515 :
516 : /* patch back original code */
517 :
518 2987 : patcher_patch_code(pr);
519 :
520 2987 : return true;
521 : }
522 : #endif /* ENABLE_VERIFIER */
523 :
524 :
525 : /* patcher_resolve_native_function *********************************************
526 :
527 : Resolves the native function for a given methodinfo.
528 : This function patches one data segment word.
529 :
530 : *******************************************************************************/
531 :
532 0 : bool patcher_resolve_native_function(patchref_t *pr)
533 : {
534 : methodinfo *m;
535 : uint8_t *datap;
536 :
537 : /* get stuff from the patcher reference */
538 :
539 0 : m = (methodinfo *) pr->ref;
540 0 : datap = (uint8_t *) pr->datap;
541 :
542 : /* resolve native function */
543 :
544 0 : NativeMethods& nm = VM::get_current()->get_nativemethods();
545 0 : void* f = nm.resolve_method(m);
546 :
547 0 : if (f == NULL)
548 0 : return false;
549 :
550 : /* patch native function pointer */
551 :
552 0 : *((intptr_t*) datap) = (intptr_t) f;
553 :
554 : /* synchronize data cache */
555 :
556 0 : md_dcacheflush(datap, SIZEOF_VOID_P);
557 :
558 : /* patch back original code */
559 :
560 0 : patcher_patch_code(pr);
561 :
562 0 : return true;
563 : }
564 :
565 :
566 : /**
567 : * Deals with breakpoint instructions (ICMD_BREAKPOINT) compiled
568 : * into a JIT method. This patcher might never patch back the
569 : * original machine code because breakpoints are kept active.
570 : */
571 0 : bool patcher_breakpoint(patchref_t *pr)
572 : {
573 : // Get stuff from the patcher reference.
574 0 : Breakpoint* breakp = (Breakpoint*) pr->ref;
575 :
576 : // Hook point when a breakpoint was triggered.
577 0 : Hook::breakpoint(breakp);
578 :
579 : // In case the breakpoint wants to be kept active, we simply
580 : // fail to "patch" at this point.
581 0 : if (!breakp->is_oneshot)
582 0 : return false;
583 :
584 : // Patch back original code.
585 0 : patcher_patch_code(pr);
586 :
587 0 : return true;
588 : }
589 :
590 :
591 : /*
592 : * These are local overrides for various environment variables in Emacs.
593 : * Please do not remove this and leave it at the end of the file, where
594 : * Emacs will automagically detect them.
595 : * ---------------------------------------------------------------------
596 : * Local variables:
597 : * mode: c++
598 : * indent-tabs-mode: t
599 : * c-basic-offset: 4
600 : * tab-width: 4
601 : * End:
602 : * vim:noexpandtab:sw=4:ts=4:
603 : */
604 :
|