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