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