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/initialize.hpp"
49 #include "vm/options.h"
51 #include "vm/resolve.hpp"
53 #include "vm/jit/code.hpp"
54 #include "vm/jit/disass.h"
55 #include "vm/jit/jit.hpp"
56 #include "vm/jit/patcher-common.hpp"
59 /* patcher_function_list *******************************************************
61 This is a list which maps patcher function pointers to the according
62 names of the patcher functions. It is only usefull for debugging
65 *******************************************************************************/
68 typedef struct patcher_function_list_t {
71 } patcher_function_list_t;
73 static patcher_function_list_t patcher_function_list[] = {
74 { PATCHER_initialize_class, "initialize_class" },
75 #ifdef ENABLE_VERIFIER
76 { PATCHER_resolve_class, "resolve_class" },
77 #endif /* ENABLE_VERIFIER */
78 { PATCHER_resolve_native_function, "resolve_native_function" },
79 { PATCHER_invokestatic_special, "invokestatic_special" },
80 { PATCHER_invokevirtual, "invokevirtual" },
81 { PATCHER_invokeinterface, "invokeinterface" },
82 { PATCHER_breakpoint, "breakpoint" },
83 { NULL, "-UNKNOWN PATCHER FUNCTION-" }
88 /* patcher_list_create *********************************************************
90 Creates an empty patcher list for the given codeinfo.
92 *******************************************************************************/
94 void patcher_list_create(codeinfo *code)
96 code->patchers = new LockedList<patchref_t>();
100 /* patcher_list_reset **********************************************************
102 Resets the patcher list inside a codeinfo. This is usefull when
103 resetting a codeinfo for recompiling.
105 *******************************************************************************/
107 void patcher_list_reset(codeinfo *code)
109 #if defined(ENABLE_STATISTICS)
111 size_patchref -= sizeof(patchref_t) * code->patchers->size();
114 // Free all elements of the list.
115 code->patchers->clear();
118 /* patcher_list_free ***********************************************************
120 Frees the patcher list and all its entries for the given codeinfo.
122 *******************************************************************************/
124 void patcher_list_free(codeinfo *code)
126 // Free all elements of the list.
127 patcher_list_reset(code);
129 // Free the list itself.
130 delete code->patchers;
135 * Find an entry inside the patcher list for the given codeinfo by
136 * specifying the program counter of the patcher position.
138 * NOTE: Caller should hold the patcher list lock or maintain
139 * exclusive access otherwise.
141 * @param pc Program counter to find.
143 * @return Pointer to patcher.
146 struct foo : public std::binary_function<patchref_t, void*, bool> {
147 bool operator() (const patchref_t& pr, const void* pc) const
149 return (pr.mpc == (uintptr_t) pc);
153 static patchref_t* patcher_list_find(codeinfo* code, void* pc)
155 // Search for a patcher with the given PC.
156 List<patchref_t>::iterator it = std::find_if(code->patchers->begin(), code->patchers->end(), std::bind2nd(foo(), pc));
158 if (it == code->patchers->end())
166 * Show the content of the whole patcher reference list for
167 * debugging purposes.
169 * @param code The codeinfo containing the patcher list.
172 void patcher_list_show(codeinfo *code)
174 for (List<patchref_t>::iterator it = code->patchers->begin(); it != code->patchers->end(); it++) {
175 patchref_t& pr = *it;
177 // Lookup name in patcher function list.
178 patcher_function_list_t* l;
179 for (l = patcher_function_list; l->patcher != NULL; l++)
180 if (l->patcher == pr.patcher)
183 // Display information about patcher.
184 printf("\tpatcher pc:"PRINTF_FORMAT_INTPTR_T, pr.mpc);
185 printf(" datap:"PRINTF_FORMAT_INTPTR_T, pr.datap);
186 printf(" ref:"PRINTF_FORMAT_INTPTR_T, (intptr_t) pr.ref);
187 #if PATCHER_CALL_SIZE == 4
188 printf(" mcode:%08x", (uint32_t) pr.mcode);
189 #elif PATCHER_CALL_SIZE == 2
190 printf(" mcode:%04x", (uint16_t) pr.mcode);
192 # error Unknown PATCHER_CALL_SIZE
194 printf(" type:%s\n", l->name);
196 // Display machine code of patched position.
197 #if 0 && defined(ENABLE_DISASSEMBLER)
198 printf("\t\tcurrent -> ");
199 disassinstr((uint8_t*) pr.mpc);
200 printf("\t\tapplied -> ");
201 disassinstr((uint8_t*) &(pr.mcode));
208 /* patcher_add_patch_ref *******************************************************
210 Appends a new patcher reference to the list of patching positions.
212 Returns a pointer to the newly created patchref_t.
214 *******************************************************************************/
216 patchref_t *patcher_add_patch_ref(jitdata *jd, functionptr patcher, void* ref, s4 disp)
218 codegendata *cd = jd->cd;
219 codeinfo *code = jd->code;
221 #if defined(ALIGN_PATCHER_TRAP)
222 emit_patcher_alignment(cd);
225 int32_t patchmpc = cd->mcodeptr - cd->mcodebase;
228 if (patcher_list_find(code, (void*) (intptr_t) patchmpc) != NULL)
229 os::abort("patcher_add_patch_ref: different patchers at same position.");
232 #if defined(USES_PATCHABLE_MEMORY_BARRIER)
236 // Set patcher information (mpc is resolved later).
243 pr.patcher = patcher;
248 // Store patcher in the list (NOTE: structure is copied).
249 code->patchers->push_back(pr);
251 #if defined(ENABLE_STATISTICS)
253 size_patchref += sizeof(patchref_t);
256 #if defined(ENABLE_JIT) && (defined(__I386__) || defined(__M68K__) || defined(__SPARC_64__) || defined(__X86_64__))
258 /* XXX We can remove that when we don't use UD2 anymore on i386
261 /* On some architectures the patcher stub call instruction might
262 be longer than the actual instruction generated. On this
263 architectures we store the last patcher call position and after
264 the basic block code generation is completed, we check the
265 range and maybe generate some nop's. */
266 /* The nops are generated in codegen_emit in each codegen */
268 cd->lastmcodeptr = cd->mcodeptr + PATCHER_CALL_SIZE;
271 return &code->patchers->back();
276 * Resolve all patchers in the current JIT run.
278 * @param jd JIT data-structure
280 void patcher_resolve(jitdata* jd)
282 // Get required compiler data.
283 codeinfo* code = jd->code;
285 for (List<patchref_t>::iterator it = code->patchers->begin(); it != code->patchers->end(); it++) {
286 patchref_t& pr = *it;
288 pr.mpc += (intptr_t) code->entrypoint;
289 pr.datap = (intptr_t) (pr.disp + code->entrypoint);
295 * Check if the patcher is already patched. This is done by comparing
296 * the machine instruction.
298 * @param pr Patcher structure.
300 * @return true if patched, false otherwise.
302 bool patcher_is_patched(patchref_t* pr)
304 // Validate the instruction at the patching position is the same
305 // instruction as the patcher structure contains.
306 uint32_t mcode = *((uint32_t*) pr->mpc);
308 #if PATCHER_CALL_SIZE == 4
309 if (mcode != pr->mcode) {
310 #elif PATCHER_CALL_SIZE == 2
311 if ((uint16_t) mcode != (uint16_t) pr->mcode) {
313 #error Unknown PATCHER_CALL_SIZE
326 bool patcher_is_patched_at(void* pc)
328 codeinfo* code = code_find_codeinfo_for_pc(pc);
330 // Get the patcher for the given PC.
331 patchref_t* pr = patcher_list_find(code, pc);
334 // The given PC is not a patcher position.
338 // Validate the instruction.
339 return patcher_is_patched(pr);
343 /* patcher_handler *************************************************************
345 Handles the request to patch JIT code at the given patching
346 position. This function is normally called by the signal
349 NOTE: The patcher list lock is used to maintain exclusive
350 access of the patched position (in fact of the whole code).
351 After patching has suceeded, the patcher reference should be
352 removed from the patcher list to avoid double patching.
354 *******************************************************************************/
357 /* XXX this indent is not thread safe! */
358 /* XXX if you want it thread safe, place patcher_depth in threadobject! */
359 static int patcher_depth = 0;
360 #define TRACE_PATCHER_INDENT for (i=0; i<patcher_depth; i++) printf("\t")
361 #endif /* !defined(NDEBUG) */
363 java_handle_t *patcher_handler(u1 *pc)
369 patcher_function_list_t *l;
373 /* define the patcher function */
375 bool (*patcher_function)(patchref_t *);
377 /* search the codeinfo for the given PC */
379 code = code_find_codeinfo_for_pc(pc);
382 // Enter a mutex on the patcher list.
383 code->patchers->lock();
385 /* search the patcher information for the given PC */
387 pr = patcher_list_find(code, pc);
390 os::abort("patcher_handler: Unable to find patcher reference.");
394 if (opt_DebugPatcher) {
395 log_println("patcher_handler: double-patching detected!");
398 code->patchers->unlock();
403 if (opt_DebugPatcher) {
404 for (l = patcher_function_list; l->patcher != NULL; l++)
405 if (l->patcher == pr->patcher)
408 TRACE_PATCHER_INDENT; printf("patching in "); method_print(code->m); printf(" at %p\n", (void *) pr->mpc);
409 TRACE_PATCHER_INDENT; printf("\tpatcher function = %s <%p>\n", l->name, (void *) (intptr_t) pr->patcher);
411 TRACE_PATCHER_INDENT;
412 printf("\tmachine code before = ");
414 # if defined(ENABLE_DISASSEMBLER)
415 disassinstr((u1*) (void*) pr->mpc);
417 printf("%x at %p (disassembler disabled)\n", *((uint32_t*) pr->mpc), (void*) pr->mpc);
421 assert(patcher_depth > 0);
425 /* cast the passed function to a patcher function */
427 patcher_function = (bool (*)(patchref_t *)) (ptrint) pr->patcher;
429 /* call the proper patcher function */
431 result = (patcher_function)(pr);
434 if (opt_DebugPatcher) {
435 assert(patcher_depth > 0);
438 TRACE_PATCHER_INDENT;
439 printf("\tmachine code after = ");
441 # if defined(ENABLE_DISASSEMBLER)
442 disassinstr((u1*) (void*) pr->mpc);
444 printf("%x at %p (disassembler disabled)\n", *((uint32_t*) pr->mpc), (void*) pr->mpc);
447 if (result == false) {
448 TRACE_PATCHER_INDENT; printf("\tPATCHER EXCEPTION!\n");
453 // Check for return value and exit accordingly.
454 if (result == false) {
455 // Mangle the pending exception.
456 resolve_handle_pending_exception(true);
458 // Get the exception and return it.
459 java_handle_t* e = exceptions_get_and_clear_exception();
461 code->patchers->unlock();
466 pr->done = true; /* XXX this is only preliminary to prevent double-patching */
468 code->patchers->unlock();
474 /* patcher_initialize_class ****************************************************
476 Initalizes a given classinfo pointer.
477 This function does not patch any data.
479 *******************************************************************************/
481 bool patcher_initialize_class(patchref_t *pr)
485 /* get stuff from the patcher reference */
487 c = (classinfo *) pr->ref;
489 /* check if the class is initialized */
491 if (!(c->state & CLASS_INITIALIZED))
492 if (!initialize_class(c))
495 /* patch back original code */
497 patcher_patch_code(pr);
503 /* patcher_resolve_class *******************************************************
505 Resolves a given unresolved class reference.
506 This function does not patch any data.
508 *******************************************************************************/
510 #ifdef ENABLE_VERIFIER
511 bool patcher_resolve_class(patchref_t *pr)
513 unresolved_class *uc;
515 /* get stuff from the patcher reference */
517 uc = (unresolved_class *) pr->ref;
519 /* resolve the class and check subtype constraints */
521 if (!resolve_class_eager_no_access_check(uc))
524 /* patch back original code */
526 patcher_patch_code(pr);
530 #endif /* ENABLE_VERIFIER */
533 /* patcher_resolve_native_function *********************************************
535 Resolves the native function for a given methodinfo.
536 This function patches one data segment word.
538 *******************************************************************************/
540 bool patcher_resolve_native_function(patchref_t *pr)
545 /* get stuff from the patcher reference */
547 m = (methodinfo *) pr->ref;
548 datap = (uint8_t *) pr->datap;
550 /* resolve native function */
552 NativeMethods& nm = VM::get_current()->get_nativemethods();
553 void* f = nm.resolve_method(m);
558 /* patch native function pointer */
560 *((intptr_t*) datap) = (intptr_t) f;
562 /* synchronize data cache */
564 md_dcacheflush(datap, SIZEOF_VOID_P);
566 /* patch back original code */
568 patcher_patch_code(pr);
575 * Deals with breakpoint instructions (ICMD_BREAKPOINT) compiled
576 * into a JIT method. This patcher might never patch back the
577 * original machine code because breakpoints are kept active.
579 bool patcher_breakpoint(patchref_t *pr)
581 // Get stuff from the patcher reference.
582 Breakpoint* breakp = (Breakpoint*) pr->ref;
584 #if defined(ENABLE_JVMTI)
585 methodinfo* m = breakp->method;
586 int32_t l = breakp->location;
588 log_message_method("JVMTI: Reached breakpoint in method ", m);
589 log_println("JVMTI: Reached breakpoint at location %d", l);
592 // In case the breakpoint wants to be kept active, we simply
593 // fail to "patch" at this point.
594 if (!breakp->is_oneshot)
597 // Patch back original code.
598 patcher_patch_code(pr);
605 * These are local overrides for various environment variables in Emacs.
606 * Please do not remove this and leave it at the end of the file, where
607 * Emacs will automagically detect them.
608 * ---------------------------------------------------------------------
611 * indent-tabs-mode: t
615 * vim:noexpandtab:sw=4:ts=4: