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