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