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