CACAO
patcher-common.cpp
Go to the documentation of this file.
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"
56 #include "vm/jit/disass.hpp"
57 #include "vm/jit/jit.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 
71 {
72  code->patchers = new PatcherListTy();
73 }
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 
84 {
85  STATISTICS(size_patchref -= sizeof(patchref_t) * code->patchers->size());
86 
87  // Free all elements of the list.
88  code->patchers->clear();
89 }
90 
91 /* patcher_list_free ***********************************************************
92 
93  Frees the patcher list and all its entries for the given codeinfo.
94 
95 *******************************************************************************/
96 
98 {
99  // Free all elements of the list.
100  patcher_list_reset(code);
101 
102  // Free the list itself.
103  delete code->patchers;
104 }
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  bool operator() (const PatcherPtrTy& pr,
123  const void* pc) const {
124  return (pr->get_mpc() == (uintptr_t) pc);
125  }
126 };
127 
128 } // end anonymous namespace
129 
131 {
132  // Search for a patcher with the given PC.
133  PatcherListTy::iterator it = std::find_if(code->patchers->begin(),
134  code->patchers->end(), std::bind2nd(find_patcher(), pc));
135 
136  if (it == code->patchers->end())
137  return NULL;
138 
139  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)
151 {
152  for (PatcherListTy::iterator i = code->patchers->begin(),
153  e = code->patchers->end(); i != e; ++i) {
154  PatcherPtrTy& pr = (*i);
155 
156  pr->print(cacao::out());
157  cacao::out() << cacao::nl;
158 
159  }
160 }
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 patchref_t *patcher_add_patch_ref(jitdata *jd, functionptr patcher, void* ref, s4 disp)
173 {
174  codegendata *cd = jd->cd;
175  codeinfo *code = jd->code;
176 
177 #if defined(ALIGN_PATCHER_TRAP)
179 #endif
180 
181  int32_t patchmpc = cd->mcodeptr - cd->mcodebase;
182 
183 #if !defined(NDEBUG)
184  if (patcher_list_find(code, (void*) (intptr_t) patchmpc) != NULL)
185  os::abort("patcher_add_patch_ref: different patchers at same position.");
186 #endif
187 
188 #if defined(USES_PATCHABLE_MEMORY_BARRIER)
189  PATCHER_NOPS;
190 #endif
191 
192  // Set patcher information (mpc is resolved later).
193  patchref_t pr;
194 
195  pr.mpc = patchmpc;
196  pr.datap = 0;
197  pr.disp = disp;
198  pr.disp_mb = 0;
199  pr.patch_align = 0;
200  pr.patcher = patcher;
201  pr.ref = ref;
202  pr.mcode = 0;
203 
204  // Store patcher in the list (NOTE: structure is copied).
205  cacao::LegacyPatcher *legacy = new cacao::LegacyPatcher(jd,pr);
206  PatcherPtrTy ptr(legacy);
207  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 
224 #endif
225 
226  //return code->patchers->back()->get();
227  return legacy->get();
228 }
229 
230 
231 /**
232  * Resolve all patchers in the current JIT run.
233  *
234  * @param jd JIT data-structure
235  */
237 {
238  for (PatcherListTy::iterator i = code->patchers->begin(),
239  e = code->patchers->end(); i != e; ++i) {
240  PatcherPtrTy& pr = (*i);
241 
242  pr->reposition((intptr_t) code->entrypoint);
243  LOG2("Patcher " << pr->get_name() << " reposition: " << pr->get_mpc() << cacao::nl);
244  }
245 }
246 
247 /**
248  *
249  */
251 {
253 
254  // Get the patcher for the given PC.
255  PatcherPtrTy* pr = patcher_list_find(code, pc);
256 
257  if (pr == NULL) {
258  // The given PC is not a patcher position.
259  return false;
260  }
261 
262  // Validate the instruction.
263  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 
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  code = code_find_codeinfo_for_pc(pc);
297  assert(code);
298 
299  // Enter a mutex on the patcher list.
300  code->patchers->lock();
301 
302  /* search the patcher information for the given PC */
303 
304  PatcherPtrTy *pr_p = patcher_list_find(code, pc);
305 
306  if (pr_p == NULL)
307  os::abort("patcher_handler: Unable to find patcher reference.");
308 
309  PatcherPtrTy &pr = *pr_p;
310 
311  if (pr->is_patched()) {
312 #if !defined(NDEBUG)
313  if (opt_DebugPatcher) {
314  log_println("patcher_handler: double-patching detected!");
315  }
316 #endif
317  code->patchers->unlock();
318  return true;
319  }
320 
321 #if !defined(NDEBUG)
322  if (opt_DebugPatcher) {
323 
324  TRACE_PATCHER_INDENT; printf("patching in "); method_print(code->m); printf(" at %p\n", (void *) pr->get_mpc());
325  TRACE_PATCHER_INDENT; printf("\tpatcher function = %s\n", pr->get_name());
326 
328  printf("\tmachine code before = ");
329 
330 # if defined(ENABLE_DISASSEMBLER)
331  disassinstr((u1*) (void*) pr->get_mpc());
332 # else
333  printf("%x at %p (disassembler disabled)\n", *((uint32_t*) pr->get_mpc()), (void*) pr->get_mpc());
334 # endif
335 
336  patcher_depth++;
337  assert(patcher_depth > 0);
338  }
339 #endif
340 
341  /* call the proper patcher function */
342 
343  result = pr->patch();
344 
345 #if !defined(NDEBUG)
346  if (opt_DebugPatcher) {
347  assert(patcher_depth > 0);
348  patcher_depth--;
349 
351  printf("\tmachine code after = ");
352 
353 # if defined(ENABLE_DISASSEMBLER)
354  disassinstr((u1*) (void*) pr->get_mpc());
355 # else
356  printf("%x at %p (disassembler disabled)\n", *((uint32_t*) pr->get_mpc()), (void*) pr->get_mpc());
357 # endif
358 
359  if (result == false) {
360  TRACE_PATCHER_INDENT; printf("\tPATCHER EXCEPTION!\n");
361  }
362  }
363 #endif
364 
365  // Check return value and mangle the pending exception.
366  if (result == false)
368 
369  code->patchers->unlock();
370 
371  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 
383 {
384  classinfo *c;
385 
386  /* get stuff from the patcher reference */
387 
388  c = (classinfo *) pr->ref;
389 
390  /* check if the class is initialized */
391 
392  if (!(c->state & CLASS_INITIALIZED))
393  if (!initialize_class(c))
394  return false;
395 
396  /* patch back original code */
397 
398  patcher_patch_code(pr);
399 
400  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
413 {
414  unresolved_class *uc;
415 
416  /* get stuff from the patcher reference */
417 
418  uc = (unresolved_class *) pr->ref;
419 
420  /* resolve the class and check subtype constraints */
421 
423  return false;
424 
425  /* patch back original code */
426 
427  patcher_patch_code(pr);
428 
429  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 
442 {
443  methodinfo *m;
444  uint8_t *datap;
445 
446  /* get stuff from the patcher reference */
447 
448  m = (methodinfo *) pr->ref;
449  datap = (uint8_t *) pr->datap;
450 
451  /* resolve native function */
452 
454  void* f = nm.resolve_method(m);
455 
456  if (f == NULL)
457  return false;
458 
459  /* patch native function pointer */
460 
461  *((intptr_t*) datap) = (intptr_t) f;
462 
463  /* synchronize data cache */
464 
465  md_dcacheflush(datap, SIZEOF_VOID_P);
466 
467  /* patch back original code */
468 
469  patcher_patch_code(pr);
470 
471  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  */
481 {
482  // Get stuff from the patcher reference.
483  Breakpoint* breakp = (Breakpoint*) pr->ref;
484 
485  // Hook point when a breakpoint was triggered.
486  Hook::breakpoint(breakp);
487 
488  // In case the breakpoint wants to be kept active, we simply
489  // fail to "patch" at this point.
490  if (!breakp->is_oneshot)
491  return false;
492 
493  // Patch back original code.
494  patcher_patch_code(pr);
495 
496  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 
bool patcher_handler(u1 *pc)
#define STATISTICS(x)
Wrapper for statistics only code.
Definition: statistics.hpp:975
functionptr patcher
Definition: jit.hpp:126
void method_print(methodinfo *m)
Definition: method.cpp:1189
Table containing all native methods registered with the VM.
Definition: native.hpp:132
NativeMethods & get_nativemethods()
Definition: vm.hpp:128
u1 * disassinstr(u1 *code)
Definition: disass.cpp:48
#define TRACE_PATCHER_INDENT
#define PATCHER_CALL_SIZE
Definition: codegen.hpp:68
bool patcher_resolve_native_function(patchref_t *pr)
codeinfo * code
Definition: jit.hpp:128
s4 state
Definition: class.hpp:115
codegendata * cd
Definition: jit.hpp:129
void resolve_handle_pending_exception(bool throwError)
Definition: resolve.cpp:78
typedef void(JNICALL *jvmtiEventSingleStep)(jvmtiEnv *jvmti_env
classinfo * resolve_class_eager_no_access_check(unresolved_class *ref)
Definition: resolve.cpp:1044
static void md_dcacheflush(void *addr, int nbytes)
Definition: md.hpp:163
patchref_t * patcher_add_patch_ref(jitdata *jd, functionptr patcher, void *ref, s4 disp)
void patcher_resolve(codeinfo *code)
Resolve all patchers in the current JIT run.
This structure contains information about a breakpoint.
Definition: breakpoint.hpp:41
uint8_t u1
Definition: types.hpp:40
void log_println(const char *text,...)
Definition: logging.cpp:193
void(* functionptr)(void)
Definition: global.hpp:39
methodinfo * m
Definition: code.hpp:75
bool is_oneshot
Indicates a &quot;one-shot&quot;.
Definition: breakpoint.hpp:42
codeinfo * code_find_codeinfo_for_pc(void *pc)
Definition: code.cpp:101
bool patcher_resolve_class(patchref_t *pr)
static PatcherPtrTy * patcher_list_find(codeinfo *code, void *pc)
void patcher_list_show(codeinfo *code)
Show the content of the whole patcher reference list for debugging purposes.
int16_t disp_mb
void patcher_patch_code(patchref_t *pr)
Definition: patcher.cpp:114
void patcher_list_create(codeinfo *code)
void patcher_list_reset(codeinfo *code)
LockedList< PatcherPtrTy > PatcherListTy
Definition: code.hpp:61
MIIterator i
#define LOG2(STMT)
Definition: logging.hpp:93
int32_t s4
Definition: types.hpp:45
int16_t patch_align
cacao::shared_ptr< cacao::Patcher > PatcherPtrTy
Definition: code.hpp:60
bool initialize_class(classinfo *c)
Definition: initialize.cpp:110
int opt_DebugPatcher
Definition: options.cpp:171
static void abort()
Definition: os.hpp:196
void * resolve_method(methodinfo *m)
Resolves a native method, maybe from a dynamic library.
Definition: native.cpp:271
MIIterator e
bool patcher_initialize_class(patchref_t *pr)
#define pc
Definition: md-asm.hpp:56
void breakpoint(Breakpoint *bp)
Definition: hook.hpp:70
PatcherListTy * patchers
Definition: code.hpp:98
void emit_patcher_alignment(codegendata *cd)
Definition: emit.cpp:578
uintptr_t datap
bool patcher_breakpoint(patchref_t *pr)
Deals with breakpoint instructions (ICMD_BREAKPOINT) compiled into a JIT method.
uint32_t mcode
OStream & out()
Definition: OStream.cpp:39
void unlock()
Definition: list.hpp:73
static int patcher_depth
uintptr_t mpc
Nl nl
Definition: OStream.cpp:56
#define STAT_DECLARE_VAR(type, var, init)
Declare an external statistics variable.
Definition: statistics.hpp:963
#define PATCHER_NOPS
Definition: codegen.hpp:70
#define printf(...)
Definition: ssa2.cpp:40
void lock()
Definition: list.hpp:72
patchref_t * get()
return the raw resource
Definition: PatcherNew.hpp:140
void patcher_list_free(codeinfo *code)
static VM * get_current()
Definition: vm.hpp:99
u1 * entrypoint
Definition: code.hpp:84
bool patcher_is_patched_at(void *pc)