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