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