* patcher_builtin_new, patcher_builtin_newarray,
[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 3619 2005-11-07 18:44:32Z 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         /* patch new function address */
467
468         *((ptrint *) (ra + 10 + 2)) = (ptrint) BUILTIN_arraycheckcast;
469
470         PATCHER_MARK_PATCHED_MONITOREXIT;
471
472         return true;
473 }
474
475
476 /* patcher_invokestatic_special ************************************************
477
478    Machine code:
479
480    <patched call position>
481    49 ba 00 00 00 00 00 00 00 00    mov    $0x0,%r10
482    49 ff d2                         callq  *%r10
483
484 *******************************************************************************/
485
486 bool patcher_invokestatic_special(u1 *sp)
487 {
488         u1                *ra;
489         java_objectheader *o;
490         u8                 mcode;
491         unresolved_method *um;
492         methodinfo        *m;
493
494         /* get stuff from the stack */
495
496         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
497         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
498         mcode =                       *((u8 *)     (sp + 2 * 8));
499         um    = (unresolved_method *) *((ptrint *) (sp + 1 * 8));
500
501         /* calculate and set the new return address */
502
503         ra = ra - 5;
504         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
505
506         PATCHER_MONITORENTER;
507
508         /* get the fieldinfo */
509
510         if (!(m = resolve_method_eager(um))) {
511                 PATCHER_MONITOREXIT;
512
513                 return false;
514         }
515         /* patch back original code */
516
517         *((u8 *) ra) = mcode;
518
519         /* if we show disassembly, we have to skip the nop's */
520
521         if (opt_showdisassemble)
522                 ra = ra + 5;
523
524         /* patch stubroutine */
525
526         *((ptrint *) (ra + 2)) = (ptrint) m->stubroutine;
527
528         PATCHER_MARK_PATCHED_MONITOREXIT;
529
530         return true;
531 }
532
533
534 /* patcher_invokevirtual *******************************************************
535
536    Machine code:
537
538    <patched call position>
539    4c 8b 17                         mov    (%rdi),%r10
540    49 8b 82 00 00 00 00             mov    0x0(%r10),%rax
541    48 ff d0                         callq  *%rax
542
543 *******************************************************************************/
544
545 bool patcher_invokevirtual(u1 *sp)
546 {
547         u1                *ra;
548         java_objectheader *o;
549         u8                 mcode;
550         unresolved_method *um;
551         methodinfo        *m;
552
553         /* get stuff from the stack */
554
555         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
556         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
557         mcode =                       *((u8 *)     (sp + 2 * 8));
558         um    = (unresolved_method *) *((ptrint *) (sp + 1 * 8));
559
560         /* calculate and set the new return address */
561
562         ra = ra - 5;
563         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
564
565         PATCHER_MONITORENTER;
566
567         /* get the fieldinfo */
568
569         if (!(m = resolve_method_eager(um))) {
570                 PATCHER_MONITOREXIT;
571
572                 return false;
573         }
574
575         /* patch back original code */
576
577         *((u8 *) ra) = mcode;
578
579         /* if we show disassembly, we have to skip the nop's */
580
581         if (opt_showdisassemble)
582                 ra = ra + 5;
583
584         /* patch vftbl index */
585
586         *((s4 *) (ra + 3 + 3)) = (s4) (OFFSET(vftbl_t, table[0]) +
587                                                                    sizeof(methodptr) * m->vftblindex);
588
589         PATCHER_MARK_PATCHED_MONITOREXIT;
590
591         return true;
592 }
593
594
595 /* patcher_invokeinterface *****************************************************
596
597    Machine code:
598
599    <patched call position>
600    4c 8b 17                         mov    (%rdi),%r10
601    4d 8b 92 00 00 00 00             mov    0x0(%r10),%r10
602    49 8b 82 00 00 00 00             mov    0x0(%r10),%rax
603    48 ff d0                         callq  *%rax
604
605 *******************************************************************************/
606
607 bool patcher_invokeinterface(u1 *sp)
608 {
609         u1                *ra;
610         java_objectheader *o;
611         u8                 mcode;
612         unresolved_method *um;
613         methodinfo        *m;
614
615         /* get stuff from the stack */
616
617         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
618         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
619         mcode =                       *((u8 *)     (sp + 2 * 8));
620         um    = (unresolved_method *) *((ptrint *) (sp + 1 * 8));
621
622         /* calculate and set the new return address */
623
624         ra = ra - 5;
625         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
626
627         PATCHER_MONITORENTER;
628
629         /* get the fieldinfo */
630
631         if (!(m = resolve_method_eager(um))) {
632                 PATCHER_MONITOREXIT;
633
634                 return false;
635         }
636
637         /* patch back original code */
638
639         *((u8 *) ra) = mcode;
640
641         /* if we show disassembly, we have to skip the nop's */
642
643         if (opt_showdisassemble)
644                 ra = ra + 5;
645
646         /* patch interfacetable index */
647
648         *((s4 *) (ra + 3 + 3)) = (s4) (OFFSET(vftbl_t, interfacetable[0]) -
649                                                                    sizeof(methodptr) * m->class->index);
650
651         /* patch method offset */
652
653         *((s4 *) (ra + 3 + 7 + 3)) =
654                 (s4) (sizeof(methodptr) * (m - m->class->methods));
655
656         PATCHER_MARK_PATCHED_MONITOREXIT;
657
658         return true;
659 }
660
661
662 /* patcher_checkcast_instanceof_flags ******************************************
663
664    Machine code:
665
666    <patched call position>
667    41 ba 00 00 00 00                mov    $0x0,%r10d
668    41 81 e2 00 02 00 00             and    $0x200,%r10d
669    0f 84 35 00 00 00                je     0x00002aaaaab01479
670
671 *******************************************************************************/
672
673 bool patcher_checkcast_instanceof_flags(u1 *sp)
674 {
675         u1                *ra;
676         java_objectheader *o;
677         u8                 mcode;
678         constant_classref *cr;
679         classinfo         *c;
680
681         /* get stuff from the stack */
682
683         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
684         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
685         mcode =                       *((u8 *)     (sp + 2 * 8));
686         cr    = (constant_classref *) *((ptrint *) (sp + 1 * 8));
687
688         /* calculate and set the new return address */
689
690         ra = ra - 5;
691         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
692
693         PATCHER_MONITORENTER;
694
695         /* get the fieldinfo */
696
697         if (!(c = resolve_classref_eager(cr))) {
698                 PATCHER_MONITOREXIT;
699
700                 return false;
701         }
702
703         /* patch back original code */
704
705         *((u8 *) ra) = mcode;
706
707         /* if we show disassembly, we have to skip the nop's */
708
709         if (opt_showdisassemble)
710                 ra = ra + 5;
711
712         /* patch class flags */
713
714         *((s4 *) (ra + 2)) = (s4) c->flags;
715
716         PATCHER_MARK_PATCHED_MONITOREXIT;
717
718         return true;
719 }
720
721
722 /* patcher_checkcast_instanceof_interface **************************************
723
724    Machine code:
725
726    <patched call position>
727    45 8b 9a 1c 00 00 00             mov    0x1c(%r10),%r11d
728    49 81 eb 00 00 00 00             sub    $0x0,%r11
729    4d 85 db                         test   %r11,%r11
730    0f 8e 94 04 00 00                jle    0x00002aaaaab018f8
731    4d 8b 9a 00 00 00 00             mov    0x0(%r10),%r11
732
733 *******************************************************************************/
734
735 bool patcher_checkcast_instanceof_interface(u1 *sp)
736 {
737         u1                *ra;
738         java_objectheader *o;
739         u8                 mcode;
740         constant_classref *cr;
741         classinfo         *c;
742
743         /* get stuff from the stack */
744
745         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
746         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
747         mcode =                       *((u8 *)     (sp + 2 * 8));
748         cr    = (constant_classref *) *((ptrint *) (sp + 1 * 8));
749
750         /* calculate and set the new return address */
751
752         ra = ra - 5;
753         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
754
755         PATCHER_MONITORENTER;
756
757         /* get the fieldinfo */
758
759         if (!(c = resolve_classref_eager(cr))) {
760                 PATCHER_MONITOREXIT;
761
762                 return false;
763         }
764
765         /* patch back original code */
766
767         *((u8 *) ra) = mcode;
768
769         /* if we show disassembly, we have to skip the nop's */
770
771         if (opt_showdisassemble)
772                 ra = ra + 5;
773
774         /* patch super class index */
775
776         *((s4 *) (ra + 7 + 3)) = (s4) c->index;
777
778         *((s4 *) (ra + 7 + 7 + 3 + 6 + 3)) =
779                 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
780                           c->index * sizeof(methodptr*));
781
782         PATCHER_MARK_PATCHED_MONITOREXIT;
783
784         return true;
785 }
786
787
788 /* patcher_checkcast_class *****************************************************
789
790    Machine code:
791
792    <patched call position>
793    49 bb 00 00 00 00 00 00 00 00    mov    $0x0,%r11
794    45 8b 92 20 00 00 00             mov    0x20(%r10),%r10d
795    45 8b 9b 20 00 00 00             mov    0x20(%r11),%r11d
796    4d 29 da                         sub    %r11,%r10
797    49 bb 00 00 00 00 00 00 00 00    mov    $0x0,%r11
798
799 *******************************************************************************/
800
801 bool patcher_checkcast_class(u1 *sp)
802 {
803         u1                *ra;
804         java_objectheader *o;
805         u8                 mcode;
806         constant_classref *cr;
807         classinfo         *c;
808
809         /* get stuff from the stack */
810
811         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
812         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
813         mcode =                       *((u8 *)     (sp + 2 * 8));
814         cr    = (constant_classref *) *((ptrint *) (sp + 1 * 8));
815
816         /* calculate and set the new return address */
817
818         ra = ra - 5;
819         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
820
821         PATCHER_MONITORENTER;
822
823         /* get the fieldinfo */
824
825         if (!(c = resolve_classref_eager(cr))) {
826                 PATCHER_MONITOREXIT;
827
828                 return false;
829         }
830
831         /* patch back original code */
832
833         *((u8 *) ra) = mcode;
834
835         /* if we show disassembly, we have to skip the nop's */
836
837         if (opt_showdisassemble)
838                 ra = ra + 5;
839
840         /* patch super class' vftbl */
841
842         *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
843         *((ptrint *) (ra + 10 + 7 + 7 + 3 + 2)) = (ptrint) c->vftbl;
844
845         PATCHER_MARK_PATCHED_MONITOREXIT;
846
847         return true;
848 }
849
850
851 /* patcher_instanceof_class ****************************************************
852
853    Machine code:
854
855    <patched call position>
856    49 ba 00 00 00 00 00 00 00 00    mov    $0x0,%r10
857
858 *******************************************************************************/
859
860 bool patcher_instanceof_class(u1 *sp)
861 {
862         u1                *ra;
863         java_objectheader *o;
864         u8                 mcode;
865         constant_classref *cr;
866         classinfo         *c;
867
868         /* get stuff from the stack */
869
870         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
871         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
872         mcode =                       *((u8 *)     (sp + 2 * 8));
873         cr    = (constant_classref *) *((ptrint *) (sp + 1 * 8));
874
875         /* calculate and set the new return address */
876
877         ra = ra - 5;
878         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
879
880         PATCHER_MONITORENTER;
881
882         /* get the fieldinfo */
883
884         if (!(c = resolve_classref_eager(cr))) {
885                 PATCHER_MONITOREXIT;
886
887                 return false;
888         }
889
890         /* patch back original code */
891
892         *((u8 *) ra) = mcode;
893
894         /* if we show disassembly, we have to skip the nop's */
895
896         if (opt_showdisassemble)
897                 ra = ra + 5;
898
899         /* patch super class' vftbl */
900
901         *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
902
903         PATCHER_MARK_PATCHED_MONITOREXIT;
904
905         return true;
906 }
907
908
909 /* patcher_clinit **************************************************************
910
911    May be used for GET/PUTSTATIC and in native stub.
912
913    Machine code:
914
915    <patched call position>
916    4d 8b 15 92 ff ff ff             mov    -110(%rip),%r10
917    49 89 1a                         mov    %rbx,(%r10)
918
919 *******************************************************************************/
920
921 bool patcher_clinit(u1 *sp)
922 {
923         u1                *ra;
924         java_objectheader *o;
925         u8                 mcode;
926         classinfo         *c;
927
928         /* get stuff from the stack */
929
930         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
931         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
932         mcode =                       *((u8 *)     (sp + 2 * 8));
933         c     = (classinfo *)         *((ptrint *) (sp + 1 * 8));
934
935         /* calculate and set the new return address */
936
937         ra = ra - 5;
938         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
939
940         PATCHER_MONITORENTER;
941
942         /* check if the class is initialized */
943
944         if (!initialize_class(c)) {
945                 PATCHER_MONITOREXIT;
946
947                 return false;
948         }
949
950         /* patch back original code */
951
952         *((u8 *) ra) = mcode;
953
954         PATCHER_MARK_PATCHED_MONITOREXIT;
955
956         return true;
957 }
958
959
960 /* patcher_athrow_areturn ******************************************************
961
962    Machine code:
963
964    <patched call position>
965
966 *******************************************************************************/
967
968 bool patcher_athrow_areturn(u1 *sp)
969 {
970         u1                *ra;
971         java_objectheader *o;
972         u8                 mcode;
973         unresolved_class  *uc;
974         classinfo         *c;
975
976         /* get stuff from the stack */
977
978         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
979         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
980         mcode =                       *((u8 *)     (sp + 2 * 8));
981         uc    = (unresolved_class *)  *((ptrint *) (sp + 1 * 8));
982
983         /* calculate and set the new return address */
984
985         ra = ra - 5;
986         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
987
988         PATCHER_MONITORENTER;
989
990         /* resolve the class */
991
992         if (!resolve_class(uc, resolveEager, false, &c)) {
993                 PATCHER_MONITOREXIT;
994
995                 return false;
996         }
997
998         /* patch back original code */
999
1000         *((u8 *) ra) = mcode;
1001
1002         PATCHER_MARK_PATCHED_MONITOREXIT;
1003
1004         return true;
1005 }
1006
1007
1008 /* patcher_resolve_native ******************************************************
1009
1010    Machine code:
1011
1012    <patched call position>
1013    48 b8 00 00 00 00 00 00 00 00    mov    $0x0,%rax
1014    48 ff d0                         callq  *%rax
1015
1016 *******************************************************************************/
1017
1018 #if !defined(ENABLE_STATICVM)
1019 bool patcher_resolve_native(u1 *sp)
1020 {
1021         u1                *ra;
1022         java_objectheader *o;
1023         u8                 mcode;
1024         methodinfo        *m;
1025         functionptr        f;
1026
1027         /* get stuff from the stack */
1028
1029         ra    = (u1 *)                *((ptrint *) (sp + 4 * 8));
1030         o     = (java_objectheader *) *((ptrint *) (sp + 3 * 8));
1031         mcode =                       *((u8 *)     (sp + 2 * 8));
1032         m     = (methodinfo *)        *((ptrint *) (sp + 1 * 8));
1033
1034         /* calculate and set the new return address */
1035
1036         ra = ra - 5;
1037         *((ptrint *) (sp + 4 * 8)) = (ptrint) ra;
1038
1039         PATCHER_MONITORENTER;
1040
1041         /* resolve native function */
1042
1043         if (!(f = native_resolve_function(m))) {
1044                 PATCHER_MONITOREXIT;
1045
1046                 return false;
1047         }
1048
1049         /* patch back original code */
1050
1051         *((u8 *) ra) = mcode;
1052
1053         /* if we show disassembly, we have to skip the nop's */
1054
1055         if (opt_showdisassemble)
1056                 ra = ra + 5;
1057
1058         /* patch native function pointer */
1059
1060         *((ptrint *) (ra + 2)) = (ptrint) f;
1061
1062         PATCHER_MARK_PATCHED_MONITOREXIT;
1063
1064         return true;
1065 }
1066 #endif /* !defined(ENABLE_STATICVM) */
1067
1068
1069 /*
1070  * These are local overrides for various environment variables in Emacs.
1071  * Please do not remove this and leave it at the end of the file, where
1072  * Emacs will automagically detect them.
1073  * ---------------------------------------------------------------------
1074  * Local variables:
1075  * mode: c
1076  * indent-tabs-mode: t
1077  * c-basic-offset: 4
1078  * tab-width: 4
1079  * End:
1080  * vim:noexpandtab:sw=4:ts=4:
1081  */