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