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