blob: 64189dcd996a5b210cda0b5feb02ea0a3101bd9c [file] [log] [blame]
sewardj35421a32004-07-05 13:12:34 +00001
2/*---------------------------------------------------------------*/
3/*--- ---*/
sewardj887a11a2004-07-05 17:26:47 +00004/*--- This file (vex_main.c) is ---*/
sewardj35421a32004-07-05 13:12:34 +00005/*--- Copyright (c) 2004 OpenWorks LLP. All rights reserved. ---*/
6/*--- ---*/
7/*---------------------------------------------------------------*/
8
sewardj887a11a2004-07-05 17:26:47 +00009#include "libvex.h"
sewardjf13a16a2004-07-05 17:10:14 +000010
sewardj887a11a2004-07-05 17:26:47 +000011#include "vex_globals.h"
sewardj35421a32004-07-05 13:12:34 +000012#include "vex_util.h"
sewardjf13a16a2004-07-05 17:10:14 +000013#include "host_regs.h"
14#include "x86h_defs.h"
sewardjc9a65702004-07-07 16:32:57 +000015#include "x86guest_defs.h"
sewardj35421a32004-07-05 13:12:34 +000016
17
18/* This file contains the top level interface to the library. */
19
20/* --------- Initialise the library. --------- */
21
22/* Exported to library client. */
23
sewardj887a11a2004-07-05 17:26:47 +000024void LibVEX_Init (
sewardj35421a32004-07-05 13:12:34 +000025 /* failure exit function */
sewardj2b515872004-07-05 20:50:45 +000026 __attribute__ ((noreturn))
sewardj35421a32004-07-05 13:12:34 +000027 void (*failure_exit) ( void ),
28 /* logging output function */
29 void (*log_bytes) ( Char*, Int nbytes ),
30 /* debug paranoia level */
31 Int debuglevel,
32 /* verbosity level */
33 Int verbosity,
34 /* Are we supporting valgrind checking? */
35 Bool valgrind_support,
36 /* Max # guest insns per bb */
37 Int guest_insns_per_bb
38)
39{
40 vassert(!vex_initdone);
41 vassert(failure_exit);
42 vex_failure_exit = failure_exit;
43 vassert(log_bytes);
44 vex_log_bytes = log_bytes;
45 vassert(debuglevel >= 0);
46 vex_debuglevel = debuglevel;
47 vassert(verbosity >= 0);
48 vex_verbosity = verbosity;
49 vex_valgrind_support = valgrind_support;
50 vassert(guest_insns_per_bb >= 1 && guest_insns_per_bb <= 100);
51 vex_guest_insns_per_bb = guest_insns_per_bb;
52 vex_initdone = True;
53}
54
55
56/* --------- Make a translation. --------- */
57
58/* Exported to library client. */
59
sewardj887a11a2004-07-05 17:26:47 +000060TranslateResult LibVEX_Translate (
sewardj35421a32004-07-05 13:12:34 +000061 /* The instruction sets we are translating from and to. */
62 InsnSet iset_guest,
63 InsnSet iset_host,
64 /* IN: the block to translate, and its guest address. */
65 Char* guest_bytes,
66 Addr64 guest_bytes_addr,
67 /* OUT: the number of bytes actually read */
68 Int* guest_bytes_read,
69 /* IN: a place to put the resulting code, and its size */
70 Char* host_bytes,
71 Int host_bytes_size,
72 /* OUT: how much of the output area is used. */
73 Int* host_bytes_used,
74 /* IN: optionally, an instrumentation function. */
sewardjf13a16a2004-07-05 17:10:14 +000075 IRBB* (*instrument) ( IRBB* ),
sewardj35421a32004-07-05 13:12:34 +000076 /* IN: optionally, an access check function for guest code. */
77 Bool (*byte_accessible) ( Addr64 )
78)
79{
sewardjf13a16a2004-07-05 17:10:14 +000080 /* Stuff we need to know for reg-alloc. */
81 HReg* available_real_regs;
82 Int n_available_real_regs;
83 Bool (*isMove) (HInstr*, HReg*, HReg*);
84 void (*getRegUsage) (HRegUsage*, HInstr*);
85 void (*mapRegs) (HRegRemap*, HInstr*);
86 HInstr* (*genSpill) ( HReg, Int );
87 HInstr* (*genReload) ( HReg, Int );
sewardj2b515872004-07-05 20:50:45 +000088 void (*ppInstr) ( HInstr* );
89 void (*ppReg) ( HReg );
sewardjf13a16a2004-07-05 17:10:14 +000090 HInstrArray* (*iselBB) ( IRBB* );
sewardj41f43bc2004-07-08 14:23:22 +000091 IRBB* (*bbToIR) ( UChar*, Addr64, Int*, Bool(*)(Addr64), Bool );
sewardjf13a16a2004-07-05 17:10:14 +000092
sewardjc9a65702004-07-07 16:32:57 +000093 Bool host_is_bigendian = False;
sewardjf13a16a2004-07-05 17:10:14 +000094 IRBB* irbb;
95 HInstrArray* vcode;
96 HInstrArray* rcode;
sewardjfbcaf332004-07-08 01:46:01 +000097 Int i;
sewardjf13a16a2004-07-05 17:10:14 +000098
sewardj35421a32004-07-05 13:12:34 +000099 vassert(vex_initdone);
sewardj887a11a2004-07-05 17:26:47 +0000100 LibVEX_Clear(False);
sewardjf13a16a2004-07-05 17:10:14 +0000101
102 /* First off, check that the guest and host insn sets
103 are supported. */
104 switch (iset_host) {
105 case InsnSetX86:
106 getAllocableRegs_X86 ( &n_available_real_regs,
107 &available_real_regs );
108 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_X86Instr;
109 getRegUsage = (void(*)(HRegUsage*,HInstr*)) getRegUsage_X86Instr;
110 mapRegs = (void(*)(HRegRemap*,HInstr*)) mapRegs_X86Instr;
111 genSpill = (HInstr*(*)(HReg,Int)) genSpill_X86;
112 genReload = (HInstr*(*)(HReg,Int)) genReload_X86;
sewardj2b515872004-07-05 20:50:45 +0000113 ppInstr = (void(*)(HInstr*)) ppX86Instr;
114 ppReg = (void(*)(HReg)) ppHRegX86;
sewardjf13a16a2004-07-05 17:10:14 +0000115 iselBB = iselBB_X86;
sewardjc9a65702004-07-07 16:32:57 +0000116 host_is_bigendian = False;
sewardjf13a16a2004-07-05 17:10:14 +0000117 break;
118 default:
sewardj887a11a2004-07-05 17:26:47 +0000119 vpanic("LibVEX_Translate: unsupported target insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000120 }
121
122 switch (iset_guest) {
123 case InsnSetX86:
sewardjc9a65702004-07-07 16:32:57 +0000124 bbToIR = bbToIR_X86Instr;
sewardjf13a16a2004-07-05 17:10:14 +0000125 break;
126 default:
sewardj887a11a2004-07-05 17:26:47 +0000127 vpanic("LibVEX_Translate: unsupported guest insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000128 }
129
130 irbb = bbToIR ( guest_bytes,
131 guest_bytes_addr,
132 guest_bytes_read,
sewardjc9a65702004-07-07 16:32:57 +0000133 byte_accessible,
134 host_is_bigendian );
sewardjf13a16a2004-07-05 17:10:14 +0000135
136 if (irbb == NULL) {
137 /* Access failure. */
sewardj887a11a2004-07-05 17:26:47 +0000138 LibVEX_Clear(False);
sewardjf13a16a2004-07-05 17:10:14 +0000139 return TransAccessFail;
140 }
sewardj35439212004-07-14 22:36:10 +0000141 sanityCheckIRBB(irbb, Ity_I32);
sewardje8e9d732004-07-16 21:03:45 +0000142
sewardjf13a16a2004-07-05 17:10:14 +0000143 /* Get the thing instrumented. */
144 if (instrument)
145 irbb = (*instrument)(irbb);
146
147 /* Turn it into virtual-registerised code. */
148 vcode = iselBB ( irbb );
sewardje8e9d732004-07-16 21:03:45 +0000149return TransOK;
sewardjf13a16a2004-07-05 17:10:14 +0000150
sewardjfbcaf332004-07-08 01:46:01 +0000151 vex_printf("\n-------- Virtual registerised code --------\n");
152 for (i = 0; i < vcode->arr_used; i++) {
153 ppInstr(vcode->arr[i]);
154 vex_printf("\n");
155 }
156 vex_printf("\n");
157
sewardjf13a16a2004-07-05 17:10:14 +0000158 /* Register allocate. */
159 rcode = doRegisterAllocation ( vcode, available_real_regs,
160 n_available_real_regs,
161 isMove, getRegUsage, mapRegs,
sewardj2b515872004-07-05 20:50:45 +0000162 genSpill, genReload,
163 ppInstr, ppReg );
sewardjf13a16a2004-07-05 17:10:14 +0000164
sewardjfbcaf332004-07-08 01:46:01 +0000165 vex_printf("\n-------- Post-regalloc code --------\n");
166 for (i = 0; i < rcode->arr_used; i++) {
167 ppInstr(rcode->arr[i]);
168 vex_printf("\n");
169 }
170 vex_printf("\n");
171
sewardjf13a16a2004-07-05 17:10:14 +0000172 /* Assemble, etc. */
sewardj887a11a2004-07-05 17:26:47 +0000173 LibVEX_Clear(True);
sewardjf13a16a2004-07-05 17:10:14 +0000174
sewardj35421a32004-07-05 13:12:34 +0000175 return TransOK;
176}
177
178
179
180/*---------------------------------------------------------------*/
sewardj887a11a2004-07-05 17:26:47 +0000181/*--- end vex_main.c ---*/
sewardj35421a32004-07-05 13:12:34 +0000182/*---------------------------------------------------------------*/