i386 / x86_64: Align patcher trap instruction.
[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 /* patcher_add_patch_ref *******************************************************
164
165    Appends a new patcher reference to the list of patching positions.
166
167 *******************************************************************************/
168
169 void patcher_add_patch_ref(jitdata *jd, functionptr patcher, void* ref, s4 disp)
170 {
171         codegendata *cd;
172         codeinfo    *code;
173         s4           patchmpc;
174
175         cd       = jd->cd;
176         code     = jd->code;
177         patchmpc = cd->mcodeptr - cd->mcodebase;
178
179 #if defined(ALIGN_PATCHER_TRAP)
180         emit_patcher_alignment(cd);
181         patchmpc = cd->mcodeptr - cd->mcodebase;
182 #endif
183
184 #if !defined(NDEBUG)
185         if (patcher_list_find(code, (void*) (intptr_t) patchmpc) != NULL)
186                 vm_abort("patcher_add_patch_ref: different patchers at same position.");
187 #endif
188
189         // Set patcher information (mpc is resolved later).
190         patchref_t pr;
191
192         pr.mpc     = patchmpc;
193         pr.datap   = 0;
194         pr.disp    = disp;
195         pr.patcher = patcher;
196         pr.ref     = ref;
197         pr.mcode   = 0;
198         pr.done    = false;
199
200         // Store patcher in the list (NOTE: structure is copied).
201         code->patchers->push_back(pr);
202
203 #if defined(ENABLE_STATISTICS)
204         if (opt_stat)
205                 size_patchref += sizeof(patchref_t);
206 #endif
207
208 #if defined(ENABLE_JIT) && (defined(__I386__) || defined(__M68K__) || defined(__SPARC_64__) || defined(__X86_64__))
209
210         /* XXX We can remove that when we don't use UD2 anymore on i386
211            and x86_64. */
212
213         /* On some architectures the patcher stub call instruction might
214            be longer than the actual instruction generated.  On this
215            architectures we store the last patcher call position and after
216            the basic block code generation is completed, we check the
217            range and maybe generate some nop's. */
218         /* The nops are generated in codegen_emit in each codegen */
219
220         cd->lastmcodeptr = cd->mcodeptr + PATCHER_CALL_SIZE;
221 #endif
222 }
223
224
225 /**
226  * Resolve all patchers in the current JIT run.
227  *
228  * @param jd JIT data-structure
229  */
230 void patcher_resolve(jitdata* jd)
231 {
232         // Get required compiler data.
233         codeinfo* code = jd->code;
234
235         for (List<patchref_t>::iterator it = code->patchers->begin(); it != code->patchers->end(); it++) {
236                 patchref_t& pr = *it;
237
238                 pr.mpc   += (intptr_t) code->entrypoint;
239                 pr.datap  = (intptr_t) (pr.disp + code->entrypoint);
240         }
241 }
242
243
244 /**
245  * Check if the patcher is already patched.  This is done by comparing
246  * the machine instruction.
247  *
248  * @param pr Patcher structure.
249  *
250  * @return true if patched, false otherwise.
251  */
252 bool patcher_is_patched(patchref_t* pr)
253 {
254         // Validate the instruction at the patching position is the same
255         // instruction as the patcher structure contains.
256         uint32_t mcode = *((uint32_t*) pr->mpc);
257
258 #if PATCHER_CALL_SIZE == 4
259         if (mcode != pr->mcode) {
260 #elif PATCHER_CALL_SIZE == 2
261         if ((uint16_t) mcode != (uint16_t) pr->mcode) {
262 #else
263 #error Unknown PATCHER_CALL_SIZE
264 #endif
265                 // The code differs.
266                 return false;
267         }
268
269         return true;
270 }
271
272
273 /**
274  *
275  */
276 bool patcher_is_patched_at(void* pc)
277 {
278         codeinfo* code = code_find_codeinfo_for_pc(pc);
279
280         // Get the patcher for the given PC.
281         patchref_t* pr = patcher_list_find(code, pc);
282
283         if (pr == NULL) {
284                 // The given PC is not a patcher position.
285                 return false;
286         }
287
288         // Validate the instruction.
289         return patcher_is_patched(pr);
290 }
291
292
293 /* patcher_handler *************************************************************
294
295    Handles the request to patch JIT code at the given patching
296    position. This function is normally called by the signal
297    handler.
298
299    NOTE: The patcher list lock is used to maintain exclusive
300    access of the patched position (in fact of the whole code).
301    After patching has suceeded, the patcher reference should be
302    removed from the patcher list to avoid double patching.
303
304 *******************************************************************************/
305
306 #if !defined(NDEBUG)
307 /* XXX this indent is not thread safe! */
308 /* XXX if you want it thread safe, place patcher_depth in threadobject! */
309 static int patcher_depth = 0;
310 #define TRACE_PATCHER_INDENT for (i=0; i<patcher_depth; i++) printf("\t")
311 #endif /* !defined(NDEBUG) */
312
313 java_handle_t *patcher_handler(u1 *pc)
314 {
315         codeinfo      *code;
316         patchref_t    *pr;
317         bool           result;
318 #if !defined(NDEBUG)
319         patcher_function_list_t *l;
320         int                      i;
321 #endif
322
323         /* define the patcher function */
324
325         bool (*patcher_function)(patchref_t *);
326
327         /* search the codeinfo for the given PC */
328
329         code = code_find_codeinfo_for_pc(pc);
330         assert(code);
331
332         // Enter a mutex on the patcher list.
333         code->patchers->lock();
334
335         /* search the patcher information for the given PC */
336
337         pr = patcher_list_find(code, pc);
338
339         if (pr == NULL)
340                 vm_abort("patcher_handler: Unable to find patcher reference.");
341
342         if (pr->done) {
343 #if !defined(NDEBUG)
344                 if (opt_DebugPatcher) {
345                         log_println("patcher_handler: double-patching detected!");
346                 }
347 #endif
348                 code->patchers->unlock();
349                 return NULL;
350         }
351
352 #if !defined(NDEBUG)
353         if (opt_DebugPatcher) {
354                 for (l = patcher_function_list; l->patcher != NULL; l++)
355                         if (l->patcher == pr->patcher)
356                                 break;
357
358                 TRACE_PATCHER_INDENT; printf("patching in "); method_print(code->m); printf(" at %p\n", (void *) pr->mpc);
359                 TRACE_PATCHER_INDENT; printf("\tpatcher function = %s <%p>\n", l->name, (void *) (intptr_t) pr->patcher);
360
361                 TRACE_PATCHER_INDENT;
362                 printf("\tmachine code before = ");
363
364 # if defined(ENABLE_DISASSEMBLER)
365                 disassinstr((u1*) (void*) pr->mpc);
366 # else
367                 printf("%x at %p (disassembler disabled)\n", *((uint32_t*) pr->mpc), (void*) pr->mpc);
368 # endif
369
370                 patcher_depth++;
371                 assert(patcher_depth > 0);
372         }
373 #endif
374
375         /* cast the passed function to a patcher function */
376
377         patcher_function = (bool (*)(patchref_t *)) (ptrint) pr->patcher;
378
379         /* call the proper patcher function */
380
381         result = (patcher_function)(pr);
382
383 #if !defined(NDEBUG)
384         if (opt_DebugPatcher) {
385                 assert(patcher_depth > 0);
386                 patcher_depth--;
387
388                 TRACE_PATCHER_INDENT;
389                 printf("\tmachine code after  = ");
390
391 # if defined(ENABLE_DISASSEMBLER)
392                 disassinstr((u1*) (void*) pr->mpc);
393 # else
394                 printf("%x at %p (disassembler disabled)\n", *((uint32_t*) pr->mpc), (void*) pr->mpc);
395 # endif
396
397                 if (result == false) {
398                         TRACE_PATCHER_INDENT; printf("\tPATCHER EXCEPTION!\n");
399                 }
400         }
401 #endif
402
403         // Check for return value and exit accordingly.
404         if (result == false) {
405                 // Mangle the pending exception.
406                 resolve_handle_pending_exception(true);
407
408                 // Get the exception and return it.
409                 java_handle_t* e = exceptions_get_and_clear_exception();
410
411                 code->patchers->unlock();
412
413                 return e;
414         }
415
416         pr->done = true; /* XXX this is only preliminary to prevent double-patching */
417
418         code->patchers->unlock();
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
495         /* get stuff from the patcher reference */
496
497         m     = (methodinfo *) pr->ref;
498         datap = (uint8_t *)    pr->datap;
499
500         /* resolve native function */
501
502         NativeMethods& nm = VM::get_current()->get_nativemethods();
503         void* f = nm.resolve_method(m);
504
505         if (f == NULL)
506                 return false;
507
508         /* patch native function pointer */
509
510         *((intptr_t*) datap) = (intptr_t) f;
511
512         /* synchronize data cache */
513
514         md_dcacheflush(datap, SIZEOF_VOID_P);
515
516         /* patch back original code */
517
518         patcher_patch_code(pr);
519
520         return true;
521 }
522
523
524 /*
525  * These are local overrides for various environment variables in Emacs.
526  * Please do not remove this and leave it at the end of the file, where
527  * Emacs will automagically detect them.
528  * ---------------------------------------------------------------------
529  * Local variables:
530  * mode: c++
531  * indent-tabs-mode: t
532  * c-basic-offset: 4
533  * tab-width: 4
534  * End:
535  * vim:noexpandtab:sw=4:ts=4:
536  */
537