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