blob: f1589c39e91d431c24c32dd207ea23f292dd2cc7 [file] [log] [blame]
sewardj35421a32004-07-05 13:12:34 +00001
2/*---------------------------------------------------------------*/
3/*--- ---*/
sewardjc0ee2ed2004-07-27 10:29:41 +00004/*--- This file (main/vex_main.c) is ---*/
sewardjdbcfae72005-08-02 11:14:04 +00005/*--- Copyright (C) OpenWorks LLP. All rights reserved. ---*/
sewardj35421a32004-07-05 13:12:34 +00006/*--- ---*/
7/*---------------------------------------------------------------*/
8
sewardjf8ed9d82004-11-12 17:40:23 +00009/*
10 This file is part of LibVEX, a library for dynamic binary
11 instrumentation and translation.
12
sewardj7bd6ffe2005-08-03 16:07:36 +000013 Copyright (C) 2004-2005 OpenWorks LLP. All rights reserved.
sewardjf8ed9d82004-11-12 17:40:23 +000014
sewardj7bd6ffe2005-08-03 16:07:36 +000015 This library is made available under a dual licensing scheme.
sewardjf8ed9d82004-11-12 17:40:23 +000016
sewardj7bd6ffe2005-08-03 16:07:36 +000017 If you link LibVEX against other code all of which is itself
18 licensed under the GNU General Public License, version 2 dated June
19 1991 ("GPL v2"), then you may use LibVEX under the terms of the GPL
20 v2, as appearing in the file LICENSE.GPL. If the file LICENSE.GPL
21 is missing, you can obtain a copy of the GPL v2 from the Free
22 Software Foundation Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 02110-1301, USA.
24
25 For any other uses of LibVEX, you must first obtain a commercial
26 license from OpenWorks LLP. Please contact info@open-works.co.uk
27 for information about commercial licensing.
28
29 This software is provided by OpenWorks LLP "as is" and any express
30 or implied warranties, including, but not limited to, the implied
31 warranties of merchantability and fitness for a particular purpose
32 are disclaimed. In no event shall OpenWorks LLP be liable for any
33 direct, indirect, incidental, special, exemplary, or consequential
34 damages (including, but not limited to, procurement of substitute
35 goods or services; loss of use, data, or profits; or business
36 interruption) however caused and on any theory of liability,
37 whether in contract, strict liability, or tort (including
38 negligence or otherwise) arising in any way out of the use of this
39 software, even if advised of the possibility of such damage.
sewardjf8ed9d82004-11-12 17:40:23 +000040
41 Neither the names of the U.S. Department of Energy nor the
42 University of California nor the names of its contributors may be
43 used to endorse or promote products derived from this software
44 without prior written permission.
sewardjf8ed9d82004-11-12 17:40:23 +000045*/
46
sewardj887a11a2004-07-05 17:26:47 +000047#include "libvex.h"
sewardj893aada2004-11-29 19:57:54 +000048#include "libvex_emwarn.h"
sewardj81ec4182004-10-25 23:15:52 +000049#include "libvex_guest_x86.h"
sewardj44d494d2005-01-20 20:26:33 +000050#include "libvex_guest_amd64.h"
sewardj2a9ad022004-11-25 02:46:58 +000051#include "libvex_guest_arm.h"
cerionaabdfbf2005-01-29 12:56:15 +000052#include "libvex_guest_ppc32.h"
sewardjf13a16a2004-07-05 17:10:14 +000053
sewardjc0ee2ed2004-07-27 10:29:41 +000054#include "main/vex_globals.h"
55#include "main/vex_util.h"
56#include "host-generic/h_generic_regs.h"
sewardjedf4d692004-08-17 13:52:58 +000057#include "ir/iropt.h"
sewardj35421a32004-07-05 13:12:34 +000058
sewardj2a9ad022004-11-25 02:46:58 +000059#include "host-x86/hdefs.h"
sewardjc33671d2005-02-01 20:30:00 +000060#include "host-amd64/hdefs.h"
cerion487e4c92005-02-04 16:28:19 +000061#include "host-ppc32/hdefs.h"
sewardj2a9ad022004-11-25 02:46:58 +000062
sewardj9e6491a2005-07-02 19:24:10 +000063#include "guest-generic/bb_to_IR.h"
sewardj2a9ad022004-11-25 02:46:58 +000064#include "guest-x86/gdefs.h"
sewardj44d494d2005-01-20 20:26:33 +000065#include "guest-amd64/gdefs.h"
sewardj2a9ad022004-11-25 02:46:58 +000066#include "guest-arm/gdefs.h"
cerionaabdfbf2005-01-29 12:56:15 +000067#include "guest-ppc32/gdefs.h"
sewardj2a9ad022004-11-25 02:46:58 +000068
sewardj35421a32004-07-05 13:12:34 +000069
70/* This file contains the top level interface to the library. */
71
72/* --------- Initialise the library. --------- */
73
74/* Exported to library client. */
75
sewardjd887b862005-01-17 18:34:34 +000076const HChar* LibVEX_Version ( void )
sewardj80f5fce2004-12-20 04:37:50 +000077{
78return
79#include "main/vex_svnversion.h"
80 ;
81}
82
83
84/* Exported to library client. */
85
sewardj08613742004-10-25 13:01:45 +000086void LibVEX_default_VexControl ( /*OUT*/ VexControl* vcon )
87{
88 vcon->iropt_verbosity = 0;
89 vcon->iropt_level = 2;
90 vcon->iropt_precise_memory_exns = False;
91 vcon->iropt_unroll_thresh = 120;
sewardj18b4bb72005-03-29 21:32:41 +000092 vcon->guest_max_insns = 60;
sewardj08613742004-10-25 13:01:45 +000093 vcon->guest_chase_thresh = 10;
94}
95
96
97/* Exported to library client. */
98
sewardj887a11a2004-07-05 17:26:47 +000099void LibVEX_Init (
sewardj35421a32004-07-05 13:12:34 +0000100 /* failure exit function */
sewardj2b515872004-07-05 20:50:45 +0000101 __attribute__ ((noreturn))
sewardj35421a32004-07-05 13:12:34 +0000102 void (*failure_exit) ( void ),
103 /* logging output function */
sewardjd9763622005-02-07 03:12:19 +0000104 void (*log_bytes) ( HChar*, Int nbytes ),
sewardj35421a32004-07-05 13:12:34 +0000105 /* debug paranoia level */
106 Int debuglevel,
sewardj35421a32004-07-05 13:12:34 +0000107 /* Are we supporting valgrind checking? */
108 Bool valgrind_support,
sewardj08613742004-10-25 13:01:45 +0000109 /* Control ... */
110 /*READONLY*/VexControl* vcon
sewardj35421a32004-07-05 13:12:34 +0000111)
112{
sewardj08613742004-10-25 13:01:45 +0000113 /* First off, do enough minimal setup so that the following
114 assertions can fail in a sane fashion, if need be. */
sewardjea602bc2004-10-14 21:40:12 +0000115 vex_failure_exit = failure_exit;
116 vex_log_bytes = log_bytes;
117
118 /* Now it's safe to check parameters for sanity. */
sewardj35421a32004-07-05 13:12:34 +0000119 vassert(!vex_initdone);
120 vassert(failure_exit);
sewardj35421a32004-07-05 13:12:34 +0000121 vassert(log_bytes);
sewardj35421a32004-07-05 13:12:34 +0000122 vassert(debuglevel >= 0);
sewardj08613742004-10-25 13:01:45 +0000123
124 vassert(vcon->iropt_verbosity >= 0);
125 vassert(vcon->iropt_level >= 0);
126 vassert(vcon->iropt_level <= 2);
127 vassert(vcon->iropt_unroll_thresh >= 0);
128 vassert(vcon->iropt_unroll_thresh <= 400);
129 vassert(vcon->guest_max_insns >= 1);
130 vassert(vcon->guest_max_insns <= 100);
131 vassert(vcon->guest_chase_thresh >= 0);
132 vassert(vcon->guest_chase_thresh < vcon->guest_max_insns);
sewardj443cd9d2004-07-18 23:06:45 +0000133
sewardjea602bc2004-10-14 21:40:12 +0000134 /* Check that Vex has been built with sizes of basic types as
135 stated in priv/libvex_basictypes.h. Failure of any of these is
136 a serious configuration error and should be corrected
137 immediately. If any of these assertions fail you can fully
138 expect Vex not to work properly, if at all. */
139
140 vassert(1 == sizeof(UChar));
141 vassert(1 == sizeof(Char));
142 vassert(2 == sizeof(UShort));
143 vassert(2 == sizeof(Short));
144 vassert(4 == sizeof(UInt));
145 vassert(4 == sizeof(Int));
146 vassert(8 == sizeof(ULong));
147 vassert(8 == sizeof(Long));
148 vassert(4 == sizeof(Float));
149 vassert(8 == sizeof(Double));
150 vassert(1 == sizeof(Bool));
151 vassert(4 == sizeof(Addr32));
152 vassert(8 == sizeof(Addr64));
sewardjc9a43662004-11-30 18:51:59 +0000153 vassert(16 == sizeof(U128));
sewardjea602bc2004-10-14 21:40:12 +0000154
155 vassert(sizeof(void*) == 4 || sizeof(void*) == 8);
156 vassert(sizeof(void*) == sizeof(int*));
157 vassert(sizeof(void*) == sizeof(HWord));
158
sewardj97e87932005-02-07 00:00:50 +0000159 vassert(VEX_HOST_WORDSIZE == sizeof(void*));
160 vassert(VEX_HOST_WORDSIZE == sizeof(HWord));
161
sewardjea602bc2004-10-14 21:40:12 +0000162 /* Really start up .. */
sewardj443cd9d2004-07-18 23:06:45 +0000163 vex_debuglevel = debuglevel;
sewardj443cd9d2004-07-18 23:06:45 +0000164 vex_valgrind_support = valgrind_support;
sewardj08613742004-10-25 13:01:45 +0000165 vex_control = *vcon;
sewardj443cd9d2004-07-18 23:06:45 +0000166 vex_initdone = True;
sewardjd887b862005-01-17 18:34:34 +0000167 vexSetAllocMode ( VexAllocModeTEMP );
sewardj35421a32004-07-05 13:12:34 +0000168}
169
170
171/* --------- Make a translation. --------- */
172
173/* Exported to library client. */
174
sewardjd887b862005-01-17 18:34:34 +0000175VexTranslateResult LibVEX_Translate (
sewardj35421a32004-07-05 13:12:34 +0000176 /* The instruction sets we are translating from and to. */
sewardj27e1dd62005-06-30 11:49:14 +0000177 VexArch arch_guest,
178 VexArchInfo* archinfo_guest,
179 VexArch arch_host,
180 VexArchInfo* archinfo_host,
sewardj35421a32004-07-05 13:12:34 +0000181 /* IN: the block to translate, and its guest address. */
sewardjbef170b2004-12-21 01:23:00 +0000182 UChar* guest_bytes,
183 Addr64 guest_bytes_addr,
184 Bool (*chase_into_ok) ( Addr64 ),
sewardj72c72812005-01-19 11:49:45 +0000185 /* OUT: which bits of guest code actually got translated */
186 VexGuestExtents* guest_extents,
sewardj35421a32004-07-05 13:12:34 +0000187 /* IN: a place to put the resulting code, and its size */
sewardjbef170b2004-12-21 01:23:00 +0000188 UChar* host_bytes,
189 Int host_bytes_size,
sewardj35421a32004-07-05 13:12:34 +0000190 /* OUT: how much of the output area is used. */
sewardjbef170b2004-12-21 01:23:00 +0000191 Int* host_bytes_used,
sewardj49651f42004-10-28 22:11:04 +0000192 /* IN: optionally, two instrumentation functions. */
sewardj918c8f32005-03-21 00:54:33 +0000193 IRBB* (*instrument1) ( IRBB*, VexGuestLayout*,
194 IRType gWordTy, IRType hWordTy ),
195 IRBB* (*instrument2) ( IRBB*, VexGuestLayout*,
196 IRType gWordTy, IRType hWordTy ),
sewardjbef170b2004-12-21 01:23:00 +0000197 Bool cleanup_after_instrumentation,
sewardjec3c8852005-07-07 09:56:24 +0000198 /* IN: should this translation be self-checking? */
199 Bool do_self_check,
sewardj35421a32004-07-05 13:12:34 +0000200 /* IN: optionally, an access check function for guest code. */
sewardjbef170b2004-12-21 01:23:00 +0000201 Bool (*byte_accessible) ( Addr64 ),
sewardjf48ac192004-10-29 00:41:29 +0000202 /* IN: debug: trace vex activity at various points */
sewardjbef170b2004-12-21 01:23:00 +0000203 Int traceflags
sewardj35421a32004-07-05 13:12:34 +0000204)
205{
sewardj81bd5502004-07-21 18:49:27 +0000206 /* This the bundle of functions we need to do the back-end stuff
207 (insn selection, reg-alloc, assembly) whilst being insulated
208 from the target instruction set. */
sewardjf13a16a2004-07-05 17:10:14 +0000209 HReg* available_real_regs;
210 Int n_available_real_regs;
sewardj443cd9d2004-07-18 23:06:45 +0000211 Bool (*isMove) (HInstr*, HReg*, HReg*);
212 void (*getRegUsage) (HRegUsage*, HInstr*);
213 void (*mapRegs) (HRegRemap*, HInstr*);
214 HInstr* (*genSpill) ( HReg, Int );
215 HInstr* (*genReload) ( HReg, Int );
216 void (*ppInstr) ( HInstr* );
217 void (*ppReg) ( HReg );
sewardj27e1dd62005-06-30 11:49:14 +0000218 HInstrArray* (*iselBB) ( IRBB*, VexArchInfo* );
sewardj81bd5502004-07-21 18:49:27 +0000219 Int (*emit) ( UChar*, Int, HInstr* );
sewardjd9763622005-02-07 03:12:19 +0000220 IRExpr* (*specHelper) ( HChar*, IRExpr** );
sewardj8d2291c2004-10-25 14:50:21 +0000221 Bool (*preciseMemExnsFn) ( Int, Int );
sewardjf13a16a2004-07-05 17:10:14 +0000222
sewardj9e6491a2005-07-02 19:24:10 +0000223 DisOneInstrFn disInstrFn;
224
sewardjeeac8412004-11-02 00:26:55 +0000225 VexGuestLayout* guest_layout;
226 Bool host_is_bigendian = False;
227 IRBB* irbb;
228 HInstrArray* vcode;
229 HInstrArray* rcode;
230 Int i, j, k, out_used, guest_sizeB;
sewardjdb4738a2005-07-07 01:32:16 +0000231 Int offB_TISTART, offB_TILEN;
sewardjeeac8412004-11-02 00:26:55 +0000232 UChar insn_bytes[32];
sewardjcf787902004-11-03 09:08:33 +0000233 IRType guest_word_type;
234 IRType host_word_type;
sewardjf13a16a2004-07-05 17:10:14 +0000235
sewardj49651f42004-10-28 22:11:04 +0000236 guest_layout = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000237 available_real_regs = NULL;
238 n_available_real_regs = 0;
239 isMove = NULL;
240 getRegUsage = NULL;
241 mapRegs = NULL;
242 genSpill = NULL;
243 genReload = NULL;
244 ppInstr = NULL;
245 ppReg = NULL;
246 iselBB = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000247 emit = NULL;
sewardj84ff0652004-08-23 16:16:08 +0000248 specHelper = NULL;
sewardj8d2291c2004-10-25 14:50:21 +0000249 preciseMemExnsFn = NULL;
sewardj9e6491a2005-07-02 19:24:10 +0000250 disInstrFn = NULL;
sewardjcf787902004-11-03 09:08:33 +0000251 guest_word_type = Ity_INVALID;
252 host_word_type = Ity_INVALID;
sewardjdb4738a2005-07-07 01:32:16 +0000253 offB_TISTART = 0;
254 offB_TILEN = 0;
sewardj36ca5132004-07-24 13:12:23 +0000255
sewardjf48ac192004-10-29 00:41:29 +0000256 vex_traceflags = traceflags;
sewardj58800ff2004-07-28 01:51:10 +0000257
sewardj35421a32004-07-05 13:12:34 +0000258 vassert(vex_initdone);
sewardjd887b862005-01-17 18:34:34 +0000259 vexClearTEMP();
sewardjf13a16a2004-07-05 17:10:14 +0000260
sewardj2a9ad022004-11-25 02:46:58 +0000261
sewardjf13a16a2004-07-05 17:10:14 +0000262 /* First off, check that the guest and host insn sets
263 are supported. */
sewardj2a9ad022004-11-25 02:46:58 +0000264
sewardjbef170b2004-12-21 01:23:00 +0000265 switch (arch_host) {
sewardj2a9ad022004-11-25 02:46:58 +0000266
sewardjbef170b2004-12-21 01:23:00 +0000267 case VexArchX86:
sewardjf13a16a2004-07-05 17:10:14 +0000268 getAllocableRegs_X86 ( &n_available_real_regs,
269 &available_real_regs );
270 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_X86Instr;
271 getRegUsage = (void(*)(HRegUsage*,HInstr*)) getRegUsage_X86Instr;
272 mapRegs = (void(*)(HRegRemap*,HInstr*)) mapRegs_X86Instr;
273 genSpill = (HInstr*(*)(HReg,Int)) genSpill_X86;
274 genReload = (HInstr*(*)(HReg,Int)) genReload_X86;
sewardj2b515872004-07-05 20:50:45 +0000275 ppInstr = (void(*)(HInstr*)) ppX86Instr;
276 ppReg = (void(*)(HReg)) ppHRegX86;
sewardjf13a16a2004-07-05 17:10:14 +0000277 iselBB = iselBB_X86;
sewardj81bd5502004-07-21 18:49:27 +0000278 emit = (Int(*)(UChar*,Int,HInstr*)) emit_X86Instr;
sewardj72c72812005-01-19 11:49:45 +0000279 host_is_bigendian = False;
sewardjcf787902004-11-03 09:08:33 +0000280 host_word_type = Ity_I32;
sewardj27e1dd62005-06-30 11:49:14 +0000281 vassert(archinfo_host->subarch == VexSubArchX86_sse0
282 || archinfo_host->subarch == VexSubArchX86_sse1
283 || archinfo_host->subarch == VexSubArchX86_sse2);
sewardjf13a16a2004-07-05 17:10:14 +0000284 break;
sewardj2a9ad022004-11-25 02:46:58 +0000285
sewardjc33671d2005-02-01 20:30:00 +0000286 case VexArchAMD64:
287 getAllocableRegs_AMD64 ( &n_available_real_regs,
288 &available_real_regs );
289 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_AMD64Instr;
290 getRegUsage = (void(*)(HRegUsage*,HInstr*)) getRegUsage_AMD64Instr;
291 mapRegs = (void(*)(HRegRemap*,HInstr*)) mapRegs_AMD64Instr;
292 genSpill = (HInstr*(*)(HReg,Int)) genSpill_AMD64;
293 genReload = (HInstr*(*)(HReg,Int)) genReload_AMD64;
294 ppInstr = (void(*)(HInstr*)) ppAMD64Instr;
295 ppReg = (void(*)(HReg)) ppHRegAMD64;
296 iselBB = iselBB_AMD64;
297 emit = (Int(*)(UChar*,Int,HInstr*)) emit_AMD64Instr;
298 host_is_bigendian = False;
299 host_word_type = Ity_I64;
sewardj27e1dd62005-06-30 11:49:14 +0000300 vassert(archinfo_host->subarch == VexSubArch_NONE);
sewardjc33671d2005-02-01 20:30:00 +0000301 break;
302
cerion487e4c92005-02-04 16:28:19 +0000303 case VexArchPPC32:
304 getAllocableRegs_PPC32 ( &n_available_real_regs,
305 &available_real_regs );
306 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_PPC32Instr;
307 getRegUsage = (void(*)(HRegUsage*,HInstr*)) getRegUsage_PPC32Instr;
308 mapRegs = (void(*)(HRegRemap*,HInstr*)) mapRegs_PPC32Instr;
309 genSpill = (HInstr*(*)(HReg,Int)) genSpill_PPC32;
310 genReload = (HInstr*(*)(HReg,Int)) genReload_PPC32;
311 ppInstr = (void(*)(HInstr*)) ppPPC32Instr;
312 ppReg = (void(*)(HReg)) ppHRegPPC32;
313 iselBB = iselBB_PPC32;
314 emit = (Int(*)(UChar*,Int,HInstr*)) emit_PPC32Instr;
315 host_is_bigendian = True;
316 host_word_type = Ity_I32;
sewardj27e1dd62005-06-30 11:49:14 +0000317 vassert(archinfo_guest->subarch == VexSubArchPPC32_noAV
318 || archinfo_guest->subarch == VexSubArchPPC32_AV);
cerion487e4c92005-02-04 16:28:19 +0000319 break;
320
sewardjf13a16a2004-07-05 17:10:14 +0000321 default:
sewardj887a11a2004-07-05 17:26:47 +0000322 vpanic("LibVEX_Translate: unsupported target insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000323 }
324
sewardj2a9ad022004-11-25 02:46:58 +0000325
sewardjbef170b2004-12-21 01:23:00 +0000326 switch (arch_guest) {
sewardj2a9ad022004-11-25 02:46:58 +0000327
sewardjbef170b2004-12-21 01:23:00 +0000328 case VexArchX86:
sewardj8d2291c2004-10-25 14:50:21 +0000329 preciseMemExnsFn = guest_x86_state_requires_precise_mem_exns;
sewardj9e6491a2005-07-02 19:24:10 +0000330 disInstrFn = disInstr_X86;
sewardj2a9ad022004-11-25 02:46:58 +0000331 specHelper = guest_x86_spechelper;
sewardj81ec4182004-10-25 23:15:52 +0000332 guest_sizeB = sizeof(VexGuestX86State);
sewardjcf787902004-11-03 09:08:33 +0000333 guest_word_type = Ity_I32;
sewardj49651f42004-10-28 22:11:04 +0000334 guest_layout = &x86guest_layout;
sewardjdb4738a2005-07-07 01:32:16 +0000335 offB_TISTART = offsetof(VexGuestX86State,guest_TISTART);
336 offB_TILEN = offsetof(VexGuestX86State,guest_TILEN);
sewardj27e1dd62005-06-30 11:49:14 +0000337 vassert(archinfo_guest->subarch == VexSubArchX86_sse0
338 || archinfo_guest->subarch == VexSubArchX86_sse1
339 || archinfo_guest->subarch == VexSubArchX86_sse2);
sewardje74f6f72005-08-05 02:55:36 +0000340 vassert(0 == sizeof(VexGuestX86State) % 8);
sewardjdb4738a2005-07-07 01:32:16 +0000341 vassert(sizeof( ((VexGuestX86State*)0)->guest_TISTART ) == 4);
342 vassert(sizeof( ((VexGuestX86State*)0)->guest_TILEN ) == 4);
sewardjf13a16a2004-07-05 17:10:14 +0000343 break;
sewardj2a9ad022004-11-25 02:46:58 +0000344
sewardj44d494d2005-01-20 20:26:33 +0000345 case VexArchAMD64:
346 preciseMemExnsFn = guest_amd64_state_requires_precise_mem_exns;
sewardj9e6491a2005-07-02 19:24:10 +0000347 disInstrFn = disInstr_AMD64;
sewardj44d494d2005-01-20 20:26:33 +0000348 specHelper = guest_amd64_spechelper;
349 guest_sizeB = sizeof(VexGuestAMD64State);
350 guest_word_type = Ity_I64;
351 guest_layout = &amd64guest_layout;
sewardjdb4738a2005-07-07 01:32:16 +0000352 offB_TISTART = offsetof(VexGuestAMD64State,guest_TISTART);
353 offB_TILEN = offsetof(VexGuestAMD64State,guest_TILEN);
sewardj27e1dd62005-06-30 11:49:14 +0000354 vassert(archinfo_guest->subarch == VexSubArch_NONE);
sewardje74f6f72005-08-05 02:55:36 +0000355 vassert(0 == sizeof(VexGuestAMD64State) % 8);
sewardjdb4738a2005-07-07 01:32:16 +0000356 vassert(sizeof( ((VexGuestAMD64State*)0)->guest_TISTART ) == 8);
357 vassert(sizeof( ((VexGuestAMD64State*)0)->guest_TILEN ) == 8);
sewardj44d494d2005-01-20 20:26:33 +0000358 break;
359
sewardjbef170b2004-12-21 01:23:00 +0000360 case VexArchARM:
sewardj2a9ad022004-11-25 02:46:58 +0000361 preciseMemExnsFn = guest_arm_state_requires_precise_mem_exns;
sewardj9e6491a2005-07-02 19:24:10 +0000362 disInstrFn = NULL; /* HACK */
sewardj2a9ad022004-11-25 02:46:58 +0000363 specHelper = guest_arm_spechelper;
364 guest_sizeB = sizeof(VexGuestARMState);
365 guest_word_type = Ity_I32;
366 guest_layout = &armGuest_layout;
sewardjdb4738a2005-07-07 01:32:16 +0000367 offB_TISTART = 0; /* hack ... arm has bitrot */
368 offB_TILEN = 0; /* hack ... arm has bitrot */
sewardj27e1dd62005-06-30 11:49:14 +0000369 vassert(archinfo_guest->subarch == VexSubArchARM_v4);
sewardj2a9ad022004-11-25 02:46:58 +0000370 break;
371
cerionaabdfbf2005-01-29 12:56:15 +0000372 case VexArchPPC32:
373 preciseMemExnsFn = guest_ppc32_state_requires_precise_mem_exns;
sewardj9e6491a2005-07-02 19:24:10 +0000374 disInstrFn = disInstr_PPC32;
cerionaabdfbf2005-01-29 12:56:15 +0000375 specHelper = guest_ppc32_spechelper;
376 guest_sizeB = sizeof(VexGuestPPC32State);
377 guest_word_type = Ity_I32;
378 guest_layout = &ppc32Guest_layout;
sewardjdb4738a2005-07-07 01:32:16 +0000379 offB_TISTART = offsetof(VexGuestPPC32State,guest_TISTART);
380 offB_TILEN = offsetof(VexGuestPPC32State,guest_TILEN);
sewardj27e1dd62005-06-30 11:49:14 +0000381 vassert(archinfo_guest->subarch == VexSubArchPPC32_noAV
382 || archinfo_guest->subarch == VexSubArchPPC32_AV);
sewardje74f6f72005-08-05 02:55:36 +0000383 vassert(0 == sizeof(VexGuestPPC32State) % 8);
sewardjdb4738a2005-07-07 01:32:16 +0000384 vassert(sizeof( ((VexGuestPPC32State*)0)->guest_TISTART ) == 4);
385 vassert(sizeof( ((VexGuestPPC32State*)0)->guest_TILEN ) == 4);
cerionaabdfbf2005-01-29 12:56:15 +0000386 break;
387
sewardjf13a16a2004-07-05 17:10:14 +0000388 default:
sewardj887a11a2004-07-05 17:26:47 +0000389 vpanic("LibVEX_Translate: unsupported guest insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000390 }
391
sewardj9df271d2004-12-31 22:37:42 +0000392 /* yet more sanity checks ... */
sewardj0ec57c52005-02-01 15:24:10 +0000393 if (arch_guest == arch_host) {
sewardj9df271d2004-12-31 22:37:42 +0000394 /* doesn't necessarily have to be true, but if it isn't it means
sewardj0ec57c52005-02-01 15:24:10 +0000395 we are simulating one flavour of an architecture a different
396 flavour of the same architecture, which is pretty strange. */
sewardj27e1dd62005-06-30 11:49:14 +0000397 vassert(archinfo_guest->subarch == archinfo_host->subarch);
sewardj9df271d2004-12-31 22:37:42 +0000398 }
sewardj2a9ad022004-11-25 02:46:58 +0000399
sewardjf48ac192004-10-29 00:41:29 +0000400 if (vex_traceflags & VEX_TRACE_FE)
401 vex_printf("\n------------------------"
402 " Front end "
403 "------------------------\n\n");
404
sewardj9e6491a2005-07-02 19:24:10 +0000405 irbb = bb_to_IR ( guest_extents,
406 disInstrFn,
407 guest_bytes,
408 guest_bytes_addr,
409 chase_into_ok,
410 host_is_bigendian,
411 archinfo_guest,
sewardjdb4738a2005-07-07 01:32:16 +0000412 guest_word_type,
sewardjec3c8852005-07-07 09:56:24 +0000413 do_self_check,
sewardjdb4738a2005-07-07 01:32:16 +0000414 offB_TISTART,
415 offB_TILEN );
sewardjf13a16a2004-07-05 17:10:14 +0000416
417 if (irbb == NULL) {
418 /* Access failure. */
sewardjd887b862005-01-17 18:34:34 +0000419 vexClearTEMP();
sewardjf48ac192004-10-29 00:41:29 +0000420 vex_traceflags = 0;
sewardjd887b862005-01-17 18:34:34 +0000421 return VexTransAccessFail;
sewardjf13a16a2004-07-05 17:10:14 +0000422 }
sewardjaa59f942004-10-09 09:34:36 +0000423
sewardj72c72812005-01-19 11:49:45 +0000424 vassert(guest_extents->n_used >= 1 && guest_extents->n_used <= 3);
425 vassert(guest_extents->base[0] == guest_bytes_addr);
426 for (i = 0; i < guest_extents->n_used; i++) {
427 vassert(guest_extents->len[i] < 10000); /* sanity */
428 }
429
sewardjaa59f942004-10-09 09:34:36 +0000430 /* If debugging, show the raw guest bytes for this bb. */
sewardj109ffdb2004-12-10 21:45:38 +0000431 if (0 || (vex_traceflags & VEX_TRACE_FE)) {
sewardj72c72812005-01-19 11:49:45 +0000432 if (guest_extents->n_used > 1) {
433 vex_printf("can't show code due to extents > 1\n");
434 } else {
435 /* HACK */
436 UChar* p = (UChar*)guest_bytes;
437 UInt guest_bytes_read = (UInt)guest_extents->len[0];
sewardjd9763622005-02-07 03:12:19 +0000438 vex_printf(". 0 %llx %u\n.", guest_bytes_addr, guest_bytes_read );
sewardj72c72812005-01-19 11:49:45 +0000439 for (i = 0; i < guest_bytes_read; i++)
sewardjaa59f942004-10-09 09:34:36 +0000440 vex_printf(" %02x", (Int)p[i] );
sewardj72c72812005-01-19 11:49:45 +0000441 vex_printf("\n\n");
442 }
sewardjaa59f942004-10-09 09:34:36 +0000443 }
444
445 /* Sanity check the initial IR. */
sewardjb9230752004-12-29 19:25:06 +0000446 sanityCheckIRBB( irbb, "initial IR",
447 False/*can be non-flat*/, guest_word_type );
sewardje8e9d732004-07-16 21:03:45 +0000448
sewardjedf4d692004-08-17 13:52:58 +0000449 /* Clean it up, hopefully a lot. */
sewardj8d2291c2004-10-25 14:50:21 +0000450 irbb = do_iropt_BB ( irbb, specHelper, preciseMemExnsFn,
451 guest_bytes_addr );
sewardjb9230752004-12-29 19:25:06 +0000452 sanityCheckIRBB( irbb, "after initial iropt",
453 True/*must be flat*/, guest_word_type );
sewardjedf4d692004-08-17 13:52:58 +0000454
sewardjf48ac192004-10-29 00:41:29 +0000455 if (vex_traceflags & VEX_TRACE_OPT1) {
456 vex_printf("\n------------------------"
457 " After pre-instr IR optimisation "
458 "------------------------\n\n");
sewardjedf4d692004-08-17 13:52:58 +0000459 ppIRBB ( irbb );
460 vex_printf("\n");
461 }
462
sewardjf13a16a2004-07-05 17:10:14 +0000463 /* Get the thing instrumented. */
sewardj49651f42004-10-28 22:11:04 +0000464 if (instrument1)
sewardj918c8f32005-03-21 00:54:33 +0000465 irbb = (*instrument1)(irbb, guest_layout,
466 guest_word_type, host_word_type);
sewardj49651f42004-10-28 22:11:04 +0000467 if (instrument2)
sewardj918c8f32005-03-21 00:54:33 +0000468 irbb = (*instrument2)(irbb, guest_layout,
469 guest_word_type, host_word_type);
sewardj49651f42004-10-28 22:11:04 +0000470
sewardjf48ac192004-10-29 00:41:29 +0000471 if (vex_traceflags & VEX_TRACE_INST) {
472 vex_printf("\n------------------------"
473 " After instrumentation "
474 "------------------------\n\n");
475 ppIRBB ( irbb );
476 vex_printf("\n");
477 }
478
sewardj49651f42004-10-28 22:11:04 +0000479 if (instrument1 || instrument2)
sewardjb9230752004-12-29 19:25:06 +0000480 sanityCheckIRBB( irbb, "after instrumentation",
481 True/*must be flat*/, guest_word_type );
sewardjf13a16a2004-07-05 17:10:14 +0000482
sewardj9578a8b2004-11-04 19:44:48 +0000483 /* Do a post-instrumentation cleanup pass. */
484 if (cleanup_after_instrumentation) {
485 do_deadcode_BB( irbb );
486 irbb = cprop_BB( irbb );
487 do_deadcode_BB( irbb );
sewardjb9230752004-12-29 19:25:06 +0000488 sanityCheckIRBB( irbb, "after post-instrumentation cleanup",
489 True/*must be flat*/, guest_word_type );
sewardj9578a8b2004-11-04 19:44:48 +0000490 }
491
492 if (vex_traceflags & VEX_TRACE_OPT2) {
493 vex_printf("\n------------------------"
494 " After post-instr IR optimisation "
495 "------------------------\n\n");
496 ppIRBB ( irbb );
497 vex_printf("\n");
498 }
499
sewardjf13a16a2004-07-05 17:10:14 +0000500 /* Turn it into virtual-registerised code. */
sewardj49651f42004-10-28 22:11:04 +0000501 do_deadcode_BB( irbb );
502 do_treebuild_BB( irbb );
sewardjf48ac192004-10-29 00:41:29 +0000503
504 if (vex_traceflags & VEX_TRACE_TREES) {
505 vex_printf("\n------------------------"
506 " After tree-building "
507 "------------------------\n\n");
508 ppIRBB ( irbb );
509 vex_printf("\n");
510 }
511
sewardje908c422005-02-04 21:18:16 +0000512 /* HACK */
cerion54560812005-02-03 13:40:49 +0000513 if (0) { *host_bytes_used = 0; return VexTransOK; }
sewardje908c422005-02-04 21:18:16 +0000514 /* end HACK */
sewardjc33671d2005-02-01 20:30:00 +0000515
sewardjf48ac192004-10-29 00:41:29 +0000516 if (vex_traceflags & VEX_TRACE_VCODE)
517 vex_printf("\n------------------------"
518 " Instruction selection "
519 "------------------------\n");
520
sewardj27e1dd62005-06-30 11:49:14 +0000521 vcode = iselBB ( irbb, archinfo_host );
sewardjf13a16a2004-07-05 17:10:14 +0000522
sewardjf48ac192004-10-29 00:41:29 +0000523 if (vex_traceflags & VEX_TRACE_VCODE)
524 vex_printf("\n");
525
sewardjf48ac192004-10-29 00:41:29 +0000526 if (vex_traceflags & VEX_TRACE_VCODE) {
sewardj1f40a0a2004-07-21 12:28:07 +0000527 for (i = 0; i < vcode->arr_used; i++) {
528 vex_printf("%3d ", i);
529 ppInstr(vcode->arr[i]);
530 vex_printf("\n");
531 }
sewardjfbcaf332004-07-08 01:46:01 +0000532 vex_printf("\n");
533 }
sewardjfbcaf332004-07-08 01:46:01 +0000534
sewardjf13a16a2004-07-05 17:10:14 +0000535 /* Register allocate. */
536 rcode = doRegisterAllocation ( vcode, available_real_regs,
sewardj72c72812005-01-19 11:49:45 +0000537 n_available_real_regs,
538 isMove, getRegUsage, mapRegs,
539 genSpill, genReload, guest_sizeB,
540 ppInstr, ppReg );
sewardjf13a16a2004-07-05 17:10:14 +0000541
sewardjf48ac192004-10-29 00:41:29 +0000542 if (vex_traceflags & VEX_TRACE_RCODE) {
543 vex_printf("\n------------------------"
544 " Register-allocated code "
545 "------------------------\n\n");
sewardj1f40a0a2004-07-21 12:28:07 +0000546 for (i = 0; i < rcode->arr_used; i++) {
547 vex_printf("%3d ", i);
548 ppInstr(rcode->arr[i]);
549 vex_printf("\n");
550 }
sewardjfbcaf332004-07-08 01:46:01 +0000551 vex_printf("\n");
552 }
sewardjfbcaf332004-07-08 01:46:01 +0000553
sewardje908c422005-02-04 21:18:16 +0000554 /* HACK */
555 if (0) { *host_bytes_used = 0; return VexTransOK; }
556 /* end HACK */
557
sewardj81bd5502004-07-21 18:49:27 +0000558 /* Assemble */
sewardjf48ac192004-10-29 00:41:29 +0000559 if (vex_traceflags & VEX_TRACE_ASM) {
560 vex_printf("\n------------------------"
561 " Assembly "
562 "------------------------\n\n");
563 }
564
sewardj81bd5502004-07-21 18:49:27 +0000565 out_used = 0; /* tracks along the host_bytes array */
566 for (i = 0; i < rcode->arr_used; i++) {
sewardjf48ac192004-10-29 00:41:29 +0000567 if (vex_traceflags & VEX_TRACE_ASM) {
sewardjbad34a92004-07-22 01:14:11 +0000568 ppInstr(rcode->arr[i]);
569 vex_printf("\n");
570 }
sewardj81bd5502004-07-21 18:49:27 +0000571 j = (*emit)( insn_bytes, 32, rcode->arr[i] );
sewardjf48ac192004-10-29 00:41:29 +0000572 if (vex_traceflags & VEX_TRACE_ASM) {
sewardjbad34a92004-07-22 01:14:11 +0000573 for (k = 0; k < j; k++)
sewardj72c72812005-01-19 11:49:45 +0000574 if (insn_bytes[k] < 16)
sewardj86898e82004-07-22 17:26:12 +0000575 vex_printf("0%x ", (UInt)insn_bytes[k]);
576 else
577 vex_printf("%x ", (UInt)insn_bytes[k]);
sewardjbad34a92004-07-22 01:14:11 +0000578 vex_printf("\n\n");
579 }
sewardj81bd5502004-07-21 18:49:27 +0000580 if (out_used + j > host_bytes_size) {
sewardjd887b862005-01-17 18:34:34 +0000581 vexClearTEMP();
sewardjf48ac192004-10-29 00:41:29 +0000582 vex_traceflags = 0;
sewardjd887b862005-01-17 18:34:34 +0000583 return VexTransOutputFull;
sewardj81bd5502004-07-21 18:49:27 +0000584 }
585 for (k = 0; k < j; k++) {
586 host_bytes[out_used] = insn_bytes[k];
587 out_used++;
588 }
589 vassert(out_used <= host_bytes_size);
590 }
591 *host_bytes_used = out_used;
592
sewardjd887b862005-01-17 18:34:34 +0000593 vexClearTEMP();
sewardjf13a16a2004-07-05 17:10:14 +0000594
sewardjf48ac192004-10-29 00:41:29 +0000595 vex_traceflags = 0;
sewardjd887b862005-01-17 18:34:34 +0000596 return VexTransOK;
sewardj35421a32004-07-05 13:12:34 +0000597}
598
599
sewardj893aada2004-11-29 19:57:54 +0000600/* --------- Emulation warnings. --------- */
601
602HChar* LibVEX_EmWarn_string ( VexEmWarn ew )
603{
604 switch (ew) {
605 case EmWarn_NONE:
606 return "none";
607 case EmWarn_X86_x87exns:
608 return "Unmasking x87 FP exceptions";
sewardj893aada2004-11-29 19:57:54 +0000609 case EmWarn_X86_x87precision:
610 return "Selection of non-80-bit x87 FP precision";
611 case EmWarn_X86_sseExns:
sewardj5edfc262004-12-15 12:13:52 +0000612 return "Unmasking SSE FP exceptions";
613 case EmWarn_X86_fz:
614 return "Setting %mxcsr.fz (SSE flush-underflows-to-zero mode)";
615 case EmWarn_X86_daz:
616 return "Setting %mxcsr.daz (SSE treat-denormals-as-zero mode)";
sewardj6d269842005-08-06 11:45:02 +0000617 case EmWarn_X86_acFlag:
618 return "Setting %eflags.ac (setting noted but ignored)";
cerion094d1392005-06-20 13:45:57 +0000619 case EmWarn_PPC32exns:
620 return "Unmasking PPC32 FP exceptions";
sewardj893aada2004-11-29 19:57:54 +0000621 default:
622 vpanic("LibVEX_EmWarn_string: unknown warning");
623 }
624}
sewardj35421a32004-07-05 13:12:34 +0000625
sewardj27e1dd62005-06-30 11:49:14 +0000626/* --------- Arch/Subarch stuff. --------- */
sewardjbef170b2004-12-21 01:23:00 +0000627
628const HChar* LibVEX_ppVexArch ( VexArch arch )
629{
630 switch (arch) {
631 case VexArch_INVALID: return "INVALID";
632 case VexArchX86: return "X86";
633 case VexArchAMD64: return "AMD64";
634 case VexArchARM: return "ARM";
sewardj0ec57c52005-02-01 15:24:10 +0000635 case VexArchPPC32: return "PPC32";
sewardjbef170b2004-12-21 01:23:00 +0000636 default: return "VexArch???";
637 }
638}
639
640const HChar* LibVEX_ppVexSubArch ( VexSubArch subarch )
641{
642 switch (subarch) {
sewardj0ec57c52005-02-01 15:24:10 +0000643 case VexSubArch_INVALID: return "INVALID";
644 case VexSubArch_NONE: return "NONE";
645 case VexSubArchX86_sse0: return "x86-sse0";
646 case VexSubArchX86_sse1: return "x86-sse1";
647 case VexSubArchX86_sse2: return "x86-sse2";
648 case VexSubArchARM_v4: return "arm-v4";
649 case VexSubArchPPC32_noAV: return "ppc32-noAltivec";
650 case VexSubArchPPC32_AV: return "ppc32-Altivec";
651 default: return "VexSubArch???";
sewardjbef170b2004-12-21 01:23:00 +0000652 }
653}
654
sewardj27e1dd62005-06-30 11:49:14 +0000655/* Write default settings info *vai. */
656void LibVEX_default_VexArchInfo ( /*OUT*/VexArchInfo* vai )
657{
658 vai->subarch = VexSubArch_INVALID;
659 vai->ppc32_cache_line_szB = 0;
660}
661
662
sewardj35421a32004-07-05 13:12:34 +0000663/*---------------------------------------------------------------*/
sewardjc0ee2ed2004-07-27 10:29:41 +0000664/*--- end main/vex_main.c ---*/
sewardj35421a32004-07-05 13:12:34 +0000665/*---------------------------------------------------------------*/