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