* Removed all Id tags.
[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, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25 */
26
27
28 #include "config.h"
29
30 #include <stdint.h>
31
32 #include "vm/types.h"
33
34 #include "vm/jit/i386/codegen.h"
35
36 #include "mm/memory.h"
37
38 #include "native/native.h"
39
40 #include "vm/builtin.h"
41 #include "vm/exceptions.h"
42 #include "vm/initialize.h"
43
44 #include "vm/jit/patcher.h"
45 #include "vm/jit/stacktrace.h"
46
47 #include "vmcore/class.h"
48 #include "vmcore/field.h"
49 #include "vmcore/options.h"
50 #include "vm/resolve.h"
51 #include "vmcore/references.h"
52
53
54 /* patcher_wrapper *************************************************************
55
56    Wrapper for all patchers.  It also creates the stackframe info
57    structure.
58
59    If the return value of the patcher function is false, it gets the
60    exception object, clears the exception pointer and returns the
61    exception.
62
63 *******************************************************************************/
64
65 java_object_t *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra)
66 {
67         stackframeinfo     sfi;
68         u1                *xpc;
69         java_object_t     *o;
70         functionptr        f;
71         bool               result;
72         java_handle_t     *e;
73
74         /* define the patcher function */
75
76         bool (*patcher_function)(u1 *);
77
78         /* get stuff from the stack */
79
80         xpc = (u1 *)                *((ptrint *) (sp + 6 * 4));
81         o   = (java_object_t *)     *((ptrint *) (sp + 4 * 4));
82         f   = (functionptr)         *((ptrint *) (sp + 0 * 4));
83
84         /* calculate and set the new return address */
85
86         xpc = xpc - PATCHER_CALL_SIZE;
87
88         *((ptrint *) (sp + 6 * 4)) = (ptrint) xpc;
89
90         /* cast the passed function to a patcher function */
91
92         patcher_function = (bool (*)(u1 *)) (ptrint) f;
93
94         /* enter a monitor on the patching position */
95
96         PATCHER_MONITORENTER;
97
98         /* create the stackframeinfo */
99
100         /* RA is passed as NULL, but the XPC is correct and can be used in
101            stacktrace_create_extern_stackframeinfo for
102            md_codegen_get_pv_from_pc. */
103
104         stacktrace_create_extern_stackframeinfo(&sfi, pv, sp + 7 * 4, xpc, xpc);
105
106         /* call the proper patcher function */
107
108         result = (patcher_function)(sp);
109
110         /* remove the stackframeinfo */
111
112         stacktrace_remove_stackframeinfo(&sfi);
113
114         /* check for return value and exit accordingly */
115
116         if (result == false) {
117                 e = exceptions_get_and_clear_exception();
118
119                 PATCHER_MONITOREXIT;
120
121                 return e;
122         }
123
124         PATCHER_MARK_PATCHED_MONITOREXIT;
125
126         return NULL;
127 }
128
129
130 /* patcher_get_putstatic *******************************************************
131
132    Machine code:
133
134    <patched call position>
135    b8 00 00 00 00             mov    $0x00000000,%eax
136
137 *******************************************************************************/
138
139 bool patcher_get_putstatic(u1 *sp)
140 {
141         u1               *ra;
142         u8                mcode;
143         unresolved_field *uf;
144         fieldinfo        *fi;
145
146         /* get stuff from the stack */
147
148         ra    = (u1 *)               *((ptrint *) (sp + 6 * 4));
149         mcode =                      *((u8 *)     (sp + 2 * 4));
150         uf    = (unresolved_field *) *((ptrint *) (sp + 1 * 4));
151
152         /* get the fieldinfo */
153
154         if (!(fi = resolve_field_eager(uf)))
155                 return false;
156
157         /* check if the field's class is initialized */
158
159         if (!(fi->class->state & CLASS_INITIALIZED))
160                 if (!initialize_class(fi->class))
161                         return false;
162
163         /* patch back original code */
164
165         *((u4 *) (ra + 0)) = (u4) mcode;
166         *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
167
168         /* if we show disassembly, we have to skip the nop's */
169
170         if (opt_shownops)
171                 ra = ra + 5;
172
173         /* patch the field value's address */
174
175         *((intptr_t *) (ra + 1)) = (intptr_t) fi->value;
176
177         return true;
178 }
179
180
181 /* patcher_getfield ************************************************************
182
183    Machine code:
184
185    <patched call position>
186    8b 88 00 00 00 00          mov    0x00000000(%eax),%ecx
187
188 *******************************************************************************/
189
190 bool patcher_getfield(u1 *sp)
191 {
192         u1               *ra;
193         u8                mcode;
194         unresolved_field *uf;
195         fieldinfo        *fi;
196
197         /* get stuff from the stack */
198
199         ra    = (u1 *)               *((ptrint *) (sp + 6 * 4));
200         mcode =                      *((u8 *)     (sp + 2 * 4));
201         uf    = (unresolved_field *) *((ptrint *) (sp + 1 * 4));
202
203         /* get the fieldinfo */
204
205         if (!(fi = resolve_field_eager(uf)))
206                 return false;
207
208         /* patch back original code */
209
210         *((u4 *) (ra + 0)) = (u4) mcode;
211         *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
212
213         /* if we show disassembly, we have to skip the nop's */
214
215         if (opt_shownops)
216                 ra = ra + 5;
217
218         /* patch the field's offset */
219
220         *((u4 *) (ra + 2)) = (u4) (fi->offset);
221
222         /* if the field has type long, we need to patch the second move too */
223
224         if (fi->type == TYPE_LNG)
225                 *((u4 *) (ra + 6 + 2)) = (u4) (fi->offset + 4);
226
227         return true;
228 }
229
230
231 /* patcher_putfield ************************************************************
232
233    Machine code:
234
235    <patched call position>
236    8b 88 00 00 00 00          mov    0x00000000(%eax),%ecx
237
238 *******************************************************************************/
239
240 bool patcher_putfield(u1 *sp)
241 {
242         u1               *ra;
243         u8                mcode;
244         unresolved_field *uf;
245         fieldinfo        *fi;
246
247         /* get stuff from the stack */
248
249         ra    = (u1 *)               *((ptrint *) (sp + 6 * 4));
250         mcode =                      *((u8 *)     (sp + 2 * 4));
251         uf    = (unresolved_field *) *((ptrint *) (sp + 1 * 4));
252
253         /* get the fieldinfo */
254
255         if (!(fi = resolve_field_eager(uf)))
256                 return false;
257
258         /* patch back original code */
259
260         *((u4 *) (ra + 0)) = (u4) mcode;
261         *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
262
263         /* if we show disassembly, we have to skip the nop's */
264
265         if (opt_shownops)
266                 ra = ra + 5;
267
268         /* patch the field's offset */
269
270         if (fi->type != TYPE_LNG) {
271                 *((u4 *) (ra + 2)) = (u4) (fi->offset);
272         }
273         else {
274                 /* The long code is special:
275                  *
276                  * 89 8d 00 00 00 00          mov    %ecx,0x00000000(%ebp)
277                  * 89 95 00 00 00 00          mov    %edx,0x00000000(%ebp)
278                  */
279
280                 *((u4 *) (ra + 2))     = (u4) (fi->offset);
281                 *((u4 *) (ra + 6 + 2)) = (u4) (fi->offset + 4);
282         }
283
284         return true;
285 }
286
287
288 /* patcher_putfieldconst *******************************************************
289
290    Machine code:
291
292    <patched call position>
293    c7 85 00 00 00 00 7b 00 00 00    movl   $0x7b,0x0(%ebp)
294
295 *******************************************************************************/
296
297 bool patcher_putfieldconst(u1 *sp)
298 {
299         u1               *ra;
300         u8                mcode;
301         unresolved_field *uf;
302         fieldinfo        *fi;
303
304         /* get stuff from the stack */
305
306         ra    = (u1 *)               *((ptrint *) (sp + 6 * 4));
307         mcode =                      *((u8 *)     (sp + 2 * 4));
308         uf    = (unresolved_field *) *((ptrint *) (sp + 1 * 4));
309
310         /* get the fieldinfo */
311
312         if (!(fi = resolve_field_eager(uf)))
313                 return false;
314
315         /* patch back original code */
316
317         *((u4 *) (ra + 0)) = (u4) mcode;
318         *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
319
320         /* if we show disassembly, we have to skip the nop's */
321
322         if (opt_shownops)
323                 ra = ra + 5;
324
325         /* patch the field's offset */
326
327         if (!IS_2_WORD_TYPE(fi->type)) {
328                 *((u4 *) (ra + 2)) = (u4) (fi->offset);
329         }
330         else {
331                 /* long/double code is different:
332                  *
333                  * c7 80 00 00 00 00 c8 01 00 00    movl   $0x1c8,0x0(%eax)
334                  * c7 80 04 00 00 00 00 00 00 00    movl   $0x0,0x4(%eax)
335                  */
336
337                 *((u4 *) (ra + 2))      = (u4) (fi->offset);
338                 *((u4 *) (ra + 10 + 2)) = (u4) (fi->offset + 4);
339         }
340
341         return true;
342 }
343
344
345 /* patcher_aconst **************************************************************
346
347    Machine code:
348
349    <patched call postition>
350    c7 04 24 00 00 00 00       movl   $0x0000000,(%esp)
351    b8 00 00 00 00             mov    $0x0000000,%eax
352
353 *******************************************************************************/
354
355 bool patcher_aconst(u1 *sp)
356 {
357         u1                *ra;
358         u8                 mcode;
359         constant_classref *cr;
360         classinfo         *c;
361
362         /* get stuff from the stack */
363
364         ra    = (u1 *)                *((ptrint *) (sp + 6 * 4));
365         mcode =                       *((u8 *)     (sp + 2 * 4));
366         cr    = (constant_classref *) *((ptrint *) (sp + 1 * 4));
367
368         /* get the classinfo */
369
370         if (!(c = resolve_classref_eager(cr)))
371                 return false;
372
373         /* patch back original code */
374
375         *((u4 *) (ra + 0)) = (u4) mcode;
376         *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
377
378         /* if we show disassembly, we have to skip the nop's */
379
380         if (opt_shownops)
381                 ra = ra + 5;
382
383         /* patch the classinfo pointer */
384
385         *((ptrint *) (ra + 1)) = (ptrint) c;
386
387         return true;
388 }
389
390
391 /* patcher_builtin_multianewarray **********************************************
392
393    Machine code:
394
395    <patched call position>
396    c7 04 24 02 00 00 00       movl   $0x2,(%esp)
397    c7 44 24 04 00 00 00 00    movl   $0x00000000,0x4(%esp)
398    89 e0                      mov    %esp,%eax
399    83 c0 0c                   add    $0xc,%eax
400    89 44 24 08                mov    %eax,0x8(%esp)
401    b8 00 00 00 00             mov    $0x00000000,%eax
402    ff d0                      call   *%eax
403
404 *******************************************************************************/
405
406 bool patcher_builtin_multianewarray(u1 *sp)
407 {
408         u1                *ra;
409         u8                 mcode;
410         constant_classref *cr;
411         classinfo         *c;
412
413         /* get stuff from the stack */
414
415         ra    = (u1 *)                *((ptrint *) (sp + 6 * 4));
416         mcode =                       *((u8 *)     (sp + 2 * 4));
417         cr    = (constant_classref *) *((ptrint *) (sp + 1 * 4));
418
419         /* get the classinfo */
420
421         if (!(c = resolve_classref_eager(cr)))
422                 return false;
423
424         /* patch back original code */
425
426         *((u4 *) (ra + 0)) = (u4) mcode;
427         *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
428
429         /* if we show disassembly, we have to skip the nop's */
430
431         if (opt_shownops)
432                 ra = ra + 5;
433
434         /* patch the classinfo pointer */
435
436         *((ptrint *) (ra + 7 + 4)) = (ptrint) c;
437
438         return true;
439 }
440
441
442 /* patcher_builtin_arraycheckcast **********************************************
443
444    Machine code:
445
446    <patched call position>
447    c7 44 24 04 00 00 00 00    movl   $0x00000000,0x4(%esp)
448    ba 00 00 00 00             mov    $0x00000000,%edx
449    ff d2                      call   *%edx
450
451 *******************************************************************************/
452
453 bool patcher_builtin_arraycheckcast(u1 *sp)
454 {
455         u1                *ra;
456         u8                 mcode;
457         constant_classref *cr;
458         classinfo         *c;
459
460         /* get stuff from the stack */
461
462         ra    = (u1 *)                *((ptrint *) (sp + 6 * 4));
463         mcode =                       *((u8 *)     (sp + 2 * 4));
464         cr    = (constant_classref *) *((ptrint *) (sp + 1 * 4));
465
466         /* get the classinfo */
467
468         if (!(c = resolve_classref_eager(cr)))
469                 return false;
470
471         /* patch back original code */
472
473         *((u4 *) (ra + 0)) = (u4) mcode;
474         *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
475
476         /* if we show disassembly, we have to skip the nop's */
477
478         if (opt_shownops)
479                 ra = ra + 5;
480
481         /* patch the classinfo pointer */
482
483         *((ptrint *) (ra + 4)) = (ptrint) c;
484
485         /* patch new function address */
486
487         *((ptrint *) (ra + 8 + 1)) = (ptrint) BUILTIN_arraycheckcast;
488
489         return true;
490 }
491
492
493 /* patcher_invokestatic_special ************************************************
494
495    Machine code:
496
497    <patched call position>
498    b9 00 00 00 00             mov    $0x00000000,%ecx
499    ff d1                      call   *%ecx
500
501 *******************************************************************************/
502
503 bool patcher_invokestatic_special(u1 *sp)
504 {
505         u1                *ra;
506         u8                 mcode;
507         unresolved_method *um;
508         methodinfo        *m;
509
510         /* get stuff from the stack */
511
512         ra    = (u1 *)                *((ptrint *) (sp + 6 * 4));
513         mcode =                       *((u8 *)     (sp + 2 * 4));
514         um    = (unresolved_method *) *((ptrint *) (sp + 1 * 4));
515
516         /* get the fieldinfo */
517
518         if (!(m = resolve_method_eager(um)))
519                 return false;
520
521         /* patch back original code */
522
523         *((u4 *) (ra + 0)) = (u4) mcode;
524         *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
525
526         /* if we show disassembly, we have to skip the nop's */
527
528         if (opt_shownops)
529                 ra = ra + 5;
530
531         /* patch stubroutine */
532
533         *((ptrint *) (ra + 1)) = (ptrint) m->stubroutine;
534
535         return true;
536 }
537
538
539 /* patcher_invokevirtual *******************************************************
540
541    Machine code:
542
543    <patched call position>
544    8b 08                      mov    (%eax),%ecx
545    8b 81 00 00 00 00          mov    0x00000000(%ecx),%eax
546    ff d0                      call   *%eax
547
548 *******************************************************************************/
549
550 bool patcher_invokevirtual(u1 *sp)
551 {
552         u1                *ra;
553         u8                 mcode;
554         unresolved_method *um;
555         methodinfo        *m;
556
557         /* get stuff from the stack */
558
559         ra    = (u1 *)                *((ptrint *) (sp + 6 * 4));
560         mcode =                       *((u8 *)     (sp + 2 * 4));
561         um    = (unresolved_method *) *((ptrint *) (sp + 1 * 4));
562
563         /* get the fieldinfo */
564
565         if (!(m = resolve_method_eager(um)))
566                 return false;
567
568         /* patch back original code */
569
570         *((u4 *) (ra + 0)) = (u4) mcode;
571         *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
572
573         /* if we show disassembly, we have to skip the nop's */
574
575         if (opt_shownops)
576                 ra = ra + 5;
577
578         /* patch vftbl index */
579
580         *((s4 *) (ra + 2 + 2)) = (s4) (OFFSET(vftbl_t, table[0]) +
581                                                                    sizeof(methodptr) * m->vftblindex);
582
583         return true;
584 }
585
586
587 /* patcher_invokeinterface *****************************************************
588
589    Machine code:
590
591    <patched call position>
592    8b 00                      mov    (%eax),%eax
593    8b 88 00 00 00 00          mov    0x00000000(%eax),%ecx
594    8b 81 00 00 00 00          mov    0x00000000(%ecx),%eax
595    ff d0                      call   *%eax
596
597 *******************************************************************************/
598
599 bool patcher_invokeinterface(u1 *sp)
600 {
601         u1                *ra;
602         u8                 mcode;
603         unresolved_method *um;
604         methodinfo        *m;
605
606         /* get stuff from the stack */
607
608         ra    = (u1 *)                *((ptrint *) (sp + 6 * 4));
609         mcode =                       *((u8 *)     (sp + 2 * 4));
610         um    = (unresolved_method *) *((ptrint *) (sp + 1 * 4));
611
612         /* get the fieldinfo */
613
614         if (!(m = resolve_method_eager(um)))
615                 return false;
616
617         /* patch back original code */
618
619         *((u4 *) (ra + 0)) = (u4) mcode;
620         *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
621
622         /* if we show disassembly, we have to skip the nop's */
623
624         if (opt_shownops)
625                 ra = ra + 5;
626
627         /* patch interfacetable index */
628
629         *((s4 *) (ra + 2 + 2)) = (s4) (OFFSET(vftbl_t, interfacetable[0]) -
630                                                                    sizeof(methodptr) * m->class->index);
631
632         /* patch method offset */
633
634         *((s4 *) (ra + 2 + 6 + 2)) =
635                 (s4) (sizeof(methodptr) * (m - m->class->methods));
636
637         return true;
638 }
639
640
641 /* patcher_checkcast_instanceof_flags ******************************************
642
643    Machine code:
644
645    <patched call position>
646    b9 00 00 00 00             mov    $0x00000000,%ecx
647
648 *******************************************************************************/
649
650 bool patcher_checkcast_instanceof_flags(u1 *sp)
651 {
652         u1                *ra;
653         u8                 mcode;
654         constant_classref *cr;
655         classinfo         *c;
656
657         /* get stuff from the stack */
658
659         ra    = (u1 *)                *((ptrint *) (sp + 6 * 4));
660         mcode =                       *((u8 *)     (sp + 2 * 4));
661         cr    = (constant_classref *) *((ptrint *) (sp + 1 * 4));
662
663         /* get the fieldinfo */
664
665         if (!(c = resolve_classref_eager(cr)))
666                 return false;
667
668         /* patch back original code */
669
670         *((u4 *) (ra + 0)) = (u4) mcode;
671         *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
672
673         /* if we show disassembly, we have to skip the nop's */
674
675         if (opt_shownops)
676                 ra = ra + 5;
677
678         /* patch class flags */
679
680         *((s4 *) (ra + 1)) = (s4) c->flags;
681
682         return true;
683 }
684
685
686 /* patcher_checkcast_interface *************************************************
687
688    Machine code:
689
690    <patched call position>
691    8b 91 00 00 00 00          mov    0x00000000(%ecx),%edx
692    81 ea 00 00 00 00          sub    $0x00000000,%edx
693    85 d2                      test   %edx,%edx
694    0f 8f 06 00 00 00          jg     0x00000000
695    8b 35 03 00 00 00          mov    0x3,%esi
696    8b 91 00 00 00 00          mov    0x00000000(%ecx),%edx
697
698 *******************************************************************************/
699
700 bool patcher_checkcast_interface(u1 *sp)
701 {
702         u1                *ra;
703         u8                 mcode;
704         constant_classref *cr;
705         classinfo         *c;
706
707         /* get stuff from the stack */
708
709         ra    = (u1 *)                *((ptrint *) (sp + 6 * 4));
710         mcode =                       *((u8 *)     (sp + 2 * 4));
711         cr    = (constant_classref *) *((ptrint *) (sp + 1 * 4));
712
713         /* get the fieldinfo */
714
715         if (!(c = resolve_classref_eager(cr)))
716                 return false;
717
718         /* patch back original code */
719
720         *((u4 *) (ra + 0)) = (u4) mcode;
721         *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
722
723         /* if we show disassembly, we have to skip the nop's */
724
725         if (opt_shownops)
726                 ra = ra + 5;
727
728         /* patch super class index */
729
730         *((s4 *) (ra + 6 + 2)) = (s4) c->index;
731
732         *((s4 *) (ra + 6 + 6 + 2 + 6 + 6 + 2)) =
733                 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
734                           c->index * sizeof(methodptr*));
735
736         return true;
737 }
738
739
740 /* patcher_instanceof_interface ************************************************
741
742    Machine code:
743
744    <patched call position>
745    8b 91 00 00 00 00          mov    0x00000000(%ecx),%edx
746    81 ea 00 00 00 00          sub    $0x00000000,%edx
747    85 d2                      test   %edx,%edx
748    0f 8e 13 00 00 00          jle    0x00000000
749    8b 91 00 00 00 00          mov    0x00000000(%ecx),%edx
750
751 *******************************************************************************/
752
753 bool patcher_instanceof_interface(u1 *sp)
754 {
755         u1                *ra;
756         u8                 mcode;
757         constant_classref *cr;
758         classinfo         *c;
759
760         /* get stuff from the stack */
761
762         ra    = (u1 *)                *((ptrint *) (sp + 6 * 4));
763         mcode =                       *((u8 *)     (sp + 2 * 4));
764         cr    = (constant_classref *) *((ptrint *) (sp + 1 * 4));
765
766         /* get the fieldinfo */
767
768         if (!(c = resolve_classref_eager(cr)))
769                 return false;
770
771         /* patch back original code */
772
773         *((u4 *) (ra + 0)) = (u4) mcode;
774         *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
775
776         /* if we show disassembly, we have to skip the nop's */
777
778         if (opt_shownops)
779                 ra = ra + 5;
780
781         /* patch super class index */
782
783         *((s4 *) (ra + 6 + 2)) = (s4) c->index;
784
785         *((s4 *) (ra + 6 + 6 + 2 + 6 + 2)) =
786                 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
787                           c->index * sizeof(methodptr*));
788
789         return true;
790 }
791
792
793 /* patcher_checkcast_class *****************************************************
794
795    Machine code:
796
797    <patched call position>
798    ba 00 00 00 00             mov    $0x00000000,%edx
799    8b 89 00 00 00 00          mov    0x00000000(%ecx),%ecx
800    8b 92 00 00 00 00          mov    0x00000000(%edx),%edx
801    29 d1                      sub    %edx,%ecx
802    ba 00 00 00 00             mov    $0x00000000,%edx
803
804 *******************************************************************************/
805
806 bool patcher_checkcast_class(u1 *sp)
807 {
808         u1                *ra;
809         u8                 mcode;
810         constant_classref *cr;
811         classinfo         *c;
812
813         /* get stuff from the stack */
814
815         ra    = (u1 *)                *((ptrint *) (sp + 6 * 4));
816         mcode =                       *((u8 *)     (sp + 2 * 4));
817         cr    = (constant_classref *) *((ptrint *) (sp + 1 * 4));
818
819         /* get the fieldinfo */
820
821         if (!(c = resolve_classref_eager(cr)))
822                 return false;
823
824         /* patch back original code */
825
826         *((u4 *) (ra + 0)) = (u4) mcode;
827         *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
828
829         /* if we show disassembly, we have to skip the nop's */
830
831         if (opt_shownops)
832                 ra = ra + 5;
833
834         /* patch super class' vftbl */
835
836         *((ptrint *) (ra + 1)) = (ptrint) c->vftbl;
837         *((ptrint *) (ra + 5 + 6 + 6 + 2 + 1)) = (ptrint) c->vftbl;
838
839         return true;
840 }
841
842
843 /* patcher_instanceof_class ****************************************************
844
845    Machine code:
846
847    <patched call position>
848    b9 00 00 00 00             mov    $0x0,%ecx
849    8b 40 14                   mov    0x14(%eax),%eax
850    8b 51 18                   mov    0x18(%ecx),%edx
851    8b 49 14                   mov    0x14(%ecx),%ecx
852
853 *******************************************************************************/
854
855 bool patcher_instanceof_class(u1 *sp)
856 {
857         u1                *ra;
858         u8                 mcode;
859         constant_classref *cr;
860         classinfo         *c;
861
862         /* get stuff from the stack */
863
864         ra    = (u1 *)                *((ptrint *) (sp + 6 * 4));
865         mcode =                       *((u8 *)     (sp + 2 * 4));
866         cr    = (constant_classref *) *((ptrint *) (sp + 1 * 4));
867
868         /* get the fieldinfo */
869
870         if (!(c = resolve_classref_eager(cr)))
871                 return false;
872
873         /* patch back original code */
874
875         *((u4 *) (ra + 0)) = (u4) mcode;
876         *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
877
878         /* if we show disassembly, we have to skip the nop's */
879
880         if (opt_shownops)
881                 ra = ra + 5;
882
883         /* patch super class' vftbl */
884
885         *((ptrint *) (ra + 1)) = (ptrint) c->vftbl;
886
887         return true;
888 }
889
890
891 /* patcher_clinit **************************************************************
892
893    Is used int PUT/GETSTATIC and native stub.
894
895    Machine code:
896
897    <patched call position>
898
899 *******************************************************************************/
900
901 bool patcher_clinit(u1 *sp)
902 {
903         u1        *ra;
904         u8         mcode;
905         classinfo *c;
906
907         /* get stuff from the stack */
908
909         ra    = (u1 *)        *((ptrint *) (sp + 6 * 4));
910         mcode =               *((u8 *)     (sp + 2 * 4));
911         c     = (classinfo *) *((ptrint *) (sp + 1 * 4));
912
913         /* check if the class is initialized */
914
915         if (!(c->state & CLASS_INITIALIZED))
916                 if (!initialize_class(c))
917                         return false;
918
919         /* patch back original code */
920
921         *((u4 *) (ra + 0)) = (u4) mcode;
922         *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
923
924         return true;
925 }
926
927
928 /* patcher_athrow_areturn ******************************************************
929
930    Machine code:
931
932    <patched call position>
933
934 *******************************************************************************/
935
936 #ifdef ENABLE_VERIFIER
937 bool patcher_athrow_areturn(u1 *sp)
938 {
939         u1               *ra;
940         u8                mcode;
941         unresolved_class *uc;
942
943         /* get stuff from the stack */
944
945         ra    = (u1 *)               *((ptrint *) (sp + 6 * 4));
946         mcode =                      *((u8 *)     (sp + 2 * 4));
947         uc    = (unresolved_class *) *((ptrint *) (sp + 1 * 4));
948
949         /* resolve the class and check subtype constraints */
950
951         if (!resolve_class_eager_no_access_check(uc))
952                 return false;
953
954         /* patch back original code */
955
956         *((u4 *) (ra + 0)) = (u4) mcode;
957         *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
958
959         return true;
960 }
961 #endif /* ENABLE_VERIFIER */
962
963
964 /* patcher_resolve_native ******************************************************
965
966    Is used in native stub.
967
968    Machine code:
969
970    <patched call position>
971    c7 44 24 04 28 90 01 40    movl   $0x40019028,0x4(%esp)
972
973 *******************************************************************************/
974
975 #if !defined(WITH_STATIC_CLASSPATH)
976 bool patcher_resolve_native(u1 *sp)
977 {
978         u1          *ra;
979         u8           mcode;
980         methodinfo  *m;
981         functionptr  f;
982
983         /* get stuff from the stack */
984
985         ra    = (u1 *)         *((ptrint *) (sp + 6 * 4));
986         mcode =                *((u8 *)     (sp + 2 * 4));
987         m     = (methodinfo *) *((ptrint *) (sp + 1 * 4));
988
989         /* resolve native function */
990
991         if (!(f = native_resolve_function(m)))
992                 return false;
993
994         /* patch back original code */
995
996         *((u4 *) (ra + 0)) = (u4) mcode;
997         *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
998
999         /* if we show disassembly, we have to skip the nop's */
1000
1001         if (opt_shownops)
1002                 ra = ra + 5;
1003
1004         /* patch native function pointer */
1005
1006         *((ptrint *) (ra + 4)) = (ptrint) f;
1007
1008         return true;
1009 }
1010 #endif /* !defined(WITH_STATIC_CLASSPATH) */
1011
1012
1013 /*
1014  * These are local overrides for various environment variables in Emacs.
1015  * Please do not remove this and leave it at the end of the file, where
1016  * Emacs will automagically detect them.
1017  * ---------------------------------------------------------------------
1018  * Local variables:
1019  * mode: c
1020  * indent-tabs-mode: t
1021  * c-basic-offset: 4
1022  * tab-width: 4
1023  * End:
1024  * vim:noexpandtab:sw=4:ts=4:
1025  */