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