* Updated header: Added 2006. Changed address of FSF. Changed email
[cacao.git] / src / vm / jit / x86_64 / patcher.c
1 /* src/vm/jit/x86_64/patcher.c - x86_64 code patching functions
2
3    Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    Contact: cacao@cacaojvm.org
26
27    Authors: Christian Thalinger
28
29    Changes:
30
31    $Id: patcher.c 4357 2006-01-22 23:33:38Z twisti $
32
33 */
34
35
36 #include "config.h"
37 #include "vm/types.h"
38
39 #include "mm/memory.h"
40 #include "native/native.h"
41 #include "vm/builtin.h"
42 #include "vm/class.h"
43 #include "vm/field.h"
44 #include "vm/initialize.h"
45 #include "vm/options.h"
46 #include "vm/references.h"
47 #include "vm/resolve.h"
48 #include "vm/jit/patcher.h"
49
50
51 /* patcher_get_putstatic *******************************************************
52
53    Machine code:
54
55    <patched call position>
56    4d 8b 15 86 fe ff ff             mov    -378(%rip),%r10
57    49 8b 32                         mov    (%r10),%rsi
58
59 *******************************************************************************/
60
61 bool patcher_get_putstatic(u1 *sp)
62 {
63         u1                *ra;
64         java_objectheader *o;
65         u8                 mcode;
66         unresolved_field  *uf;
67         s4                 disp;
68         fieldinfo         *fi;
69         s4                 offset;
70
71         /* get stuff from the stack */
72
73         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
74         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
75         mcode =                       *((u8 *)     (sp + 2 * 8));
76         uf    = (unresolved_field *)  *((ptrint *) (sp + 1 * 8));
77         disp  =                       *((s4 *)     (sp + 0 * 8));
78
79         /* calculate and set the new return address */
80
81         ra = ra - 5;
82         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
83
84         PATCHER_MONITORENTER;
85
86         /* get the fieldinfo */
87
88         if (!(fi = resolve_field_eager(uf))) {
89                 PATCHER_MONITOREXIT;
90
91                 return false;
92         }
93
94         /* check if the field's class is initialized */
95
96         if (!(fi->class->state & CLASS_INITIALIZED)) {
97                 if (!initialize_class(fi->class)) {
98                         PATCHER_MONITOREXIT;
99
100                         return false;
101                 }
102         }
103
104         /* patch back original code */
105
106         *((u8 *) ra) = mcode;
107
108         /* if we show disassembly, we have to skip the nop's */
109
110         if (opt_showdisassemble)
111                 ra = ra + 5;
112
113         /* get RIP offset from machine instruction */
114
115         offset = *((u4 *) (ra + 3));
116
117         /* patch the field value's address (+ 7: is the size of the RIP move) */
118
119         *((ptrint *) (ra + 7 + offset)) = (ptrint) &(fi->value);
120
121         PATCHER_MARK_PATCHED_MONITOREXIT;
122
123         return true;
124 }
125
126
127 /* patcher_get_putfield ********************************************************
128
129    Machine code:
130
131    <patched call position>
132    45 8b 8f 00 00 00 00             mov    0x0(%r15),%r9d
133
134 *******************************************************************************/
135
136 bool patcher_get_putfield(u1 *sp)
137 {
138         u1                *ra;
139         java_objectheader *o;
140         u8                 mcode;
141         unresolved_field  *uf;
142         fieldinfo         *fi;
143         u1                 byte;
144
145         /* get stuff from the stack */
146
147         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
148         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
149         mcode =                       *((u8 *)     (sp + 2 * 8));
150         uf    = (unresolved_field *)  *((ptrint *) (sp + 1 * 8));
151
152         /* calculate and set the new return address */
153
154         ra = ra - 5;
155         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
156
157         PATCHER_MONITORENTER;
158
159         /* get the fieldinfo */
160
161         if (!(fi = resolve_field_eager(uf))) {
162                 PATCHER_MONITOREXIT;
163
164                 return false;
165         }
166
167         /* patch back original code (instruction code is smaller than 8 bytes) */
168
169         *((u4 *) (ra + 0)) = (u4) mcode;
170         *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
171
172         /* if we show disassembly, we have to skip the nop's */
173
174         if (opt_showdisassemble)
175                 ra = ra + 5;
176
177         /* patch the field's offset: we check for the field type, because the     */
178         /* instructions have different lengths                                    */
179
180         if (IS_INT_LNG_TYPE(fi->type)) {
181                 /* check for special case: %rsp or %r12 as base register */
182
183                 byte = *(ra + 3);
184
185                 if (byte == 0x24)
186                         *((u4 *) (ra + 4)) = (u4) (fi->offset);
187                 else
188                         *((u4 *) (ra + 3)) = (u4) (fi->offset);
189
190         } else {
191                 /* check for special case: %rsp or %r12 as base register */
192
193                 byte = *(ra + 5);
194
195                 if (byte == 0x24)
196                         *((u4 *) (ra + 6)) = (u4) (fi->offset);
197                 else
198                         *((u4 *) (ra + 5)) = (u4) (fi->offset);
199         }
200
201         PATCHER_MARK_PATCHED_MONITOREXIT;
202
203         return true;
204 }
205
206
207 /* patcher_putfieldconst *******************************************************
208
209    Machine code:
210
211    <patched call position>
212    41 c7 85 00 00 00 00 7b 00 00 00    movl   $0x7b,0x0(%r13)
213
214 *******************************************************************************/
215
216 bool patcher_putfieldconst(u1 *sp)
217 {
218         u1                *ra;
219         java_objectheader *o;
220         u8                 mcode;
221         unresolved_field  *uf;
222         fieldinfo         *fi;
223
224         /* get stuff from the stack */
225
226         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
227         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
228         mcode =                       *((u8 *)     (sp + 2 * 8));
229         uf    = (unresolved_field *)  *((ptrint *) (sp + 1 * 8));
230
231         /* calculate and set the new return address */
232
233         ra = ra - 5;
234         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
235
236         PATCHER_MONITORENTER;
237
238         /* get the fieldinfo */
239
240         if (!(fi = resolve_field_eager(uf))) {
241                 PATCHER_MONITOREXIT;
242
243                 return false;
244         }
245
246         /* patch back original code */
247
248         *((u8 *) ra) = mcode;
249
250         /* if we show disassembly, we have to skip the nop's */
251
252         if (opt_showdisassemble)
253                 ra = ra + 5;
254
255         /* patch the field's offset */
256
257         if (IS_2_WORD_TYPE(fi->type) || IS_ADR_TYPE(fi->type)) {
258                 /* handle special case when the base register is %r12 */
259
260                 if (*(ra + 2) == 0x84) {
261                         *((u4 *) (ra + 4)) = (u4) (fi->offset);
262                         *((u4 *) (ra + 12 + 4)) = (u4) (fi->offset + 4);
263
264                 } else {
265                         *((u4 *) (ra + 3)) = (u4) (fi->offset);
266                         *((u4 *) (ra + 11 + 3)) = (u4) (fi->offset + 4);
267                 }
268
269         } else {
270                 /* handle special case when the base register is %r12 */
271
272                 if (*(ra + 2) == 0x84)
273                         *((u4 *) (ra + 4)) = (u4) (fi->offset);
274                 else
275                         *((u4 *) (ra + 3)) = (u4) (fi->offset);
276         }
277
278         PATCHER_MARK_PATCHED_MONITOREXIT;
279
280         return true;
281 }
282
283
284 /* patcher_aconst **************************************************************
285
286    Machine code:
287
288    <patched call position>
289    48 bf a0 f0 92 00 00 00 00 00    mov    $0x92f0a0,%rdi
290
291 *******************************************************************************/
292
293 bool patcher_aconst(u1 *sp)
294 {
295         u1                *ra;
296         java_objectheader *o;
297         u8                 mcode;
298         constant_classref *cr;
299         classinfo         *c;
300
301         /* get stuff from the stack */
302
303         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
304         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
305         mcode =                       *((u8 *)     (sp + 2 * 8));
306         cr    = (constant_classref *) *((ptrint *) (sp + 1 * 8));
307
308         /* calculate and set the new return address */
309
310         ra = ra - 5;
311         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
312
313         PATCHER_MONITORENTER;
314
315         /* get the classinfo */
316
317         if (!(c = resolve_classref_eager(cr))) {
318                 PATCHER_MONITOREXIT;
319
320                 return false;
321         }
322
323         /* patch back original code */
324
325         *((u8 *) ra) = mcode;
326
327         /* if we show disassembly, we have to skip the nop's */
328
329         if (opt_showdisassemble)
330                 ra = ra + 5;
331
332         /* patch the classinfo pointer */
333
334         *((ptrint *) (ra + 2)) = (ptrint) c;
335
336         PATCHER_MARK_PATCHED_MONITOREXIT;
337
338         return true;
339 }
340
341
342 /* patcher_builtin_multianewarray **********************************************
343
344    Machine code:
345
346    <patched call position>
347    48 bf 02 00 00 00 00 00 00 00    mov    $0x2,%rdi
348    48 be 30 40 b2 00 00 00 00 00    mov    $0xb24030,%rsi
349    48 89 e2                         mov    %rsp,%rdx
350    48 b8 7c 96 4b 00 00 00 00 00    mov    $0x4b967c,%rax
351    48 ff d0                         callq  *%rax
352
353 *******************************************************************************/
354
355 bool patcher_builtin_multianewarray(u1 *sp)
356 {
357         u1                *ra;
358         java_objectheader *o;
359         u8                 mcode;
360         constant_classref *cr;
361         classinfo         *c;
362
363         /* get stuff from the stack */
364
365         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
366         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
367         mcode =                       *((u8 *)     (sp + 2 * 8));
368         cr    = (constant_classref *) *((ptrint *) (sp + 1 * 8));
369
370         /* calculate and set the new return address */
371
372         ra = ra - 5;
373         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
374
375         PATCHER_MONITORENTER;
376
377         /* get the classinfo */
378
379         if (!(c = resolve_classref_eager(cr))) {
380                 PATCHER_MONITOREXIT;
381
382                 return false;
383         }
384
385         /* patch back original code */
386
387         *((u8 *) ra) = mcode;
388
389         /* if we show disassembly, we have to skip the nop's */
390
391         if (opt_showdisassemble)
392                 ra = ra + 5;
393
394         /* patch the classinfo pointer */
395
396         *((ptrint *) (ra + 10 + 2)) = (ptrint) c;
397
398         /* patch new function address */
399
400         *((ptrint *) (ra + 10 + 10 + 3 + 2)) = (ptrint) BUILTIN_multianewarray;
401
402         PATCHER_MARK_PATCHED_MONITOREXIT;
403
404         return true;
405 }
406
407
408 /* patcher_builtin_arraycheckcast **********************************************
409
410    Machine code:
411
412    <patched call position>
413    48 be b8 3f b2 00 00 00 00 00    mov    $0xb23fb8,%rsi
414    48 b8 00 00 00 00 00 00 00 00    mov    $0x0,%rax
415    48 ff d0                         callq  *%rax
416
417 *******************************************************************************/
418
419 bool patcher_builtin_arraycheckcast(u1 *sp)
420 {
421         u1                *ra;
422         java_objectheader *o;
423         u8                 mcode;
424         constant_classref *cr;
425         classinfo         *c;
426
427         /* get stuff from the stack */
428
429         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
430         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
431         mcode =                       *((u8 *)     (sp + 2 * 8));
432         cr    = (constant_classref *) *((ptrint *) (sp + 1 * 8));
433
434         /* calculate and set the new return address */
435
436         ra = ra - 5;
437         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
438
439         PATCHER_MONITORENTER;
440
441         /* get the classinfo */
442
443         if (!(c = resolve_classref_eager(cr))) {
444                 PATCHER_MONITOREXIT;
445
446                 return false;
447         }
448
449         /* patch back original code */
450
451         *((u8 *) ra) = mcode;
452
453         /* if we show disassembly, we have to skip the nop's */
454
455         if (opt_showdisassemble)
456                 ra = ra + 5;
457
458         /* patch the classinfo pointer */
459
460         *((ptrint *) (ra + 2)) = (ptrint) c;
461
462         PATCHER_MARK_PATCHED_MONITOREXIT;
463
464         return true;
465 }
466
467
468 /* patcher_invokestatic_special ************************************************
469
470    Machine code:
471
472    <patched call position>
473    49 ba 00 00 00 00 00 00 00 00    mov    $0x0,%r10
474    49 ff d2                         callq  *%r10
475
476 *******************************************************************************/
477
478 bool patcher_invokestatic_special(u1 *sp)
479 {
480         u1                *ra;
481         java_objectheader *o;
482         u8                 mcode;
483         unresolved_method *um;
484         methodinfo        *m;
485
486         /* get stuff from the stack */
487
488         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
489         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
490         mcode =                       *((u8 *)     (sp + 2 * 8));
491         um    = (unresolved_method *) *((ptrint *) (sp + 1 * 8));
492
493         /* calculate and set the new return address */
494
495         ra = ra - 5;
496         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
497
498         PATCHER_MONITORENTER;
499
500         /* get the fieldinfo */
501
502         if (!(m = resolve_method_eager(um))) {
503                 PATCHER_MONITOREXIT;
504
505                 return false;
506         }
507         /* patch back original code */
508
509         *((u8 *) ra) = mcode;
510
511         /* if we show disassembly, we have to skip the nop's */
512
513         if (opt_showdisassemble)
514                 ra = ra + 5;
515
516         /* patch stubroutine */
517
518         *((ptrint *) (ra + 2)) = (ptrint) m->stubroutine;
519
520         PATCHER_MARK_PATCHED_MONITOREXIT;
521
522         return true;
523 }
524
525
526 /* patcher_invokevirtual *******************************************************
527
528    Machine code:
529
530    <patched call position>
531    4c 8b 17                         mov    (%rdi),%r10
532    49 8b 82 00 00 00 00             mov    0x0(%r10),%rax
533    48 ff d0                         callq  *%rax
534
535 *******************************************************************************/
536
537 bool patcher_invokevirtual(u1 *sp)
538 {
539         u1                *ra;
540         java_objectheader *o;
541         u8                 mcode;
542         unresolved_method *um;
543         methodinfo        *m;
544
545         /* get stuff from the stack */
546
547         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
548         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
549         mcode =                       *((u8 *)     (sp + 2 * 8));
550         um    = (unresolved_method *) *((ptrint *) (sp + 1 * 8));
551
552         /* calculate and set the new return address */
553
554         ra = ra - 5;
555         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
556
557         PATCHER_MONITORENTER;
558
559         /* get the fieldinfo */
560
561         if (!(m = resolve_method_eager(um))) {
562                 PATCHER_MONITOREXIT;
563
564                 return false;
565         }
566
567         /* patch back original code */
568
569         *((u8 *) ra) = mcode;
570
571         /* if we show disassembly, we have to skip the nop's */
572
573         if (opt_showdisassemble)
574                 ra = ra + 5;
575
576         /* patch vftbl index */
577
578         *((s4 *) (ra + 3 + 3)) = (s4) (OFFSET(vftbl_t, table[0]) +
579                                                                    sizeof(methodptr) * m->vftblindex);
580
581         PATCHER_MARK_PATCHED_MONITOREXIT;
582
583         return true;
584 }
585
586
587 /* patcher_invokeinterface *****************************************************
588
589    Machine code:
590
591    <patched call position>
592    4c 8b 17                         mov    (%rdi),%r10
593    4d 8b 92 00 00 00 00             mov    0x0(%r10),%r10
594    49 8b 82 00 00 00 00             mov    0x0(%r10),%rax
595    48 ff d0                         callq  *%rax
596
597 *******************************************************************************/
598
599 bool patcher_invokeinterface(u1 *sp)
600 {
601         u1                *ra;
602         java_objectheader *o;
603         u8                 mcode;
604         unresolved_method *um;
605         methodinfo        *m;
606
607         /* get stuff from the stack */
608
609         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
610         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
611         mcode =                       *((u8 *)     (sp + 2 * 8));
612         um    = (unresolved_method *) *((ptrint *) (sp + 1 * 8));
613
614         /* calculate and set the new return address */
615
616         ra = ra - 5;
617         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
618
619         PATCHER_MONITORENTER;
620
621         /* get the fieldinfo */
622
623         if (!(m = resolve_method_eager(um))) {
624                 PATCHER_MONITOREXIT;
625
626                 return false;
627         }
628
629         /* patch back original code */
630
631         *((u8 *) ra) = mcode;
632
633         /* if we show disassembly, we have to skip the nop's */
634
635         if (opt_showdisassemble)
636                 ra = ra + 5;
637
638         /* patch interfacetable index */
639
640         *((s4 *) (ra + 3 + 3)) = (s4) (OFFSET(vftbl_t, interfacetable[0]) -
641                                                                    sizeof(methodptr) * m->class->index);
642
643         /* patch method offset */
644
645         *((s4 *) (ra + 3 + 7 + 3)) =
646                 (s4) (sizeof(methodptr) * (m - m->class->methods));
647
648         PATCHER_MARK_PATCHED_MONITOREXIT;
649
650         return true;
651 }
652
653
654 /* patcher_checkcast_instanceof_flags ******************************************
655
656    Machine code:
657
658    <patched call position>
659    41 ba 00 00 00 00                mov    $0x0,%r10d
660    41 81 e2 00 02 00 00             and    $0x200,%r10d
661    0f 84 35 00 00 00                je     0x00002aaaaab01479
662
663 *******************************************************************************/
664
665 bool patcher_checkcast_instanceof_flags(u1 *sp)
666 {
667         u1                *ra;
668         java_objectheader *o;
669         u8                 mcode;
670         constant_classref *cr;
671         classinfo         *c;
672
673         /* get stuff from the stack */
674
675         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
676         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
677         mcode =                       *((u8 *)     (sp + 2 * 8));
678         cr    = (constant_classref *) *((ptrint *) (sp + 1 * 8));
679
680         /* calculate and set the new return address */
681
682         ra = ra - 5;
683         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
684
685         PATCHER_MONITORENTER;
686
687         /* get the fieldinfo */
688
689         if (!(c = resolve_classref_eager(cr))) {
690                 PATCHER_MONITOREXIT;
691
692                 return false;
693         }
694
695         /* patch back original code */
696
697         *((u8 *) ra) = mcode;
698
699         /* if we show disassembly, we have to skip the nop's */
700
701         if (opt_showdisassemble)
702                 ra = ra + 5;
703
704         /* patch class flags */
705
706         *((s4 *) (ra + 2)) = (s4) c->flags;
707
708         PATCHER_MARK_PATCHED_MONITOREXIT;
709
710         return true;
711 }
712
713
714 /* patcher_checkcast_instanceof_interface **************************************
715
716    Machine code:
717
718    <patched call position>
719    45 8b 9a 1c 00 00 00             mov    0x1c(%r10),%r11d
720    49 81 eb 00 00 00 00             sub    $0x0,%r11
721    4d 85 db                         test   %r11,%r11
722    0f 8e 94 04 00 00                jle    0x00002aaaaab018f8
723    4d 8b 9a 00 00 00 00             mov    0x0(%r10),%r11
724
725 *******************************************************************************/
726
727 bool patcher_checkcast_instanceof_interface(u1 *sp)
728 {
729         u1                *ra;
730         java_objectheader *o;
731         u8                 mcode;
732         constant_classref *cr;
733         classinfo         *c;
734
735         /* get stuff from the stack */
736
737         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
738         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
739         mcode =                       *((u8 *)     (sp + 2 * 8));
740         cr    = (constant_classref *) *((ptrint *) (sp + 1 * 8));
741
742         /* calculate and set the new return address */
743
744         ra = ra - 5;
745         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
746
747         PATCHER_MONITORENTER;
748
749         /* get the fieldinfo */
750
751         if (!(c = resolve_classref_eager(cr))) {
752                 PATCHER_MONITOREXIT;
753
754                 return false;
755         }
756
757         /* patch back original code */
758
759         *((u8 *) ra) = mcode;
760
761         /* if we show disassembly, we have to skip the nop's */
762
763         if (opt_showdisassemble)
764                 ra = ra + 5;
765
766         /* patch super class index */
767
768         *((s4 *) (ra + 7 + 3)) = (s4) c->index;
769
770         *((s4 *) (ra + 7 + 7 + 3 + 6 + 3)) =
771                 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
772                           c->index * sizeof(methodptr*));
773
774         PATCHER_MARK_PATCHED_MONITOREXIT;
775
776         return true;
777 }
778
779
780 /* patcher_checkcast_class *****************************************************
781
782    Machine code:
783
784    <patched call position>
785    49 bb 00 00 00 00 00 00 00 00    mov    $0x0,%r11
786    45 8b 92 20 00 00 00             mov    0x20(%r10),%r10d
787    45 8b 9b 20 00 00 00             mov    0x20(%r11),%r11d
788    4d 29 da                         sub    %r11,%r10
789    49 bb 00 00 00 00 00 00 00 00    mov    $0x0,%r11
790
791 *******************************************************************************/
792
793 bool patcher_checkcast_class(u1 *sp)
794 {
795         u1                *ra;
796         java_objectheader *o;
797         u8                 mcode;
798         constant_classref *cr;
799         classinfo         *c;
800
801         /* get stuff from the stack */
802
803         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
804         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
805         mcode =                       *((u8 *)     (sp + 2 * 8));
806         cr    = (constant_classref *) *((ptrint *) (sp + 1 * 8));
807
808         /* calculate and set the new return address */
809
810         ra = ra - 5;
811         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
812
813         PATCHER_MONITORENTER;
814
815         /* get the fieldinfo */
816
817         if (!(c = resolve_classref_eager(cr))) {
818                 PATCHER_MONITOREXIT;
819
820                 return false;
821         }
822
823         /* patch back original code */
824
825         *((u8 *) ra) = mcode;
826
827         /* if we show disassembly, we have to skip the nop's */
828
829         if (opt_showdisassemble)
830                 ra = ra + 5;
831
832         /* patch super class' vftbl */
833
834         *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
835         *((ptrint *) (ra + 10 + 7 + 7 + 3 + 2)) = (ptrint) c->vftbl;
836
837         PATCHER_MARK_PATCHED_MONITOREXIT;
838
839         return true;
840 }
841
842
843 /* patcher_instanceof_class ****************************************************
844
845    Machine code:
846
847    <patched call position>
848    49 ba 00 00 00 00 00 00 00 00    mov    $0x0,%r10
849
850 *******************************************************************************/
851
852 bool patcher_instanceof_class(u1 *sp)
853 {
854         u1                *ra;
855         java_objectheader *o;
856         u8                 mcode;
857         constant_classref *cr;
858         classinfo         *c;
859
860         /* get stuff from the stack */
861
862         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
863         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
864         mcode =                       *((u8 *)     (sp + 2 * 8));
865         cr    = (constant_classref *) *((ptrint *) (sp + 1 * 8));
866
867         /* calculate and set the new return address */
868
869         ra = ra - 5;
870         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
871
872         PATCHER_MONITORENTER;
873
874         /* get the fieldinfo */
875
876         if (!(c = resolve_classref_eager(cr))) {
877                 PATCHER_MONITOREXIT;
878
879                 return false;
880         }
881
882         /* patch back original code */
883
884         *((u8 *) ra) = mcode;
885
886         /* if we show disassembly, we have to skip the nop's */
887
888         if (opt_showdisassemble)
889                 ra = ra + 5;
890
891         /* patch super class' vftbl */
892
893         *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
894
895         PATCHER_MARK_PATCHED_MONITOREXIT;
896
897         return true;
898 }
899
900
901 /* patcher_clinit **************************************************************
902
903    May be used for GET/PUTSTATIC and in native stub.
904
905    Machine code:
906
907    <patched call position>
908    4d 8b 15 92 ff ff ff             mov    -110(%rip),%r10
909    49 89 1a                         mov    %rbx,(%r10)
910
911 *******************************************************************************/
912
913 bool patcher_clinit(u1 *sp)
914 {
915         u1                *ra;
916         java_objectheader *o;
917         u8                 mcode;
918         classinfo         *c;
919
920         /* get stuff from the stack */
921
922         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
923         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
924         mcode =                       *((u8 *)     (sp + 2 * 8));
925         c     = (classinfo *)         *((ptrint *) (sp + 1 * 8));
926
927         /* calculate and set the new return address */
928
929         ra = ra - 5;
930         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
931
932         PATCHER_MONITORENTER;
933
934         /* check if the class is initialized */
935
936         if (!(c->state & CLASS_INITIALIZED)) {
937                 if (!initialize_class(c)) {
938                         PATCHER_MONITOREXIT;
939
940                         return false;
941                 }
942         }
943
944         /* patch back original code */
945
946         *((u8 *) ra) = mcode;
947
948         PATCHER_MARK_PATCHED_MONITOREXIT;
949
950         return true;
951 }
952
953
954 /* patcher_athrow_areturn ******************************************************
955
956    Machine code:
957
958    <patched call position>
959
960 *******************************************************************************/
961
962 #ifdef ENABLE_VERIFIER
963 bool patcher_athrow_areturn(u1 *sp)
964 {
965         u1                *ra;
966         java_objectheader *o;
967         u8                 mcode;
968         unresolved_class  *uc;
969         classinfo         *c;
970
971         /* get stuff from the stack */
972
973         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
974         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
975         mcode =                       *((u8 *)     (sp + 2 * 8));
976         uc    = (unresolved_class *)  *((ptrint *) (sp + 1 * 8));
977
978         /* calculate and set the new return address */
979
980         ra = ra - 5;
981         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
982
983         PATCHER_MONITORENTER;
984
985         /* resolve the class */
986
987         if (!resolve_class(uc, resolveEager, false, &c)) {
988                 PATCHER_MONITOREXIT;
989
990                 return false;
991         }
992
993         /* patch back original code */
994
995         *((u8 *) ra) = mcode;
996
997         PATCHER_MARK_PATCHED_MONITOREXIT;
998
999         return true;
1000 }
1001 #endif /* ENABLE_VERIFIER */
1002
1003
1004 /* patcher_resolve_native ******************************************************
1005
1006    Machine code:
1007
1008    <patched call position>
1009    48 b8 00 00 00 00 00 00 00 00    mov    $0x0,%rax
1010    48 ff d0                         callq  *%rax
1011
1012 *******************************************************************************/
1013
1014 #if !defined(ENABLE_STATICVM)
1015 bool patcher_resolve_native(u1 *sp)
1016 {
1017         u1                *ra;
1018         java_objectheader *o;
1019         u8                 mcode;
1020         methodinfo        *m;
1021         functionptr        f;
1022
1023         /* get stuff from the stack */
1024
1025         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
1026         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
1027         mcode =                       *((u8 *)     (sp + 2 * 8));
1028         m     = (methodinfo *)        *((ptrint *) (sp + 1 * 8));
1029
1030         /* calculate and set the new return address */
1031
1032         ra = ra - 5;
1033         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
1034
1035         PATCHER_MONITORENTER;
1036
1037         /* resolve native function */
1038
1039         if (!(f = native_resolve_function(m))) {
1040                 PATCHER_MONITOREXIT;
1041
1042                 return false;
1043         }
1044
1045         /* patch back original code */
1046
1047         *((u8 *) ra) = mcode;
1048
1049         /* if we show disassembly, we have to skip the nop's */
1050
1051         if (opt_showdisassemble)
1052                 ra = ra + 5;
1053
1054         /* patch native function pointer */
1055
1056         *((ptrint *) (ra + 2)) = (ptrint) f;
1057
1058         PATCHER_MARK_PATCHED_MONITOREXIT;
1059
1060         return true;
1061 }
1062 #endif /* !defined(ENABLE_STATICVM) */
1063
1064
1065 /*
1066  * These are local overrides for various environment variables in Emacs.
1067  * Please do not remove this and leave it at the end of the file, where
1068  * Emacs will automagically detect them.
1069  * ---------------------------------------------------------------------
1070  * Local variables:
1071  * mode: c
1072  * indent-tabs-mode: t
1073  * c-basic-offset: 4
1074  * tab-width: 4
1075  * End:
1076  * vim:noexpandtab:sw=4:ts=4:
1077  */