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