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