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