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