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