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