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