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