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