CACAO
patcher.cpp
Go to the documentation of this file.
1 /* src/vm/jit/i386/patcher.cpp - i386 code patching functions
2 
3  Copyright (C) 1996-2013
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 
6  This file is part of CACAO.
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2, or (at
11  your option) any later version.
12 
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  02110-1301, USA.
22 
23 */
24 
25 
26 #include "config.h"
27 
28 #include <stdint.h>
29 
30 #include "vm/types.hpp"
31 
32 #include "vm/jit/i386/codegen.hpp"
33 #include "vm/jit/i386/md.hpp"
34 #include "vm/jit/i386/patcher.hpp"
35 
36 #include "mm/memory.hpp"
37 
38 #include "native/native.hpp"
39 
40 #include "vm/jit/builtin.hpp"
41 #include "vm/class.hpp"
42 #include "vm/field.hpp"
43 #include "vm/initialize.hpp"
44 #include "vm/options.hpp"
45 #include "vm/references.hpp"
46 #include "vm/resolve.hpp"
47 
49 
50 
51 /* patcher_patch_code **********************************************************
52 
53  Just patches back the original machine code.
54 
55 *******************************************************************************/
56 
58 {
59  *((uint16_t*) pr->mpc) = (uint16_t) pr->mcode;
60  md_icacheflush((void*) pr->mpc, PATCHER_CALL_SIZE);
61 }
62 
63 /**
64  * Check if the trap instruction at the given PC is valid.
65  *
66  * @param pc Program counter.
67  *
68  * @return true if valid, false otherwise.
69  */
71 {
72  uint16_t mcode = *((uint16_t*) pc);
73 
74  // Check for the undefined instruction we use.
75  return (mcode == 0x0b0f);
76 }
77 
78 
79 /* patcher_get_putstatic *******************************************************
80 
81  Machine code:
82 
83  <patched call position>
84  c7 c0 00 00 00 00 mov $0x00000000,%eax
85 
86 *******************************************************************************/
87 
89 {
90  u1 *ra;
91  unresolved_field *uf;
92  fieldinfo *fi;
93 
94  /* get stuff from the stack */
95 
96  ra = (u1 *) pr->mpc;
97  uf = (unresolved_field *) pr->ref;
98 
99  /* get the fieldinfo */
100 
101  if (!(fi = resolve_field_eager(uf)))
102  return false;
103 
104  /* check if the field's class is initialized */
105 
106  if (!(fi->clazz->state & CLASS_INITIALIZED))
107  if (!initialize_class(fi->clazz))
108  return false;
109 
110  /* patch the field value's address */
111 
112  *((intptr_t *) (ra + 2)) = (intptr_t) fi->value;
113  md_icacheflush((void*) (ra + 2), SIZEOF_VOID_P);
114 
115  // Patch back the original code.
116  patcher_patch_code(pr);
117 
118  return true;
119 }
120 
121 
122 /* patcher_getfield ************************************************************
123 
124  Machine code:
125 
126  <patched call position>
127  8b 88 00 00 00 00 mov 0x00000000(%eax),%ecx
128 
129 *******************************************************************************/
130 
132 {
133  u1 *ra;
134  unresolved_field *uf;
135  fieldinfo *fi;
136 
137  /* get stuff from the stack */
138 
139  ra = (u1 *) pr->mpc;
140  uf = (unresolved_field *) pr->ref;
141 
142  /* get the fieldinfo */
143 
144  if (!(fi = resolve_field_eager(uf)))
145  return false;
146 
147  /* patch the field's offset */
148 
149  *((u4 *) (ra + 2)) = (u4) (fi->offset);
150  int clen = SIZEOF_VOID_P;
151 
152  /* if the field has type long, we need to patch the second move too */
153 
154  if (fi->type == TYPE_LNG) {
155  *((u4 *) (ra + 6 + 2)) = (u4) (fi->offset + 4);
156  clen += 6;
157  }
158 
159  md_icacheflush((void*) (ra + 2), clen);
160 
161  // Patch back the original code.
162  patcher_patch_code(pr);
163 
164  return true;
165 }
166 
167 
168 /* patcher_putfield ************************************************************
169 
170  Machine code:
171 
172  <patched call position>
173  8b 88 00 00 00 00 mov 0x00000000(%eax),%ecx
174 
175 *******************************************************************************/
176 
178 {
179  u1 *ra;
180  unresolved_field *uf;
181  fieldinfo *fi;
182 
183  /* get stuff from the stack */
184 
185  ra = (u1 *) pr->mpc;
186  uf = (unresolved_field *) pr->ref;
187 
188  /* get the fieldinfo */
189 
190  if (!(fi = resolve_field_eager(uf)))
191  return false;
192 
193  /* patch the field's offset */
194 
195  int clen = SIZEOF_VOID_P;
196  if (fi->type != TYPE_LNG) {
197  *((u4 *) (ra + 2)) = (u4) (fi->offset);
198  }
199  else {
200  /* The long code is special:
201  *
202  * 89 8d 00 00 00 00 mov %ecx,0x00000000(%ebp)
203  * 89 95 00 00 00 00 mov %edx,0x00000000(%ebp)
204  */
205 
206  *((u4 *) (ra + 2)) = (u4) (fi->offset);
207  *((u4 *) (ra + 6 + 2)) = (u4) (fi->offset + 4);
208  clen += 6;
209  }
210 
211  md_icacheflush((void*) (ra + 2), clen);
212 
213  // Patch back the original code.
214  patcher_patch_code(pr);
215 
216  return true;
217 }
218 
219 
220 /* patcher_putfieldconst *******************************************************
221 
222  Machine code:
223 
224  <patched call position>
225  c7 85 00 00 00 00 7b 00 00 00 movl $0x7b,0x0(%ebp)
226 
227 *******************************************************************************/
228 
230 {
231  u1 *ra;
232  unresolved_field *uf;
233  fieldinfo *fi;
234 
235  /* get stuff from the stack */
236 
237  ra = (u1 *) pr->mpc;
238  uf = (unresolved_field *) pr->ref;
239 
240  /* get the fieldinfo */
241 
242  if (!(fi = resolve_field_eager(uf)))
243  return false;
244 
245  /* patch the field's offset */
246 
247  int clen = SIZEOF_VOID_P;
248  if (!IS_2_WORD_TYPE(fi->type)) {
249  *((u4 *) (ra + 2)) = (u4) (fi->offset);
250  }
251  else {
252  /* long/double code is different:
253  *
254  * c7 80 00 00 00 00 c8 01 00 00 movl $0x1c8,0x0(%eax)
255  * c7 80 04 00 00 00 00 00 00 00 movl $0x0,0x4(%eax)
256  */
257 
258  *((u4 *) (ra + 2)) = (u4) (fi->offset);
259  *((u4 *) (ra + 10 + 2)) = (u4) (fi->offset + 4);
260  clen += 10;
261  }
262 
263  md_icacheflush((void*) (ra + 2), clen);
264 
265  // Patch back the original code.
266  patcher_patch_code(pr);
267 
268  return true;
269 }
270 
271 
272 /* patcher_aconst **************************************************************
273 
274  Machine code:
275 
276  <patched call postition>
277  c7 c0 00 00 00 00 mov $0x00000000,%eax
278 
279 *******************************************************************************/
280 
282 {
283  u1 *ra;
284  constant_classref *cr;
285  classinfo *c;
286 
287  /* get stuff from the stack */
288 
289  ra = (u1 *) pr->mpc;
290  cr = (constant_classref *) pr->ref;
291 
292  /* get the classinfo */
293 
294  if (!(c = resolve_classref_eager(cr)))
295  return false;
296 
297  /* patch the classinfo pointer */
298 
299  *((ptrint *) (ra + 2)) = (ptrint) c;
300  md_icacheflush((void*) (ra + 2), SIZEOF_VOID_P);
301 
302  // Patch back the original code.
303  patcher_patch_code(pr);
304 
305  return true;
306 }
307 
308 
309 /* patcher_builtin_multianewarray **********************************************
310 
311  Machine code:
312 
313  <patched call position>
314  c7 04 24 02 00 00 00 movl $0x2,(%esp)
315  c7 44 24 04 00 00 00 00 movl $0x00000000,0x4(%esp)
316  89 e0 mov %esp,%eax
317  83 c0 0c add $0xc,%eax
318  89 44 24 08 mov %eax,0x8(%esp)
319  b8 00 00 00 00 mov $0x00000000,%eax
320  ff d0 call *%eax
321 
322 *******************************************************************************/
323 
325 {
326  u1 *ra;
327  constant_classref *cr;
328  classinfo *c;
329 
330  /* get stuff from the stack */
331 
332  ra = (u1 *) pr->mpc;
333  cr = (constant_classref *) pr->ref;
334 
335  /* get the classinfo */
336 
337  if (!(c = resolve_classref_eager(cr)))
338  return false;
339 
340  /* patch the classinfo pointer */
341 
342  *((ptrint *) (ra + 7 + 4)) = (ptrint) c;
343  md_icacheflush((void*) (ra + 7 + 4), SIZEOF_VOID_P);
344 
345  // Patch back the original code.
346  patcher_patch_code(pr);
347 
348  return true;
349 }
350 
351 
352 /* patcher_builtin_arraycheckcast **********************************************
353 
354  Machine code:
355 
356  <patched call position>
357  c7 44 24 04 00 00 00 00 movl $0x00000000,0x4(%esp)
358  ba 00 00 00 00 mov $0x00000000,%edx
359  ff d2 call *%edx
360 
361 *******************************************************************************/
362 
364 {
365  u1 *ra;
366  constant_classref *cr;
367  classinfo *c;
368 
369  /* get stuff from the stack */
370 
371  ra = (u1 *) pr->mpc;
372  cr = (constant_classref *) pr->ref;
373 
374  /* get the classinfo */
375 
376  if (!(c = resolve_classref_eager(cr)))
377  return false;
378 
379  /* patch the classinfo pointer */
380 
381  *((ptrint *) (ra + 4)) = (ptrint) c;
382 
383  /* patch new function address */
384 
385  *((ptrint *) (ra + 8 + 1)) = (ptrint) BUILTIN_arraycheckcast;
386  md_icacheflush((void*) (ra + 4), SIZEOF_VOID_P + 8 + 1 - 4);
387 
388  // Patch back the original code.
389  patcher_patch_code(pr);
390 
391  return true;
392 }
393 
394 
395 /* patcher_invokestatic_special ************************************************
396 
397  Machine code:
398 
399  <patched call position>
400  c7 c1 00 00 00 00 mov $0x00000000,%ecx
401  ff d1 call *%ecx
402 
403 *******************************************************************************/
404 
406 {
407  u1 *ra;
408  unresolved_method *um;
409  methodinfo *m;
410 
411  /* get stuff from the stack */
412 
413  ra = (u1 *) pr->mpc;
414  um = (unresolved_method *) pr->ref;
415 
416  /* get the fieldinfo */
417 
418  if (!(m = resolve_method_eager(um)))
419  return false;
420 
421  /* patch stubroutine */
422 
423  *((ptrint *) (ra + 2)) = (ptrint) m->stubroutine;
424  md_icacheflush((void*) (ra + 2), SIZEOF_VOID_P);
425 
426  // Patch back the original code.
427  patcher_patch_code(pr);
428 
429  return true;
430 }
431 
432 
433 /* patcher_invokevirtual *******************************************************
434 
435  Machine code:
436 
437  <patched call position>
438  8b 08 mov (%eax),%ecx
439  8b 81 00 00 00 00 mov 0x00000000(%ecx),%eax
440  ff d0 call *%eax
441 
442 *******************************************************************************/
443 
445 {
446  u1 *ra;
447  unresolved_method *um;
448  methodinfo *m;
449 
450  /* get stuff from the stack */
451 
452  ra = (u1 *) pr->mpc;
453  um = (unresolved_method *) pr->ref;
454 
455  /* get the fieldinfo */
456 
457  if (!(m = resolve_method_eager(um)))
458  return false;
459 
460  /* patch vftbl index */
461 
462  *((s4 *) (ra + 2 + 2)) = (s4) (OFFSET(vftbl_t, table[0]) +
463  sizeof(methodptr) * m->vftblindex);
464  md_icacheflush((void*) (ra + 2 + 2), SIZEOF_VOID_P);
465 
466  // Patch back the original code.
467  patcher_patch_code(pr);
468 
469  return true;
470 }
471 
472 
473 /* patcher_invokeinterface *****************************************************
474 
475  Machine code:
476 
477  <patched call position>
478  8b 00 mov (%eax),%eax
479  8b 88 00 00 00 00 mov 0x00000000(%eax),%ecx
480  8b 81 00 00 00 00 mov 0x00000000(%ecx),%eax
481  ff d0 call *%eax
482 
483 *******************************************************************************/
484 
486 {
487  u1 *ra;
488  unresolved_method *um;
489  methodinfo *m;
490 
491  /* get stuff from the stack */
492 
493  ra = (u1 *) pr->mpc;
494  um = (unresolved_method *) pr->ref;
495 
496  /* get the fieldinfo */
497 
498  if (!(m = resolve_method_eager(um)))
499  return false;
500 
501  /* patch interfacetable index */
502 
503  *((s4 *) (ra + 2 + 2)) = (s4) (OFFSET(vftbl_t, interfacetable[0]) -
504  sizeof(methodptr) * m->clazz->index);
505 
506  /* patch method offset */
507 
508  *((s4 *) (ra + 2 + 6 + 2)) =
509  (s4) (sizeof(methodptr) * (m - m->clazz->methods));
510  md_icacheflush((void*) (ra + 2 + 2), SIZEOF_VOID_P + 6);
511 
512  // Patch back the original code.
513  patcher_patch_code(pr);
514 
515  return true;
516 }
517 
518 
519 /* patcher_checkcast_instanceof_flags ******************************************
520 
521  Machine code:
522 
523  <patched call position>
524  c7 c1 00 00 00 00 mov $0x00000000,%ecx
525 
526 *******************************************************************************/
527 
529 {
530  u1 *ra;
531  constant_classref *cr;
532  classinfo *c;
533 
534  /* get stuff from the stack */
535 
536  ra = (u1 *) pr->mpc;
537  cr = (constant_classref *) pr->ref;
538 
539  /* get the fieldinfo */
540 
541  if (!(c = resolve_classref_eager(cr)))
542  return false;
543 
544  /* patch class flags */
545 
546  *((s4 *) (ra + 2)) = (s4) c->flags;
547  md_icacheflush((void*) (ra + 2), SIZEOF_VOID_P);
548 
549  // Patch back the original code.
550  patcher_patch_code(pr);
551 
552  return true;
553 }
554 
555 
556 /* patcher_checkcast_interface *************************************************
557 
558  Machine code:
559 
560  <patched call position>
561  8b 91 00 00 00 00 mov 0x00000000(%ecx),%edx
562  81 ea 00 00 00 00 sub $0x00000000,%edx
563  85 d2 test %edx,%edx
564  0f 8f 06 00 00 00 jg 0x00000000
565  8b 35 03 00 00 00 mov 0x3,%esi
566  8b 91 00 00 00 00 mov 0x00000000(%ecx),%edx
567 
568 *******************************************************************************/
569 
571 {
572  u1 *ra;
573  constant_classref *cr;
574  classinfo *c;
575 
576  /* get stuff from the stack */
577 
578  ra = (u1 *) pr->mpc;
579  cr = (constant_classref *) pr->ref;
580 
581  /* get the fieldinfo */
582 
583  if (!(c = resolve_classref_eager(cr)))
584  return false;
585 
586  /* patch super class index */
587 
588  *((s4 *) (ra + 6 + 2)) = (s4) c->index;
589 
590  *((s4 *) (ra + 6 + 6 + 2 + 6 + 6 + 2)) =
591  (s4) (OFFSET(vftbl_t, interfacetable[0]) -
592  c->index * sizeof(methodptr*));
593  md_icacheflush((void*) (ra + 6 + 2), SIZEOF_VOID_P + 6 + 6 + 6 + 2);
594 
595  // Patch back the original code.
596  patcher_patch_code(pr);
597 
598  return true;
599 }
600 
601 
602 /* patcher_instanceof_interface ************************************************
603 
604  Machine code:
605 
606  <patched call position>
607  8b 91 00 00 00 00 mov 0x00000000(%ecx),%edx
608  81 ea 00 00 00 00 sub $0x00000000,%edx
609  85 d2 test %edx,%edx
610  0f 8e 13 00 00 00 jle 0x00000000
611  8b 91 00 00 00 00 mov 0x00000000(%ecx),%edx
612 
613 *******************************************************************************/
614 
616 {
617  u1 *ra;
618  constant_classref *cr;
619  classinfo *c;
620 
621  /* get stuff from the stack */
622 
623  ra = (u1 *) pr->mpc;
624  cr = (constant_classref *) pr->ref;
625 
626  /* get the fieldinfo */
627 
628  if (!(c = resolve_classref_eager(cr)))
629  return false;
630 
631  /* patch super class index */
632 
633  *((s4 *) (ra + 6 + 2)) = (s4) c->index;
634 
635  *((s4 *) (ra + 6 + 6 + 2 + 6 + 2)) =
636  (s4) (OFFSET(vftbl_t, interfacetable[0]) -
637  c->index * sizeof(methodptr*));
638  md_icacheflush((void*) (ra + 6 + 2), SIZEOF_VOID_P + 6 + 6 + 2);
639 
640  // Patch back the original code.
641  patcher_patch_code(pr);
642 
643  return true;
644 }
645 
646 
647 /* patcher_checkcast_class *****************************************************
648 
649  Machine code:
650 
651  <patched call position>
652  c7 c1 00 00 00 00 mov $0x00000000,%ecx
653 
654 *******************************************************************************/
655 
657 {
658  u1 *ra;
659  constant_classref *cr;
660  classinfo *c;
661 
662  /* get stuff from the stack */
663 
664  ra = (u1 *) pr->mpc;
665  cr = (constant_classref *) pr->ref;
666 
667  /* get the fieldinfo */
668 
669  if (!(c = resolve_classref_eager(cr)))
670  return false;
671 
672  /* patch super class' vftbl */
673 
674  *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
675  md_icacheflush((void*) (ra + 2), SIZEOF_VOID_P);
676 
677  // Patch back the original code.
678  patcher_patch_code(pr);
679 
680  return true;
681 }
682 
683 
684 /* patcher_instanceof_class ****************************************************
685 
686  Machine code:
687 
688  <patched call position>
689  c7 c1 00 00 00 00 mov $0x00000000,%ecx
690 
691 *******************************************************************************/
692 
694 {
695  u1 *ra;
696  constant_classref *cr;
697  classinfo *c;
698 
699  /* get stuff from the stack */
700 
701  ra = (u1 *) pr->mpc;
702  cr = (constant_classref *) pr->ref;
703 
704  /* get the fieldinfo */
705 
706  if (!(c = resolve_classref_eager(cr)))
707  return false;
708 
709  /* patch super class' vftbl */
710 
711  *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
712  md_icacheflush((void*) (ra + 2), SIZEOF_VOID_P);
713 
714  // Patch back the original code.
715  patcher_patch_code(pr);
716 
717  return true;
718 }
719 
720 
721 #if !defined(NDEBUG)
723  { PATCHER_initialize_class, "initialize_class" },
724 #ifdef ENABLE_VERIFIER
725  { PATCHER_resolve_class, "resolve_class" },
726 #endif /* ENABLE_VERIFIER */
727  { PATCHER_resolve_native_function, "resolve_native_function" },
728  { PATCHER_invokestatic_special, "invokestatic_special" },
729  { PATCHER_invokevirtual, "invokevirtual" },
730  { PATCHER_invokeinterface, "invokeinterface" },
731  { PATCHER_breakpoint, "breakpoint" },
732  { PATCHER_checkcast_interface, "checkcast_interface" },
733  { PATCHER_instanceof_interface, "instanceof_interface" },
734  { PATCHER_get_putstatic, "get_putstatic" },
735  { PATCHER_getfield, "getfield" },
736  { PATCHER_putfield, "putfield" },
737  { PATCHER_putfieldconst, "putfieldconst" },
738  { PATCHER_builtin_multianewarray, "builtin_multianewarray" },
739  { PATCHER_builtin_arraycheckcast, "builtin_arraycheckcast" },
740  { PATCHER_checkcast_instanceof_flags, "checkcast_instanceof_flags" },
741  { PATCHER_checkcast_class, "checkcast_class" },
742  { PATCHER_instanceof_class, "instanceof_class" },
743  { NULL, "-UNKNOWN PATCHER FUNCTION-" }
744 };
745 #endif
746 
747 
748 /*
749  * These are local overrides for various environment variables in Emacs.
750  * Please do not remove this and leave it at the end of the file, where
751  * Emacs will automagically detect them.
752  * ---------------------------------------------------------------------
753  * Local variables:
754  * mode: c++
755  * indent-tabs-mode: t
756  * c-basic-offset: 4
757  * tab-width: 4
758  * End:
759  * vim:noexpandtab:sw=4:ts=4:
760  */
bool patcher_invokestatic_special(patchref_t *pr)
Definition: patcher.cpp:392
bool patcher_get_putstatic(patchref_t *pr)
Definition: patcher.cpp:264
#define PATCHER_invokeinterface
#define ra
Definition: md-asm.hpp:62
patcher_function_list
methodinfo * methods
Definition: class.hpp:113
bool patcher_invokeinterface(patchref_t *pr)
Definition: patcher.cpp:477
#define PATCHER_CALL_SIZE
Definition: codegen.hpp:68
bool patcher_instanceof_class(patchref_t *pr)
Definition: patcher.cpp:693
s4 state
Definition: class.hpp:115
#define PATCHER_resolve_class
#define PATCHER_putfieldconst
Definition: patcher.hpp:41
#define PATCHER_builtin_arraycheckcast
Definition: patcher.hpp:50
uint8_t u1
Definition: types.hpp:40
u1 * methodptr
Definition: global.hpp:40
#define PATCHER_breakpoint
patcher_function_list_t patcher_function_list[]
Definition: patcher.cpp:607
bool patcher_putfield(patchref_t *pr)
Definition: patcher.cpp:177
#define PATCHER_get_putstatic
#define PATCHER_checkcast_instanceof_flags
Definition: patcher.hpp:53
#define BUILTIN_arraycheckcast
Definition: builtin.hpp:148
#define PATCHER_instanceof_interface
#define IS_2_WORD_TYPE(a)
Definition: global.hpp:132
#define PATCHER_resolve_native_function
u1 * stubroutine
Definition: method.hpp:102
s4 vftblindex
Definition: method.hpp:81
int32_t offset
Definition: field.hpp:66
classinfo * clazz
Definition: method.hpp:80
void patcher_patch_code(patchref_t *pr)
Definition: patcher.cpp:114
#define OFFSET(s, el)
Definition: memory.hpp:90
bool patcher_invokevirtual(patchref_t *pr)
Definition: patcher.cpp:433
imm_union * value
Definition: field.hpp:67
bool patcher_aconst(patchref_t *pr)
Definition: patcher.cpp:281
#define PATCHER_checkcast_class
Definition: patcher.hpp:56
bool patcher_checkcast_interface(patchref_t *pr)
Definition: patcher.cpp:526
s4 flags
Definition: class.hpp:90
#define PATCHER_getfield
Definition: patcher.hpp:35
int32_t s4
Definition: types.hpp:45
classinfo * clazz
Definition: field.hpp:55
s4 index
Definition: class.hpp:116
bool initialize_class(classinfo *c)
Definition: initialize.cpp:110
bool patcher_putfieldconst(patchref_t *pr)
Definition: patcher.cpp:229
#define PATCHER_checkcast_interface
#define PATCHER_builtin_multianewarray
Definition: patcher.hpp:47
uint32_t u4
Definition: types.hpp:46
#define PATCHER_invokestatic_special
vftbl_t * vftbl
Definition: class.hpp:121
fieldinfo * resolve_field_eager(unresolved_field *ref)
Definition: resolve.cpp:1497
#define PATCHER_invokevirtual
#define pc
Definition: md-asm.hpp:56
#define PATCHER_instanceof_class
Definition: patcher.hpp:59
bool patcher_checkcast_instanceof_flags(patchref_t *pr)
Definition: patcher.cpp:528
s4 type
Definition: field.hpp:60
methodinfo * resolve_method_eager(unresolved_method *ref)
Definition: resolve.cpp:2236
uint32_t mcode
#define PATCHER_initialize_class
bool patcher_builtin_arraycheckcast(patchref_t *pr)
Definition: patcher.cpp:363
#define PATCHER_putfield
Definition: patcher.hpp:38
classinfo * resolve_classref_eager(constant_classref *ref)
Definition: resolve.cpp:961
bool patcher_builtin_multianewarray(patchref_t *pr)
Definition: patcher.cpp:324
uintptr_t ptrint
Definition: types.hpp:54
static void md_icacheflush(void *addr, int nbytes)
Definition: md.hpp:155
uintptr_t mpc
bool patcher_is_valid_trap_instruction_at(void *pc)
Check if the trap instruction at the given PC is valid.
Definition: patcher.cpp:72
bool patcher_getfield(patchref_t *pr)
Definition: patcher.cpp:131
bool patcher_checkcast_class(patchref_t *pr)
Definition: patcher.cpp:656
bool patcher_instanceof_interface(patchref_t *pr)
Definition: patcher.cpp:572