d7407c28a0467d7af8d0805bad6dd3247f7a2f3a
[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 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    Contact: cacao@cacaojvm.org
26
27    Authors: Christian Thalinger
28
29    Changes:
30
31    $Id: patcher.c 5109 2006-07-11 19:17:23Z 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/exceptions.h"
44 #include "vm/field.h"
45 #include "vm/initialize.h"
46 #include "vm/options.h"
47 #include "vm/resolve.h"
48 #include "vm/references.h"
49 #include "vm/jit/patcher.h"
50 #include "vm/jit/i386/codegen.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_findmethod. */
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_showdisassemble)
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_showdisassemble)
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_showdisassemble)
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_showdisassemble)
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_showdisassemble)
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_showdisassemble)
431                 ra = ra + 5;
432
433         /* patch the classinfo pointer */
434
435         *((ptrint *) (ra + 7 + 4)) = (ptrint) c;
436
437         /* patch new function address */
438
439         *((ptrint *) (ra + 7 + 8 + 2 + 3 + 4 + 1)) =
440                 (ptrint) BUILTIN_multianewarray;
441
442         return true;
443 }
444
445
446 /* patcher_builtin_arraycheckcast **********************************************
447
448    Machine code:
449
450    <patched call position>
451    c7 44 24 04 00 00 00 00    movl   $0x00000000,0x4(%esp)
452    ba 00 00 00 00             mov    $0x00000000,%edx
453    ff d2                      call   *%edx
454
455 *******************************************************************************/
456
457 bool patcher_builtin_arraycheckcast(u1 *sp)
458 {
459         u1                *ra;
460         u8                 mcode;
461         constant_classref *cr;
462         classinfo         *c;
463
464         /* get stuff from the stack */
465
466         ra    = (u1 *)                *((ptrint *) (sp + 6 * 4));
467         mcode =                       *((u8 *)     (sp + 2 * 4));
468         cr    = (constant_classref *) *((ptrint *) (sp + 1 * 4));
469
470         /* get the classinfo */
471
472         if (!(c = resolve_classref_eager(cr)))
473                 return false;
474
475         /* patch back original code */
476
477         *((u4 *) (ra + 0)) = (u4) mcode;
478         *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
479
480         /* if we show disassembly, we have to skip the nop's */
481
482         if (opt_showdisassemble)
483                 ra = ra + 5;
484
485         /* patch the classinfo pointer */
486
487         *((ptrint *) (ra + 4)) = (ptrint) c;
488
489         /* patch new function address */
490
491         *((ptrint *) (ra + 8 + 1)) = (ptrint) BUILTIN_arraycheckcast;
492
493         return true;
494 }
495
496
497 /* patcher_invokestatic_special ************************************************
498
499    Machine code:
500
501    <patched call position>
502    b9 00 00 00 00             mov    $0x00000000,%ecx
503    ff d1                      call   *%ecx
504
505 *******************************************************************************/
506
507 bool patcher_invokestatic_special(u1 *sp)
508 {
509         u1                *ra;
510         u8                 mcode;
511         unresolved_method *um;
512         methodinfo        *m;
513
514         /* get stuff from the stack */
515
516         ra    = (u1 *)                *((ptrint *) (sp + 6 * 4));
517         mcode =                       *((u8 *)     (sp + 2 * 4));
518         um    = (unresolved_method *) *((ptrint *) (sp + 1 * 4));
519
520         /* get the fieldinfo */
521
522         if (!(m = resolve_method_eager(um)))
523                 return false;
524
525         /* patch back original code */
526
527         *((u4 *) (ra + 0)) = (u4) mcode;
528         *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
529
530         /* if we show disassembly, we have to skip the nop's */
531
532         if (opt_showdisassemble)
533                 ra = ra + 5;
534
535         /* patch stubroutine */
536
537         *((ptrint *) (ra + 1)) = (ptrint) m->stubroutine;
538
539         return true;
540 }
541
542
543 /* patcher_invokevirtual *******************************************************
544
545    Machine code:
546
547    <patched call position>
548    8b 08                      mov    (%eax),%ecx
549    8b 81 00 00 00 00          mov    0x00000000(%ecx),%eax
550    ff d0                      call   *%eax
551
552 *******************************************************************************/
553
554 bool patcher_invokevirtual(u1 *sp)
555 {
556         u1                *ra;
557         u8                 mcode;
558         unresolved_method *um;
559         methodinfo        *m;
560
561         /* get stuff from the stack */
562
563         ra    = (u1 *)                *((ptrint *) (sp + 6 * 4));
564         mcode =                       *((u8 *)     (sp + 2 * 4));
565         um    = (unresolved_method *) *((ptrint *) (sp + 1 * 4));
566
567         /* get the fieldinfo */
568
569         if (!(m = resolve_method_eager(um)))
570                 return false;
571
572         /* patch back original code */
573
574         *((u4 *) (ra + 0)) = (u4) mcode;
575         *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
576
577         /* if we show disassembly, we have to skip the nop's */
578
579         if (opt_showdisassemble)
580                 ra = ra + 5;
581
582         /* patch vftbl index */
583
584         *((s4 *) (ra + 2 + 2)) = (s4) (OFFSET(vftbl_t, table[0]) +
585                                                                    sizeof(methodptr) * m->vftblindex);
586
587         return true;
588 }
589
590
591 /* patcher_invokeinterface *****************************************************
592
593    Machine code:
594
595    <patched call position>
596    8b 00                      mov    (%eax),%eax
597    8b 88 00 00 00 00          mov    0x00000000(%eax),%ecx
598    8b 81 00 00 00 00          mov    0x00000000(%ecx),%eax
599    ff d0                      call   *%eax
600
601 *******************************************************************************/
602
603 bool patcher_invokeinterface(u1 *sp)
604 {
605         u1                *ra;
606         u8                 mcode;
607         unresolved_method *um;
608         methodinfo        *m;
609
610         /* get stuff from the stack */
611
612         ra    = (u1 *)                *((ptrint *) (sp + 6 * 4));
613         mcode =                       *((u8 *)     (sp + 2 * 4));
614         um    = (unresolved_method *) *((ptrint *) (sp + 1 * 4));
615
616         /* get the fieldinfo */
617
618         if (!(m = resolve_method_eager(um)))
619                 return false;
620
621         /* patch back original code */
622
623         *((u4 *) (ra + 0)) = (u4) mcode;
624         *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
625
626         /* if we show disassembly, we have to skip the nop's */
627
628         if (opt_showdisassemble)
629                 ra = ra + 5;
630
631         /* patch interfacetable index */
632
633         *((s4 *) (ra + 2 + 2)) = (s4) (OFFSET(vftbl_t, interfacetable[0]) -
634                                                                    sizeof(methodptr) * m->class->index);
635
636         /* patch method offset */
637
638         *((s4 *) (ra + 2 + 6 + 2)) =
639                 (s4) (sizeof(methodptr) * (m - m->class->methods));
640
641         return true;
642 }
643
644
645 /* patcher_checkcast_instanceof_flags ******************************************
646
647    Machine code:
648
649    <patched call position>
650    b9 00 00 00 00             mov    $0x00000000,%ecx
651
652 *******************************************************************************/
653
654 bool patcher_checkcast_instanceof_flags(u1 *sp)
655 {
656         u1                *ra;
657         u8                 mcode;
658         constant_classref *cr;
659         classinfo         *c;
660
661         /* get stuff from the stack */
662
663         ra    = (u1 *)                *((ptrint *) (sp + 6 * 4));
664         mcode =                       *((u8 *)     (sp + 2 * 4));
665         cr    = (constant_classref *) *((ptrint *) (sp + 1 * 4));
666
667         /* get the fieldinfo */
668
669         if (!(c = resolve_classref_eager(cr)))
670                 return false;
671
672         /* patch back original code */
673
674         *((u4 *) (ra + 0)) = (u4) mcode;
675         *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
676
677         /* if we show disassembly, we have to skip the nop's */
678
679         if (opt_showdisassemble)
680                 ra = ra + 5;
681
682         /* patch class flags */
683
684         *((s4 *) (ra + 1)) = (s4) c->flags;
685
686         return true;
687 }
688
689
690 /* patcher_checkcast_instanceof_interface **************************************
691
692    Machine code:
693
694    <patched call position>
695    8b 91 00 00 00 00          mov    0x00000000(%ecx),%edx
696    81 ea 00 00 00 00          sub    $0x00000000,%edx
697    85 d2                      test   %edx,%edx
698    0f 8e 00 00 00 00          jle    0x00000000
699    8b 91 00 00 00 00          mov    0x00000000(%ecx),%edx
700
701 *******************************************************************************/
702
703 bool patcher_checkcast_instanceof_interface(u1 *sp)
704 {
705         u1                *ra;
706         u8                 mcode;
707         constant_classref *cr;
708         classinfo         *c;
709
710         /* get stuff from the stack */
711
712         ra    = (u1 *)                *((ptrint *) (sp + 6 * 4));
713         mcode =                       *((u8 *)     (sp + 2 * 4));
714         cr    = (constant_classref *) *((ptrint *) (sp + 1 * 4));
715
716         /* get the fieldinfo */
717
718         if (!(c = resolve_classref_eager(cr)))
719                 return false;
720
721         /* patch back original code */
722
723         *((u4 *) (ra + 0)) = (u4) mcode;
724         *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
725
726         /* if we show disassembly, we have to skip the nop's */
727
728         if (opt_showdisassemble)
729                 ra = ra + 5;
730
731         /* patch super class index */
732
733         *((s4 *) (ra + 6 + 2)) = (s4) c->index;
734
735         *((s4 *) (ra + 6 + 6 + 2 + 6 + 2)) =
736                 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
737                           c->index * sizeof(methodptr*));
738
739         return true;
740 }
741
742
743 /* patcher_checkcast_class *****************************************************
744
745    Machine code:
746
747    <patched call position>
748    ba 00 00 00 00             mov    $0x00000000,%edx
749    8b 89 00 00 00 00          mov    0x00000000(%ecx),%ecx
750    8b 92 00 00 00 00          mov    0x00000000(%edx),%edx
751    29 d1                      sub    %edx,%ecx
752    ba 00 00 00 00             mov    $0x00000000,%edx
753
754 *******************************************************************************/
755
756 bool patcher_checkcast_class(u1 *sp)
757 {
758         u1                *ra;
759         u8                 mcode;
760         constant_classref *cr;
761         classinfo         *c;
762
763         /* get stuff from the stack */
764
765         ra    = (u1 *)                *((ptrint *) (sp + 6 * 4));
766         mcode =                       *((u8 *)     (sp + 2 * 4));
767         cr    = (constant_classref *) *((ptrint *) (sp + 1 * 4));
768
769         /* get the fieldinfo */
770
771         if (!(c = resolve_classref_eager(cr)))
772                 return false;
773
774         /* patch back original code */
775
776         *((u4 *) (ra + 0)) = (u4) mcode;
777         *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
778
779         /* if we show disassembly, we have to skip the nop's */
780
781         if (opt_showdisassemble)
782                 ra = ra + 5;
783
784         /* patch super class' vftbl */
785
786         *((ptrint *) (ra + 1)) = (ptrint) c->vftbl;
787         *((ptrint *) (ra + 5 + 6 + 6 + 2 + 1)) = (ptrint) c->vftbl;
788
789         return true;
790 }
791
792
793 /* patcher_instanceof_class ****************************************************
794
795    Machine code:
796
797    <patched call position>
798    b9 00 00 00 00             mov    $0x0,%ecx
799    8b 40 14                   mov    0x14(%eax),%eax
800    8b 51 18                   mov    0x18(%ecx),%edx
801    8b 49 14                   mov    0x14(%ecx),%ecx
802
803 *******************************************************************************/
804
805 bool patcher_instanceof_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_showdisassemble)
831                 ra = ra + 5;
832
833         /* patch super class' vftbl */
834
835         *((ptrint *) (ra + 1)) = (ptrint) c->vftbl;
836
837         return true;
838 }
839
840
841 /* patcher_clinit **************************************************************
842
843    Is used int PUT/GETSTATIC and native stub.
844
845    Machine code:
846
847    <patched call position>
848
849 *******************************************************************************/
850
851 bool patcher_clinit(u1 *sp)
852 {
853         u1        *ra;
854         u8         mcode;
855         classinfo *c;
856
857         /* get stuff from the stack */
858
859         ra    = (u1 *)        *((ptrint *) (sp + 6 * 4));
860         mcode =               *((u8 *)     (sp + 2 * 4));
861         c     = (classinfo *) *((ptrint *) (sp + 1 * 4));
862
863         /* check if the class is initialized */
864
865         if (!(c->state & CLASS_INITIALIZED))
866                 if (!initialize_class(c))
867                         return false;
868
869         /* patch back original code */
870
871         *((u4 *) (ra + 0)) = (u4) mcode;
872         *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
873
874         return true;
875 }
876
877
878 /* patcher_athrow_areturn ******************************************************
879
880    Machine code:
881
882    <patched call position>
883
884 *******************************************************************************/
885
886 #ifdef ENABLE_VERIFIER
887 bool patcher_athrow_areturn(u1 *sp)
888 {
889         u1               *ra;
890         u8                mcode;
891         unresolved_class *uc;
892         classinfo        *c;
893
894         /* get stuff from the stack */
895
896         ra    = (u1 *)               *((ptrint *) (sp + 6 * 4));
897         mcode =                      *((u8 *)     (sp + 2 * 4));
898         uc    = (unresolved_class *) *((ptrint *) (sp + 1 * 4));
899
900         /* resolve the class */
901
902         if (!resolve_class(uc, resolveEager, false, &c))
903                 return false;
904
905         /* patch back original code */
906
907         *((u4 *) (ra + 0)) = (u4) mcode;
908         *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
909
910         return true;
911 }
912 #endif /* ENABLE_VERIFIER */
913
914
915 /* patcher_resolve_native ******************************************************
916
917    Is used in native stub.
918
919    Machine code:
920
921    <patched call position>
922    c7 44 24 04 28 90 01 40    movl   $0x40019028,0x4(%esp)
923
924 *******************************************************************************/
925
926 #if !defined(WITH_STATIC_CLASSPATH)
927 bool patcher_resolve_native(u1 *sp)
928 {
929         u1          *ra;
930         u8           mcode;
931         methodinfo  *m;
932         functionptr  f;
933
934         /* get stuff from the stack */
935
936         ra    = (u1 *)         *((ptrint *) (sp + 6 * 4));
937         mcode =                *((u8 *)     (sp + 2 * 4));
938         m     = (methodinfo *) *((ptrint *) (sp + 1 * 4));
939
940         /* resolve native function */
941
942         if (!(f = native_resolve_function(m)))
943                 return false;
944
945         /* patch back original code */
946
947         *((u4 *) (ra + 0)) = (u4) mcode;
948         *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
949
950         /* if we show disassembly, we have to skip the nop's */
951
952         if (opt_showdisassemble)
953                 ra = ra + 5;
954
955         /* patch native function pointer */
956
957         *((ptrint *) (ra + 4)) = (ptrint) f;
958
959         return true;
960 }
961 #endif /* !defined(WITH_STATIC_CLASSPATH) */
962
963
964 /*
965  * These are local overrides for various environment variables in Emacs.
966  * Please do not remove this and leave it at the end of the file, where
967  * Emacs will automagically detect them.
968  * ---------------------------------------------------------------------
969  * Local variables:
970  * mode: c
971  * indent-tabs-mode: t
972  * c-basic-offset: 4
973  * tab-width: 4
974  * End:
975  * vim:noexpandtab:sw=4:ts=4:
976  */