ce9df0711b5a579756c6115699e9797962ace2e0
[cacao.git] / src / vm / jit / x86_64 / patcher.c
1 /* src/vm/jit/x86_64/patcher.c - x86_64 code patching functions
2
3    Copyright (C) 1996-2005, 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 5142 2006-07-17 09:47:02Z twisti $
32
33 */
34
35
36 #include "config.h"
37 #include "vm/types.h"
38
39 #include "vm/jit/x86_64/codegen.h"
40
41 #include "mm/memory.h"
42 #include "native/native.h"
43 #include "vm/builtin.h"
44 #include "vm/class.h"
45 #include "vm/exceptions.h"
46 #include "vm/field.h"
47 #include "vm/initialize.h"
48 #include "vm/options.h"
49 #include "vm/references.h"
50 #include "vm/resolve.h"
51 #include "vm/jit/patcher.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_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra)
66 {
67         stackframeinfo     sfi;
68         u1                *xpc;
69         java_objectheader *o;
70         functionptr        f;
71         bool               result;
72         java_objectheader *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 + 5 * 8));
81         o   = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
82         f   = (functionptr)         *((ptrint *) (sp + 0 * 8));
83
84         /* calculate and set the new return address */
85
86         xpc = xpc - PATCHER_CALL_SIZE;
87
88         *((ptrint *) (sp + 5 * 8)) = (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_findmethod. */
103
104         stacktrace_create_extern_stackframeinfo(&sfi, pv, sp + 6 * 8, 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    4d 8b 15 86 fe ff ff             mov    -378(%rip),%r10
136    49 8b 32                         mov    (%r10),%rsi
137
138 *******************************************************************************/
139
140 bool patcher_get_putstatic(u1 *sp)
141 {
142         u1               *ra;
143         u8                mcode;
144         unresolved_field *uf;
145         s4                disp;
146         fieldinfo        *fi;
147         s4                offset;
148
149         /* get stuff from the stack */
150
151         ra    = (u1 *)               *((ptrint *) (sp + 5 * 8));
152         mcode =                      *((u8 *)     (sp + 3 * 8));
153         uf    = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
154         disp  =                      *((s4 *)     (sp + 1 * 8));
155
156         /* get the fieldinfo */
157
158         if (!(fi = resolve_field_eager(uf)))
159                 return false;
160
161         /* check if the field's class is initialized */
162
163         if (!(fi->class->state & CLASS_INITIALIZED))
164                 if (!initialize_class(fi->class))
165                         return false;
166
167         /* patch back original code */
168
169         *((u8 *) ra) = mcode;
170
171         /* if we show disassembly, we have to skip the nop's */
172
173         if (opt_showdisassemble)
174                 ra = ra + 5;
175
176         /* get RIP offset from machine instruction */
177
178         offset = *((u4 *) (ra + 3));
179
180         /* patch the field value's address (+ 7: is the size of the RIP move) */
181
182         *((ptrint *) (ra + 7 + offset)) = (ptrint) &(fi->value);
183
184         return true;
185 }
186
187
188 /* patcher_get_putfield ********************************************************
189
190    Machine code:
191
192    <patched call position>
193    45 8b 8f 00 00 00 00             mov    0x0(%r15),%r9d
194
195 *******************************************************************************/
196
197 bool patcher_get_putfield(u1 *sp)
198 {
199         u1               *ra;
200         u8                mcode;
201         unresolved_field *uf;
202         fieldinfo        *fi;
203         u1                byte;
204
205         /* get stuff from the stack */
206
207         ra    = (u1 *)               *((ptrint *) (sp + 5 * 8));
208         mcode =                      *((u8 *)     (sp + 3 * 8));
209         uf    = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
210
211         /* get the fieldinfo */
212
213         if (!(fi = resolve_field_eager(uf)))
214                 return false;
215
216         /* patch back original code (instruction code is smaller than 8 bytes) */
217
218         *((u4 *) (ra + 0)) = (u4) mcode;
219         *((u1 *) (ra + 4)) = (u1) (mcode >> 32);
220
221         /* if we show disassembly, we have to skip the nop's */
222
223         if (opt_showdisassemble)
224                 ra = ra + 5;
225
226         /* patch the field's offset: we check for the field type, because the     */
227         /* instructions have different lengths                                    */
228
229         if (IS_INT_LNG_TYPE(fi->type)) {
230                 /* check for special case: %rsp or %r12 as base register */
231
232                 byte = *(ra + 3);
233
234                 if (byte == 0x24)
235                         *((u4 *) (ra + 4)) = (u4) (fi->offset);
236                 else
237                         *((u4 *) (ra + 3)) = (u4) (fi->offset);
238         }
239         else {
240                 /* check for special case: %rsp or %r12 as base register */
241
242                 byte = *(ra + 5);
243
244                 if (byte == 0x24)
245                         *((u4 *) (ra + 6)) = (u4) (fi->offset);
246                 else
247                         *((u4 *) (ra + 5)) = (u4) (fi->offset);
248         }
249
250         return true;
251 }
252
253
254 /* patcher_putfieldconst *******************************************************
255
256    Machine code:
257
258    <patched call position>
259    41 c7 85 00 00 00 00 7b 00 00 00    movl   $0x7b,0x0(%r13)
260
261 *******************************************************************************/
262
263 bool patcher_putfieldconst(u1 *sp)
264 {
265         u1               *ra;
266         u8                mcode;
267         unresolved_field *uf;
268         fieldinfo        *fi;
269
270         /* get stuff from the stack */
271
272         ra    = (u1 *)               *((ptrint *) (sp + 5 * 8));
273         mcode =                      *((u8 *)     (sp + 3 * 8));
274         uf    = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
275
276         /* get the fieldinfo */
277
278         if (!(fi = resolve_field_eager(uf)))
279                 return false;
280
281         /* patch back original code */
282
283         *((u8 *) ra) = mcode;
284
285         /* if we show disassembly, we have to skip the nop's */
286
287         if (opt_showdisassemble)
288                 ra = ra + 5;
289
290         /* patch the field's offset */
291
292         if (IS_2_WORD_TYPE(fi->type) || IS_ADR_TYPE(fi->type)) {
293                 /* handle special case when the base register is %r12 */
294
295                 if (*(ra + 2) == 0x84) {
296                         *((u4 *) (ra + 4))      = (u4) (fi->offset);
297                         *((u4 *) (ra + 12 + 4)) = (u4) (fi->offset + 4);
298                 }
299                 else {
300                         *((u4 *) (ra + 3))      = (u4) (fi->offset);
301                         *((u4 *) (ra + 11 + 3)) = (u4) (fi->offset + 4);
302                 }
303         }
304         else {
305                 /* handle special case when the base register is %r12 */
306
307                 if (*(ra + 2) == 0x84)
308                         *((u4 *) (ra + 4)) = (u4) (fi->offset);
309                 else
310                         *((u4 *) (ra + 3)) = (u4) (fi->offset);
311         }
312
313         return true;
314 }
315
316
317 /* patcher_aconst **************************************************************
318
319    Machine code:
320
321    <patched call position>
322    48 bf a0 f0 92 00 00 00 00 00    mov    $0x92f0a0,%rdi
323
324 *******************************************************************************/
325
326 bool patcher_aconst(u1 *sp)
327 {
328         u1                *ra;
329         u8                 mcode;
330         constant_classref *cr;
331         classinfo         *c;
332
333         /* get stuff from the stack */
334
335         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
336         mcode =                       *((u8 *)     (sp + 3 * 8));
337         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 8));
338
339         /* get the classinfo */
340
341         if (!(c = resolve_classref_eager(cr)))
342                 return false;
343
344         /* patch back original code */
345
346         *((u8 *) ra) = mcode;
347
348         /* if we show disassembly, we have to skip the nop's */
349
350         if (opt_showdisassemble)
351                 ra = ra + 5;
352
353         /* patch the classinfo pointer */
354
355         *((ptrint *) (ra + 2)) = (ptrint) c;
356
357         return true;
358 }
359
360
361 /* patcher_builtin_multianewarray **********************************************
362
363    Machine code:
364
365    <patched call position>
366    48 bf 02 00 00 00 00 00 00 00    mov    $0x2,%rdi
367    48 be 30 40 b2 00 00 00 00 00    mov    $0xb24030,%rsi
368    48 89 e2                         mov    %rsp,%rdx
369    48 b8 7c 96 4b 00 00 00 00 00    mov    $0x4b967c,%rax
370    48 ff d0                         callq  *%rax
371
372 *******************************************************************************/
373
374 bool patcher_builtin_multianewarray(u1 *sp)
375 {
376         u1                *ra;
377         u8                 mcode;
378         constant_classref *cr;
379         classinfo         *c;
380
381         /* get stuff from the stack */
382
383         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
384         mcode =                       *((u8 *)     (sp + 3 * 8));
385         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 8));
386
387         /* get the classinfo */
388
389         if (!(c = resolve_classref_eager(cr)))
390                 return false;
391
392         /* patch back original code */
393
394         *((u8 *) ra) = mcode;
395
396         /* if we show disassembly, we have to skip the nop's */
397
398         if (opt_showdisassemble)
399                 ra = ra + 5;
400
401         /* patch the classinfo pointer */
402
403         *((ptrint *) (ra + 10 + 2)) = (ptrint) c;
404
405         /* patch new function address */
406
407         *((ptrint *) (ra + 10 + 10 + 3 + 2)) = (ptrint) BUILTIN_multianewarray;
408
409         return true;
410 }
411
412
413 /* patcher_builtin_arraycheckcast **********************************************
414
415    Machine code:
416
417    <patched call position>
418    48 be b8 3f b2 00 00 00 00 00    mov    $0xb23fb8,%rsi
419    48 b8 00 00 00 00 00 00 00 00    mov    $0x0,%rax
420    48 ff d0                         callq  *%rax
421
422 *******************************************************************************/
423
424 bool patcher_builtin_arraycheckcast(u1 *sp)
425 {
426         u1                *ra;
427         u8                 mcode;
428         constant_classref *cr;
429         classinfo         *c;
430
431         /* get stuff from the stack */
432
433         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
434         mcode =                       *((u8 *)     (sp + 3 * 8));
435         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 8));
436
437         /* get the classinfo */
438
439         if (!(c = resolve_classref_eager(cr)))
440                 return false;
441
442         /* patch back original code */
443
444         *((u8 *) ra) = mcode;
445
446         /* if we show disassembly, we have to skip the nop's */
447
448         if (opt_showdisassemble)
449                 ra = ra + 5;
450
451         /* patch the classinfo pointer */
452
453         *((ptrint *) (ra + 2)) = (ptrint) c;
454
455         return true;
456 }
457
458
459 /* patcher_invokestatic_special ************************************************
460
461    Machine code:
462
463    <patched call position>
464    49 ba 00 00 00 00 00 00 00 00    mov    $0x0,%r10
465    49 ff d2                         callq  *%r10
466
467 *******************************************************************************/
468
469 bool patcher_invokestatic_special(u1 *sp)
470 {
471         u1                *ra;
472         u8                 mcode;
473         unresolved_method *um;
474         methodinfo        *m;
475
476         /* get stuff from the stack */
477
478         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
479         mcode =                       *((u8 *)     (sp + 3 * 8));
480         um    = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
481
482         /* get the fieldinfo */
483
484         if (!(m = resolve_method_eager(um)))
485                 return false;
486
487         /* patch back original code */
488
489         *((u8 *) ra) = mcode;
490
491         /* if we show disassembly, we have to skip the nop's */
492
493         if (opt_showdisassemble)
494                 ra = ra + 5;
495
496         /* patch stubroutine */
497
498         *((ptrint *) (ra + 2)) = (ptrint) m->stubroutine;
499
500         return true;
501 }
502
503
504 /* patcher_invokevirtual *******************************************************
505
506    Machine code:
507
508    <patched call position>
509    4c 8b 17                         mov    (%rdi),%r10
510    49 8b 82 00 00 00 00             mov    0x0(%r10),%rax
511    48 ff d0                         callq  *%rax
512
513 *******************************************************************************/
514
515 bool patcher_invokevirtual(u1 *sp)
516 {
517         u1                *ra;
518         u8                 mcode;
519         unresolved_method *um;
520         methodinfo        *m;
521
522         /* get stuff from the stack */
523
524         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
525         mcode =                       *((u8 *)     (sp + 3 * 8));
526         um    = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
527
528         /* get the fieldinfo */
529
530         if (!(m = resolve_method_eager(um)))
531                 return false;
532
533         /* patch back original code */
534
535         *((u8 *) ra) = mcode;
536
537         /* if we show disassembly, we have to skip the nop's */
538
539         if (opt_showdisassemble)
540                 ra = ra + 5;
541
542         /* patch vftbl index */
543
544         *((s4 *) (ra + 3 + 3)) = (s4) (OFFSET(vftbl_t, table[0]) +
545                                                                    sizeof(methodptr) * m->vftblindex);
546
547         return true;
548 }
549
550
551 /* patcher_invokeinterface *****************************************************
552
553    Machine code:
554
555    <patched call position>
556    4c 8b 17                         mov    (%rdi),%r10
557    4d 8b 92 00 00 00 00             mov    0x0(%r10),%r10
558    49 8b 82 00 00 00 00             mov    0x0(%r10),%rax
559    48 ff d0                         callq  *%rax
560
561 *******************************************************************************/
562
563 bool patcher_invokeinterface(u1 *sp)
564 {
565         u1                *ra;
566         u8                 mcode;
567         unresolved_method *um;
568         methodinfo        *m;
569
570         /* get stuff from the stack */
571
572         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
573         mcode =                       *((u8 *)     (sp + 3 * 8));
574         um    = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
575
576         /* get the fieldinfo */
577
578         if (!(m = resolve_method_eager(um)))
579                 return false;
580
581         /* patch back original code */
582
583         *((u8 *) ra) = mcode;
584
585         /* if we show disassembly, we have to skip the nop's */
586
587         if (opt_showdisassemble)
588                 ra = ra + 5;
589
590         /* patch interfacetable index */
591
592         *((s4 *) (ra + 3 + 3)) = (s4) (OFFSET(vftbl_t, interfacetable[0]) -
593                                                                    sizeof(methodptr) * m->class->index);
594
595         /* patch method offset */
596
597         *((s4 *) (ra + 3 + 7 + 3)) =
598                 (s4) (sizeof(methodptr) * (m - m->class->methods));
599
600         return true;
601 }
602
603
604 /* patcher_checkcast_instanceof_flags ******************************************
605
606    Machine code:
607
608    <patched call position>
609    41 ba 00 00 00 00                mov    $0x0,%r10d
610    41 81 e2 00 02 00 00             and    $0x200,%r10d
611    0f 84 35 00 00 00                je     0x00002aaaaab01479
612
613 *******************************************************************************/
614
615 bool patcher_checkcast_instanceof_flags(u1 *sp)
616 {
617         u1                *ra;
618         u8                 mcode;
619         constant_classref *cr;
620         classinfo         *c;
621
622         /* get stuff from the stack */
623
624         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
625         mcode =                       *((u8 *)     (sp + 3 * 8));
626         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 8));
627
628         /* get the fieldinfo */
629
630         if (!(c = resolve_classref_eager(cr)))
631                 return false;
632
633         /* patch back original code */
634
635         *((u8 *) ra) = mcode;
636
637         /* if we show disassembly, we have to skip the nop's */
638
639         if (opt_showdisassemble)
640                 ra = ra + 5;
641
642         /* patch class flags */
643
644         *((s4 *) (ra + 2)) = (s4) c->flags;
645
646         return true;
647 }
648
649
650 /* patcher_checkcast_instanceof_interface **************************************
651
652    Machine code:
653
654    <patched call position>
655    45 8b 9a 1c 00 00 00             mov    0x1c(%r10),%r11d
656    49 81 eb 00 00 00 00             sub    $0x0,%r11
657    4d 85 db                         test   %r11,%r11
658    0f 8e 94 04 00 00                jle    0x00002aaaaab018f8
659    4d 8b 9a 00 00 00 00             mov    0x0(%r10),%r11
660
661 *******************************************************************************/
662
663 bool patcher_checkcast_instanceof_interface(u1 *sp)
664 {
665         u1                *ra;
666         u8                 mcode;
667         constant_classref *cr;
668         classinfo         *c;
669
670         /* get stuff from the stack */
671
672         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
673         mcode =                       *((u8 *)     (sp + 3 * 8));
674         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 8));
675
676         /* get the fieldinfo */
677
678         if (!(c = resolve_classref_eager(cr)))
679                 return false;
680
681         /* patch back original code */
682
683         *((u8 *) ra) = mcode;
684
685         /* if we show disassembly, we have to skip the nop's */
686
687         if (opt_showdisassemble)
688                 ra = ra + 5;
689
690         /* patch super class index */
691
692         *((s4 *) (ra + 7 + 3)) = (s4) c->index;
693
694         *((s4 *) (ra + 7 + 7 + 3 + 6 + 3)) =
695                 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
696                           c->index * sizeof(methodptr*));
697
698         return true;
699 }
700
701
702 /* patcher_checkcast_class *****************************************************
703
704    Machine code:
705
706    <patched call position>
707    49 bb 00 00 00 00 00 00 00 00    mov    $0x0,%r11
708    45 8b 92 20 00 00 00             mov    0x20(%r10),%r10d
709    45 8b 9b 20 00 00 00             mov    0x20(%r11),%r11d
710    4d 29 da                         sub    %r11,%r10
711    49 bb 00 00 00 00 00 00 00 00    mov    $0x0,%r11
712
713 *******************************************************************************/
714
715 bool patcher_checkcast_class(u1 *sp)
716 {
717         u1                *ra;
718         u8                 mcode;
719         constant_classref *cr;
720         classinfo         *c;
721
722         /* get stuff from the stack */
723
724         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
725         mcode =                       *((u8 *)     (sp + 3 * 8));
726         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 8));
727
728         /* get the fieldinfo */
729
730         if (!(c = resolve_classref_eager(cr)))
731                 return false;
732
733         /* patch back original code */
734
735         *((u8 *) ra) = mcode;
736
737         /* if we show disassembly, we have to skip the nop's */
738
739         if (opt_showdisassemble)
740                 ra = ra + 5;
741
742         /* patch super class' vftbl */
743
744         *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
745         *((ptrint *) (ra + 10 + 7 + 7 + 3 + 2)) = (ptrint) c->vftbl;
746
747         return true;
748 }
749
750
751 /* patcher_instanceof_class ****************************************************
752
753    Machine code:
754
755    <patched call position>
756    49 ba 00 00 00 00 00 00 00 00    mov    $0x0,%r10
757
758 *******************************************************************************/
759
760 bool patcher_instanceof_class(u1 *sp)
761 {
762         u1                *ra;
763         u8                 mcode;
764         constant_classref *cr;
765         classinfo         *c;
766
767         /* get stuff from the stack */
768
769         ra    = (u1 *)                *((ptrint *) (sp + 5 * 8));
770         mcode =                       *((u8 *)     (sp + 3 * 8));
771         cr    = (constant_classref *) *((ptrint *) (sp + 2 * 8));
772
773         /* get the fieldinfo */
774
775         if (!(c = resolve_classref_eager(cr)))
776                 return false;
777
778         /* patch back original code */
779
780         *((u8 *) ra) = mcode;
781
782         /* if we show disassembly, we have to skip the nop's */
783
784         if (opt_showdisassemble)
785                 ra = ra + 5;
786
787         /* patch super class' vftbl */
788
789         *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
790
791         return true;
792 }
793
794
795 /* patcher_clinit **************************************************************
796
797    May be used for GET/PUTSTATIC and in native stub.
798
799    Machine code:
800
801    <patched call position>
802    4d 8b 15 92 ff ff ff             mov    -110(%rip),%r10
803    49 89 1a                         mov    %rbx,(%r10)
804
805 *******************************************************************************/
806
807 bool patcher_clinit(u1 *sp)
808 {
809         u1        *ra;
810         u8         mcode;
811         classinfo *c;
812
813         /* get stuff from the stack */
814
815         ra    = (u1 *)        *((ptrint *) (sp + 5 * 8));
816         mcode =               *((u8 *)     (sp + 3 * 8));
817         c     = (classinfo *) *((ptrint *) (sp + 2 * 8));
818
819         /* check if the class is initialized */
820
821         if (!(c->state & CLASS_INITIALIZED))
822                 if (!initialize_class(c))
823                         return false;
824
825         /* patch back original code */
826
827         *((u8 *) ra) = mcode;
828
829         return true;
830 }
831
832
833 /* patcher_athrow_areturn ******************************************************
834
835    Machine code:
836
837    <patched call position>
838
839 *******************************************************************************/
840
841 #ifdef ENABLE_VERIFIER
842 bool patcher_athrow_areturn(u1 *sp)
843 {
844         u1               *ra;
845         u8                mcode;
846         unresolved_class *uc;
847         classinfo        *c;
848
849         /* get stuff from the stack */
850
851         ra    = (u1 *)               *((ptrint *) (sp + 5 * 8));
852         mcode =                      *((u8 *)     (sp + 3 * 8));
853         uc    = (unresolved_class *) *((ptrint *) (sp + 2 * 8));
854
855         /* resolve the class */
856
857         if (!resolve_class(uc, resolveEager, false, &c))
858                 return false;
859
860         /* patch back original code */
861
862         *((u8 *) ra) = mcode;
863
864         return true;
865 }
866 #endif /* ENABLE_VERIFIER */
867
868
869 /* patcher_resolve_native ******************************************************
870
871    Machine code:
872
873    <patched call position>
874    48 b8 00 00 00 00 00 00 00 00    mov    $0x0,%rax
875    48 ff d0                         callq  *%rax
876
877 *******************************************************************************/
878
879 #if !defined(WITH_STATIC_CLASSPATH)
880 bool patcher_resolve_native(u1 *sp)
881 {
882         u1          *ra;
883         u8           mcode;
884         methodinfo  *m;
885         functionptr  f;
886
887         /* get stuff from the stack */
888
889         ra    = (u1 *)         *((ptrint *) (sp + 5 * 8));
890         mcode =                *((u8 *)     (sp + 3 * 8));
891         m     = (methodinfo *) *((ptrint *) (sp + 2 * 8));
892
893         /* resolve native function */
894
895         if (!(f = native_resolve_function(m)))
896                 return false;
897
898         /* patch back original code */
899
900         *((u8 *) ra) = mcode;
901
902         /* if we show disassembly, we have to skip the nop's */
903
904         if (opt_showdisassemble)
905                 ra = ra + 5;
906
907         /* patch native function pointer */
908
909         *((ptrint *) (ra + 2)) = (ptrint) f;
910
911         return true;
912 }
913 #endif /* !defined(WITH_STATIC_CLASSPATH) */
914
915
916 /*
917  * These are local overrides for various environment variables in Emacs.
918  * Please do not remove this and leave it at the end of the file, where
919  * Emacs will automagically detect them.
920  * ---------------------------------------------------------------------
921  * Local variables:
922  * mode: c
923  * indent-tabs-mode: t
924  * c-basic-offset: 4
925  * tab-width: 4
926  * End:
927  * vim:noexpandtab:sw=4:ts=4:
928  */