1 /* src/vm/jit/patcher-common.cpp - architecture independent code patching stuff
3 Copyright (C) 2007, 2008, 2009
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 Copyright (C) 2008 Theobroma Systems Ltd.
7 This file is part of CACAO.
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.
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.
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
35 #include "codegen.h" /* for PATCHER_NOPS */
39 #include "mm/memory.hpp"
41 #include "native/native.hpp"
43 #include "toolbox/list.hpp"
44 #include "toolbox/logging.hpp" /* XXX remove me! */
46 #include "vm/breakpoint.hpp"
47 #include "vm/exceptions.hpp"
48 #include "vm/hook.hpp"
49 #include "vm/initialize.hpp"
50 #include "vm/options.h"
52 #include "vm/resolve.hpp"
54 #include "vm/jit/code.hpp"
55 #include "vm/jit/disass.h"
56 #include "vm/jit/jit.hpp"
57 #include "vm/jit/patcher-common.hpp"
60 /* patcher_function_list *******************************************************
62 This is a list which maps patcher function pointers to the according
63 names of the patcher functions. It is only usefull for debugging
66 *******************************************************************************/
69 typedef struct patcher_function_list_t {
72 } patcher_function_list_t;
74 static patcher_function_list_t patcher_function_list[] = {
75 { PATCHER_initialize_class, "initialize_class" },
76 #ifdef ENABLE_VERIFIER
77 { PATCHER_resolve_class, "resolve_class" },
78 #endif /* ENABLE_VERIFIER */
79 { PATCHER_resolve_native_function, "resolve_native_function" },
80 { PATCHER_invokestatic_special, "invokestatic_special" },
81 { PATCHER_invokevirtual, "invokevirtual" },
82 { PATCHER_invokeinterface, "invokeinterface" },
83 { PATCHER_breakpoint, "breakpoint" },
84 { NULL, "-UNKNOWN PATCHER FUNCTION-" }
89 /* patcher_list_create *********************************************************
91 Creates an empty patcher list for the given codeinfo.
93 *******************************************************************************/
95 void patcher_list_create(codeinfo *code)
97 code->patchers = new LockedList<patchref_t>();
101 /* patcher_list_reset **********************************************************
103 Resets the patcher list inside a codeinfo. This is usefull when
104 resetting a codeinfo for recompiling.
106 *******************************************************************************/
108 void patcher_list_reset(codeinfo *code)
110 #if defined(ENABLE_STATISTICS)
112 size_patchref -= sizeof(patchref_t) * code->patchers->size();
115 // Free all elements of the list.
116 code->patchers->clear();
119 /* patcher_list_free ***********************************************************
121 Frees the patcher list and all its entries for the given codeinfo.
123 *******************************************************************************/
125 void patcher_list_free(codeinfo *code)
127 // Free all elements of the list.
128 patcher_list_reset(code);
130 // Free the list itself.
131 delete code->patchers;
136 * Find an entry inside the patcher list for the given codeinfo by
137 * specifying the program counter of the patcher position.
139 * NOTE: Caller should hold the patcher list lock or maintain
140 * exclusive access otherwise.
142 * @param pc Program counter to find.
144 * @return Pointer to patcher.
147 struct foo : public std::binary_function<patchref_t, void*, bool> {
148 bool operator() (const patchref_t& pr, const void* pc) const
150 return (pr.mpc == (uintptr_t) pc);
154 static patchref_t* patcher_list_find(codeinfo* code, void* pc)
156 // Search for a patcher with the given PC.
157 List<patchref_t>::iterator it = std::find_if(code->patchers->begin(), code->patchers->end(), std::bind2nd(foo(), pc));
159 if (it == code->patchers->end())
167 * Show the content of the whole patcher reference list for
168 * debugging purposes.
170 * @param code The codeinfo containing the patcher list.
173 void patcher_list_show(codeinfo *code)
175 for (List<patchref_t>::iterator it = code->patchers->begin(); it != code->patchers->end(); it++) {
176 patchref_t& pr = *it;
178 // Lookup name in patcher function list.
179 patcher_function_list_t* l;
180 for (l = patcher_function_list; l->patcher != NULL; l++)
181 if (l->patcher == pr.patcher)
184 // Display information about patcher.
185 printf("\tpatcher pc:"PRINTF_FORMAT_INTPTR_T, pr.mpc);
186 printf(" datap:"PRINTF_FORMAT_INTPTR_T, pr.datap);
187 printf(" ref:"PRINTF_FORMAT_INTPTR_T, (intptr_t) pr.ref);
188 #if PATCHER_CALL_SIZE == 4
189 printf(" mcode:%08x", (uint32_t) pr.mcode);
190 #elif PATCHER_CALL_SIZE == 2
191 printf(" mcode:%04x", (uint16_t) pr.mcode);
193 # error Unknown PATCHER_CALL_SIZE
195 printf(" type:%s\n", l->name);
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));
209 /* patcher_add_patch_ref *******************************************************
211 Appends a new patcher reference to the list of patching positions.
213 *******************************************************************************/
215 void patcher_add_patch_ref(jitdata *jd, functionptr patcher, void* ref, s4 disp)
223 patchmpc = cd->mcodeptr - cd->mcodebase;
225 #if defined(ALIGN_PATCHER_TRAP)
226 emit_patcher_alignment(cd);
227 patchmpc = cd->mcodeptr - cd->mcodebase;
231 if (patcher_list_find(code, (void*) (intptr_t) patchmpc) != NULL)
232 os::abort("patcher_add_patch_ref: different patchers at same position.");
235 // Set patcher information (mpc is resolved later).
241 pr.patcher = patcher;
246 // Store patcher in the list (NOTE: structure is copied).
247 code->patchers->push_back(pr);
249 #if defined(ENABLE_STATISTICS)
251 size_patchref += sizeof(patchref_t);
254 #if defined(ENABLE_JIT) && (defined(__I386__) || defined(__M68K__) || defined(__SPARC_64__) || defined(__X86_64__))
256 /* XXX We can remove that when we don't use UD2 anymore on i386
259 /* On some architectures the patcher stub call instruction might
260 be longer than the actual instruction generated. On this
261 architectures we store the last patcher call position and after
262 the basic block code generation is completed, we check the
263 range and maybe generate some nop's. */
264 /* The nops are generated in codegen_emit in each codegen */
266 cd->lastmcodeptr = cd->mcodeptr + PATCHER_CALL_SIZE;
272 * Resolve all patchers in the current JIT run.
274 * @param jd JIT data-structure
276 void patcher_resolve(jitdata* jd)
278 // Get required compiler data.
279 codeinfo* code = jd->code;
281 for (List<patchref_t>::iterator it = code->patchers->begin(); it != code->patchers->end(); it++) {
282 patchref_t& pr = *it;
284 pr.mpc += (intptr_t) code->entrypoint;
285 pr.datap = (intptr_t) (pr.disp + code->entrypoint);
291 * Check if the patcher is already patched. This is done by comparing
292 * the machine instruction.
294 * @param pr Patcher structure.
296 * @return true if patched, false otherwise.
298 bool patcher_is_patched(patchref_t* pr)
300 // Validate the instruction at the patching position is the same
301 // instruction as the patcher structure contains.
302 uint32_t mcode = *((uint32_t*) pr->mpc);
304 #if PATCHER_CALL_SIZE == 4
305 if (mcode != pr->mcode) {
306 #elif PATCHER_CALL_SIZE == 2
307 if ((uint16_t) mcode != (uint16_t) pr->mcode) {
309 #error Unknown PATCHER_CALL_SIZE
322 bool patcher_is_patched_at(void* pc)
324 codeinfo* code = code_find_codeinfo_for_pc(pc);
326 // Get the patcher for the given PC.
327 patchref_t* pr = patcher_list_find(code, pc);
330 // The given PC is not a patcher position.
334 // Validate the instruction.
335 return patcher_is_patched(pr);
339 /* patcher_handler *************************************************************
341 Handles the request to patch JIT code at the given patching
342 position. This function is normally called by the signal
345 NOTE: The patcher list lock is used to maintain exclusive
346 access of the patched position (in fact of the whole code).
347 After patching has suceeded, the patcher reference should be
348 removed from the patcher list to avoid double patching.
350 *******************************************************************************/
353 /* XXX this indent is not thread safe! */
354 /* XXX if you want it thread safe, place patcher_depth in threadobject! */
355 static int patcher_depth = 0;
356 #define TRACE_PATCHER_INDENT for (i=0; i<patcher_depth; i++) printf("\t")
357 #endif /* !defined(NDEBUG) */
359 java_handle_t *patcher_handler(u1 *pc)
365 patcher_function_list_t *l;
369 /* define the patcher function */
371 bool (*patcher_function)(patchref_t *);
373 /* search the codeinfo for the given PC */
375 code = code_find_codeinfo_for_pc(pc);
378 // Enter a mutex on the patcher list.
379 code->patchers->lock();
381 /* search the patcher information for the given PC */
383 pr = patcher_list_find(code, pc);
386 os::abort("patcher_handler: Unable to find patcher reference.");
390 if (opt_DebugPatcher) {
391 log_println("patcher_handler: double-patching detected!");
394 code->patchers->unlock();
399 if (opt_DebugPatcher) {
400 for (l = patcher_function_list; l->patcher != NULL; l++)
401 if (l->patcher == pr->patcher)
404 TRACE_PATCHER_INDENT; printf("patching in "); method_print(code->m); printf(" at %p\n", (void *) pr->mpc);
405 TRACE_PATCHER_INDENT; printf("\tpatcher function = %s <%p>\n", l->name, (void *) (intptr_t) pr->patcher);
407 TRACE_PATCHER_INDENT;
408 printf("\tmachine code before = ");
410 # if defined(ENABLE_DISASSEMBLER)
411 disassinstr((u1*) (void*) pr->mpc);
413 printf("%x at %p (disassembler disabled)\n", *((uint32_t*) pr->mpc), (void*) pr->mpc);
417 assert(patcher_depth > 0);
421 /* cast the passed function to a patcher function */
423 patcher_function = (bool (*)(patchref_t *)) (ptrint) pr->patcher;
425 /* call the proper patcher function */
427 result = (patcher_function)(pr);
430 if (opt_DebugPatcher) {
431 assert(patcher_depth > 0);
434 TRACE_PATCHER_INDENT;
435 printf("\tmachine code after = ");
437 # if defined(ENABLE_DISASSEMBLER)
438 disassinstr((u1*) (void*) pr->mpc);
440 printf("%x at %p (disassembler disabled)\n", *((uint32_t*) pr->mpc), (void*) pr->mpc);
443 if (result == false) {
444 TRACE_PATCHER_INDENT; printf("\tPATCHER EXCEPTION!\n");
449 // Check for return value and exit accordingly.
450 if (result == false) {
451 // Mangle the pending exception.
452 resolve_handle_pending_exception(true);
454 // Get the exception and return it.
455 java_handle_t* e = exceptions_get_and_clear_exception();
457 code->patchers->unlock();
462 pr->done = true; /* XXX this is only preliminary to prevent double-patching */
464 code->patchers->unlock();
470 /* patcher_initialize_class ****************************************************
472 Initalizes a given classinfo pointer.
473 This function does not patch any data.
475 *******************************************************************************/
477 bool patcher_initialize_class(patchref_t *pr)
481 /* get stuff from the patcher reference */
483 c = (classinfo *) pr->ref;
485 /* check if the class is initialized */
487 if (!(c->state & CLASS_INITIALIZED))
488 if (!initialize_class(c))
491 /* patch back original code */
493 patcher_patch_code(pr);
499 /* patcher_resolve_class *******************************************************
501 Resolves a given unresolved class reference.
502 This function does not patch any data.
504 *******************************************************************************/
506 #ifdef ENABLE_VERIFIER
507 bool patcher_resolve_class(patchref_t *pr)
509 unresolved_class *uc;
511 /* get stuff from the patcher reference */
513 uc = (unresolved_class *) pr->ref;
515 /* resolve the class and check subtype constraints */
517 if (!resolve_class_eager_no_access_check(uc))
520 /* patch back original code */
522 patcher_patch_code(pr);
526 #endif /* ENABLE_VERIFIER */
529 /* patcher_resolve_native_function *********************************************
531 Resolves the native function for a given methodinfo.
532 This function patches one data segment word.
534 *******************************************************************************/
536 bool patcher_resolve_native_function(patchref_t *pr)
541 /* get stuff from the patcher reference */
543 m = (methodinfo *) pr->ref;
544 datap = (uint8_t *) pr->datap;
546 /* resolve native function */
548 NativeMethods& nm = VM::get_current()->get_nativemethods();
549 void* f = nm.resolve_method(m);
554 /* patch native function pointer */
556 *((intptr_t*) datap) = (intptr_t) f;
558 /* synchronize data cache */
560 md_dcacheflush(datap, SIZEOF_VOID_P);
562 /* patch back original code */
564 patcher_patch_code(pr);
571 * Deals with breakpoint instructions (ICMD_BREAKPOINT) compiled
572 * into a JIT method. This patcher might never patch back the
573 * original machine code because breakpoints are kept active.
575 bool patcher_breakpoint(patchref_t *pr)
577 // Get stuff from the patcher reference.
578 Breakpoint* breakp = (Breakpoint*) pr->ref;
580 // Hook point when a breakpoint was triggered.
581 Hook::breakpoint(breakp);
583 // In case the breakpoint wants to be kept active, we simply
584 // fail to "patch" at this point.
585 if (!breakp->is_oneshot)
588 // Patch back original code.
589 patcher_patch_code(pr);
596 * These are local overrides for various environment variables in Emacs.
597 * Please do not remove this and leave it at the end of the file, where
598 * Emacs will automagically detect them.
599 * ---------------------------------------------------------------------
602 * indent-tabs-mode: t
606 * vim:noexpandtab:sw=4:ts=4: