blob: 9c1d9b2a104d34ede5513f90510b653d5a5342b0 [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 ---*/
sewardj35421a32004-07-05 13:12:34 +00005/*--- Copyright (c) 2004 OpenWorks LLP. All rights reserved. ---*/
6/*--- ---*/
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
13 Copyright (C) 2004 OpenWorks, LLP.
14
15 This program is free software; you can redistribute it and/or modify
16 it under the terms of the GNU General Public License as published by
17 the Free Software Foundation; Version 2 dated June 1991 of the
18 license.
19
20 This program is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or liability
23 for damages. See the GNU General Public License for more details.
24
25 Neither the names of the U.S. Department of Energy nor the
26 University of California nor the names of its contributors may be
27 used to endorse or promote products derived from this software
28 without prior written permission.
29
30 You should have received a copy of the GNU General Public License
31 along with this program; if not, write to the Free Software
32 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
33 USA.
34*/
35
sewardj887a11a2004-07-05 17:26:47 +000036#include "libvex.h"
sewardj893aada2004-11-29 19:57:54 +000037#include "libvex_emwarn.h"
sewardj81ec4182004-10-25 23:15:52 +000038#include "libvex_guest_x86.h"
sewardj44d494d2005-01-20 20:26:33 +000039#include "libvex_guest_amd64.h"
sewardj2a9ad022004-11-25 02:46:58 +000040#include "libvex_guest_arm.h"
cerionaabdfbf2005-01-29 12:56:15 +000041#include "libvex_guest_ppc32.h"
sewardjf13a16a2004-07-05 17:10:14 +000042
sewardjc0ee2ed2004-07-27 10:29:41 +000043#include "main/vex_globals.h"
44#include "main/vex_util.h"
45#include "host-generic/h_generic_regs.h"
sewardjedf4d692004-08-17 13:52:58 +000046#include "ir/iropt.h"
sewardj35421a32004-07-05 13:12:34 +000047
sewardj2a9ad022004-11-25 02:46:58 +000048#include "host-x86/hdefs.h"
sewardjc33671d2005-02-01 20:30:00 +000049#include "host-amd64/hdefs.h"
cerion487e4c92005-02-04 16:28:19 +000050#include "host-ppc32/hdefs.h"
sewardj2a9ad022004-11-25 02:46:58 +000051
52#include "guest-x86/gdefs.h"
sewardj44d494d2005-01-20 20:26:33 +000053#include "guest-amd64/gdefs.h"
sewardj2a9ad022004-11-25 02:46:58 +000054#include "guest-arm/gdefs.h"
cerionaabdfbf2005-01-29 12:56:15 +000055#include "guest-ppc32/gdefs.h"
sewardj2a9ad022004-11-25 02:46:58 +000056
sewardj35421a32004-07-05 13:12:34 +000057
58/* This file contains the top level interface to the library. */
59
60/* --------- Initialise the library. --------- */
61
62/* Exported to library client. */
63
sewardjd887b862005-01-17 18:34:34 +000064const HChar* LibVEX_Version ( void )
sewardj80f5fce2004-12-20 04:37:50 +000065{
66return
67#include "main/vex_svnversion.h"
68 ;
69}
70
71
72/* Exported to library client. */
73
sewardj08613742004-10-25 13:01:45 +000074void LibVEX_default_VexControl ( /*OUT*/ VexControl* vcon )
75{
76 vcon->iropt_verbosity = 0;
77 vcon->iropt_level = 2;
78 vcon->iropt_precise_memory_exns = False;
79 vcon->iropt_unroll_thresh = 120;
80 vcon->guest_max_insns = 50;
81 vcon->guest_chase_thresh = 10;
82}
83
84
85/* Exported to library client. */
86
sewardj887a11a2004-07-05 17:26:47 +000087void LibVEX_Init (
sewardj35421a32004-07-05 13:12:34 +000088 /* failure exit function */
sewardj2b515872004-07-05 20:50:45 +000089 __attribute__ ((noreturn))
sewardj35421a32004-07-05 13:12:34 +000090 void (*failure_exit) ( void ),
91 /* logging output function */
92 void (*log_bytes) ( Char*, Int nbytes ),
93 /* debug paranoia level */
94 Int debuglevel,
sewardj35421a32004-07-05 13:12:34 +000095 /* Are we supporting valgrind checking? */
96 Bool valgrind_support,
sewardj08613742004-10-25 13:01:45 +000097 /* Control ... */
98 /*READONLY*/VexControl* vcon
sewardj35421a32004-07-05 13:12:34 +000099)
100{
sewardj08613742004-10-25 13:01:45 +0000101 /* First off, do enough minimal setup so that the following
102 assertions can fail in a sane fashion, if need be. */
sewardjea602bc2004-10-14 21:40:12 +0000103 vex_failure_exit = failure_exit;
104 vex_log_bytes = log_bytes;
105
106 /* Now it's safe to check parameters for sanity. */
sewardj35421a32004-07-05 13:12:34 +0000107 vassert(!vex_initdone);
108 vassert(failure_exit);
sewardj35421a32004-07-05 13:12:34 +0000109 vassert(log_bytes);
sewardj35421a32004-07-05 13:12:34 +0000110 vassert(debuglevel >= 0);
sewardj08613742004-10-25 13:01:45 +0000111
112 vassert(vcon->iropt_verbosity >= 0);
113 vassert(vcon->iropt_level >= 0);
114 vassert(vcon->iropt_level <= 2);
115 vassert(vcon->iropt_unroll_thresh >= 0);
116 vassert(vcon->iropt_unroll_thresh <= 400);
117 vassert(vcon->guest_max_insns >= 1);
118 vassert(vcon->guest_max_insns <= 100);
119 vassert(vcon->guest_chase_thresh >= 0);
120 vassert(vcon->guest_chase_thresh < vcon->guest_max_insns);
sewardj443cd9d2004-07-18 23:06:45 +0000121
sewardj81ec4182004-10-25 23:15:52 +0000122 /* All the guest state structs must have an 8-aligned size. */
123 vassert(0 == sizeof(VexGuestX86State) % 8);
124
sewardjea602bc2004-10-14 21:40:12 +0000125 /* Check that Vex has been built with sizes of basic types as
126 stated in priv/libvex_basictypes.h. Failure of any of these is
127 a serious configuration error and should be corrected
128 immediately. If any of these assertions fail you can fully
129 expect Vex not to work properly, if at all. */
130
131 vassert(1 == sizeof(UChar));
132 vassert(1 == sizeof(Char));
133 vassert(2 == sizeof(UShort));
134 vassert(2 == sizeof(Short));
135 vassert(4 == sizeof(UInt));
136 vassert(4 == sizeof(Int));
137 vassert(8 == sizeof(ULong));
138 vassert(8 == sizeof(Long));
139 vassert(4 == sizeof(Float));
140 vassert(8 == sizeof(Double));
141 vassert(1 == sizeof(Bool));
142 vassert(4 == sizeof(Addr32));
143 vassert(8 == sizeof(Addr64));
sewardjc9a43662004-11-30 18:51:59 +0000144 vassert(16 == sizeof(U128));
sewardjea602bc2004-10-14 21:40:12 +0000145
146 vassert(sizeof(void*) == 4 || sizeof(void*) == 8);
147 vassert(sizeof(void*) == sizeof(int*));
148 vassert(sizeof(void*) == sizeof(HWord));
149
150 /* Really start up .. */
sewardj443cd9d2004-07-18 23:06:45 +0000151 vex_debuglevel = debuglevel;
sewardj443cd9d2004-07-18 23:06:45 +0000152 vex_valgrind_support = valgrind_support;
sewardj08613742004-10-25 13:01:45 +0000153 vex_control = *vcon;
sewardj443cd9d2004-07-18 23:06:45 +0000154 vex_initdone = True;
sewardjd887b862005-01-17 18:34:34 +0000155 vexSetAllocMode ( VexAllocModeTEMP );
sewardj35421a32004-07-05 13:12:34 +0000156}
157
158
159/* --------- Make a translation. --------- */
160
161/* Exported to library client. */
162
sewardjd887b862005-01-17 18:34:34 +0000163VexTranslateResult LibVEX_Translate (
sewardj35421a32004-07-05 13:12:34 +0000164 /* The instruction sets we are translating from and to. */
sewardjbef170b2004-12-21 01:23:00 +0000165 VexArch arch_guest,
166 VexSubArch subarch_guest,
167 VexArch arch_host,
168 VexSubArch subarch_host,
sewardj35421a32004-07-05 13:12:34 +0000169 /* IN: the block to translate, and its guest address. */
sewardjbef170b2004-12-21 01:23:00 +0000170 UChar* guest_bytes,
171 Addr64 guest_bytes_addr,
172 Bool (*chase_into_ok) ( Addr64 ),
sewardj72c72812005-01-19 11:49:45 +0000173 /* OUT: which bits of guest code actually got translated */
174 VexGuestExtents* guest_extents,
sewardj35421a32004-07-05 13:12:34 +0000175 /* IN: a place to put the resulting code, and its size */
sewardjbef170b2004-12-21 01:23:00 +0000176 UChar* host_bytes,
177 Int host_bytes_size,
sewardj35421a32004-07-05 13:12:34 +0000178 /* OUT: how much of the output area is used. */
sewardjbef170b2004-12-21 01:23:00 +0000179 Int* host_bytes_used,
sewardj49651f42004-10-28 22:11:04 +0000180 /* IN: optionally, two instrumentation functions. */
sewardjbef170b2004-12-21 01:23:00 +0000181 IRBB* (*instrument1) ( IRBB*, VexGuestLayout*, IRType hWordTy ),
182 IRBB* (*instrument2) ( IRBB*, VexGuestLayout*, IRType hWordTy ),
183 Bool cleanup_after_instrumentation,
sewardj35421a32004-07-05 13:12:34 +0000184 /* IN: optionally, an access check function for guest code. */
sewardjbef170b2004-12-21 01:23:00 +0000185 Bool (*byte_accessible) ( Addr64 ),
sewardjf48ac192004-10-29 00:41:29 +0000186 /* IN: debug: trace vex activity at various points */
sewardjbef170b2004-12-21 01:23:00 +0000187 Int traceflags
sewardj35421a32004-07-05 13:12:34 +0000188)
189{
sewardj81bd5502004-07-21 18:49:27 +0000190 /* This the bundle of functions we need to do the back-end stuff
191 (insn selection, reg-alloc, assembly) whilst being insulated
192 from the target instruction set. */
sewardjf13a16a2004-07-05 17:10:14 +0000193 HReg* available_real_regs;
194 Int n_available_real_regs;
sewardj443cd9d2004-07-18 23:06:45 +0000195 Bool (*isMove) (HInstr*, HReg*, HReg*);
196 void (*getRegUsage) (HRegUsage*, HInstr*);
197 void (*mapRegs) (HRegRemap*, HInstr*);
198 HInstr* (*genSpill) ( HReg, Int );
199 HInstr* (*genReload) ( HReg, Int );
200 void (*ppInstr) ( HInstr* );
201 void (*ppReg) ( HReg );
sewardj9df271d2004-12-31 22:37:42 +0000202 HInstrArray* (*iselBB) ( IRBB*, VexSubArch );
sewardj72c72812005-01-19 11:49:45 +0000203 IRBB* (*bbToIR) ( UChar*, Addr64,
204 VexGuestExtents*,
sewardj5bd4d162004-11-10 13:02:48 +0000205 Bool(*)(Addr64),
sewardj72c72812005-01-19 11:49:45 +0000206 Bool(*)(Addr64),
207 Bool, VexSubArch );
sewardj81bd5502004-07-21 18:49:27 +0000208 Int (*emit) ( UChar*, Int, HInstr* );
sewardj84ff0652004-08-23 16:16:08 +0000209 IRExpr* (*specHelper) ( Char*, IRExpr** );
sewardj8d2291c2004-10-25 14:50:21 +0000210 Bool (*preciseMemExnsFn) ( Int, Int );
sewardjf13a16a2004-07-05 17:10:14 +0000211
sewardjeeac8412004-11-02 00:26:55 +0000212 VexGuestLayout* guest_layout;
213 Bool host_is_bigendian = False;
214 IRBB* irbb;
215 HInstrArray* vcode;
216 HInstrArray* rcode;
217 Int i, j, k, out_used, guest_sizeB;
218 UChar insn_bytes[32];
sewardjcf787902004-11-03 09:08:33 +0000219 IRType guest_word_type;
220 IRType host_word_type;
sewardjf13a16a2004-07-05 17:10:14 +0000221
sewardj49651f42004-10-28 22:11:04 +0000222 guest_layout = NULL;
sewardj36ca5132004-07-24 13:12:23 +0000223 available_real_regs = NULL;
224 n_available_real_regs = 0;
225 isMove = NULL;
226 getRegUsage = NULL;
227 mapRegs = NULL;
228 genSpill = NULL;
229 genReload = NULL;
230 ppInstr = NULL;
231 ppReg = NULL;
232 iselBB = NULL;
233 bbToIR = NULL;
234 emit = NULL;
sewardj84ff0652004-08-23 16:16:08 +0000235 specHelper = NULL;
sewardj8d2291c2004-10-25 14:50:21 +0000236 preciseMemExnsFn = NULL;
sewardjcf787902004-11-03 09:08:33 +0000237 guest_word_type = Ity_INVALID;
238 host_word_type = Ity_INVALID;
sewardj36ca5132004-07-24 13:12:23 +0000239
sewardjf48ac192004-10-29 00:41:29 +0000240 vex_traceflags = traceflags;
sewardj58800ff2004-07-28 01:51:10 +0000241
sewardj35421a32004-07-05 13:12:34 +0000242 vassert(vex_initdone);
sewardjd887b862005-01-17 18:34:34 +0000243 vexClearTEMP();
sewardjf13a16a2004-07-05 17:10:14 +0000244
sewardj2a9ad022004-11-25 02:46:58 +0000245
sewardjf13a16a2004-07-05 17:10:14 +0000246 /* First off, check that the guest and host insn sets
247 are supported. */
sewardj2a9ad022004-11-25 02:46:58 +0000248
sewardjbef170b2004-12-21 01:23:00 +0000249 switch (arch_host) {
sewardj2a9ad022004-11-25 02:46:58 +0000250
sewardjbef170b2004-12-21 01:23:00 +0000251 case VexArchX86:
sewardjf13a16a2004-07-05 17:10:14 +0000252 getAllocableRegs_X86 ( &n_available_real_regs,
253 &available_real_regs );
254 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_X86Instr;
255 getRegUsage = (void(*)(HRegUsage*,HInstr*)) getRegUsage_X86Instr;
256 mapRegs = (void(*)(HRegRemap*,HInstr*)) mapRegs_X86Instr;
257 genSpill = (HInstr*(*)(HReg,Int)) genSpill_X86;
258 genReload = (HInstr*(*)(HReg,Int)) genReload_X86;
sewardj2b515872004-07-05 20:50:45 +0000259 ppInstr = (void(*)(HInstr*)) ppX86Instr;
260 ppReg = (void(*)(HReg)) ppHRegX86;
sewardjf13a16a2004-07-05 17:10:14 +0000261 iselBB = iselBB_X86;
sewardj81bd5502004-07-21 18:49:27 +0000262 emit = (Int(*)(UChar*,Int,HInstr*)) emit_X86Instr;
sewardj72c72812005-01-19 11:49:45 +0000263 host_is_bigendian = False;
sewardjcf787902004-11-03 09:08:33 +0000264 host_word_type = Ity_I32;
sewardj9df271d2004-12-31 22:37:42 +0000265 vassert(subarch_host == VexSubArchX86_sse0
266 || subarch_host == VexSubArchX86_sse1
267 || subarch_host == VexSubArchX86_sse2);
sewardjf13a16a2004-07-05 17:10:14 +0000268 break;
sewardj2a9ad022004-11-25 02:46:58 +0000269
sewardjc33671d2005-02-01 20:30:00 +0000270 case VexArchAMD64:
271 getAllocableRegs_AMD64 ( &n_available_real_regs,
272 &available_real_regs );
273 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_AMD64Instr;
274 getRegUsage = (void(*)(HRegUsage*,HInstr*)) getRegUsage_AMD64Instr;
275 mapRegs = (void(*)(HRegRemap*,HInstr*)) mapRegs_AMD64Instr;
276 genSpill = (HInstr*(*)(HReg,Int)) genSpill_AMD64;
277 genReload = (HInstr*(*)(HReg,Int)) genReload_AMD64;
278 ppInstr = (void(*)(HInstr*)) ppAMD64Instr;
279 ppReg = (void(*)(HReg)) ppHRegAMD64;
280 iselBB = iselBB_AMD64;
281 emit = (Int(*)(UChar*,Int,HInstr*)) emit_AMD64Instr;
282 host_is_bigendian = False;
283 host_word_type = Ity_I64;
284 vassert(subarch_host == VexSubArch_NONE);
285 break;
286
cerion487e4c92005-02-04 16:28:19 +0000287 case VexArchPPC32:
288 getAllocableRegs_PPC32 ( &n_available_real_regs,
289 &available_real_regs );
290 isMove = (Bool(*)(HInstr*,HReg*,HReg*)) isMove_PPC32Instr;
291 getRegUsage = (void(*)(HRegUsage*,HInstr*)) getRegUsage_PPC32Instr;
292 mapRegs = (void(*)(HRegRemap*,HInstr*)) mapRegs_PPC32Instr;
293 genSpill = (HInstr*(*)(HReg,Int)) genSpill_PPC32;
294 genReload = (HInstr*(*)(HReg,Int)) genReload_PPC32;
295 ppInstr = (void(*)(HInstr*)) ppPPC32Instr;
296 ppReg = (void(*)(HReg)) ppHRegPPC32;
297 iselBB = iselBB_PPC32;
298 emit = (Int(*)(UChar*,Int,HInstr*)) emit_PPC32Instr;
299 host_is_bigendian = True;
300 host_word_type = Ity_I32;
301 vassert(subarch_guest == VexSubArchPPC32_noAV
302 || subarch_guest == VexSubArchPPC32_AV);
303 break;
304
sewardjf13a16a2004-07-05 17:10:14 +0000305 default:
sewardj887a11a2004-07-05 17:26:47 +0000306 vpanic("LibVEX_Translate: unsupported target insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000307 }
308
sewardj2a9ad022004-11-25 02:46:58 +0000309
sewardjbef170b2004-12-21 01:23:00 +0000310 switch (arch_guest) {
sewardj2a9ad022004-11-25 02:46:58 +0000311
sewardjbef170b2004-12-21 01:23:00 +0000312 case VexArchX86:
sewardj8d2291c2004-10-25 14:50:21 +0000313 preciseMemExnsFn = guest_x86_state_requires_precise_mem_exns;
sewardj2a9ad022004-11-25 02:46:58 +0000314 bbToIR = bbToIR_X86;
315 specHelper = guest_x86_spechelper;
sewardj81ec4182004-10-25 23:15:52 +0000316 guest_sizeB = sizeof(VexGuestX86State);
sewardjcf787902004-11-03 09:08:33 +0000317 guest_word_type = Ity_I32;
sewardj49651f42004-10-28 22:11:04 +0000318 guest_layout = &x86guest_layout;
sewardj9df271d2004-12-31 22:37:42 +0000319 vassert(subarch_guest == VexSubArchX86_sse0
320 || subarch_guest == VexSubArchX86_sse1
321 || subarch_guest == VexSubArchX86_sse2);
sewardjf13a16a2004-07-05 17:10:14 +0000322 break;
sewardj2a9ad022004-11-25 02:46:58 +0000323
sewardj44d494d2005-01-20 20:26:33 +0000324 case VexArchAMD64:
325 preciseMemExnsFn = guest_amd64_state_requires_precise_mem_exns;
326 bbToIR = bbToIR_AMD64;
327 specHelper = guest_amd64_spechelper;
328 guest_sizeB = sizeof(VexGuestAMD64State);
329 guest_word_type = Ity_I64;
330 guest_layout = &amd64guest_layout;
331 vassert(subarch_guest == VexSubArch_NONE);
332 break;
333
sewardjbef170b2004-12-21 01:23:00 +0000334 case VexArchARM:
sewardj2a9ad022004-11-25 02:46:58 +0000335 preciseMemExnsFn = guest_arm_state_requires_precise_mem_exns;
sewardjc2c87162004-11-25 13:07:02 +0000336 bbToIR = bbToIR_ARM;
sewardj2a9ad022004-11-25 02:46:58 +0000337 specHelper = guest_arm_spechelper;
338 guest_sizeB = sizeof(VexGuestARMState);
339 guest_word_type = Ity_I32;
340 guest_layout = &armGuest_layout;
sewardj44d494d2005-01-20 20:26:33 +0000341 vassert(subarch_guest == VexSubArchARM_v4);
sewardj2a9ad022004-11-25 02:46:58 +0000342 break;
343
cerionaabdfbf2005-01-29 12:56:15 +0000344 case VexArchPPC32:
345 preciseMemExnsFn = guest_ppc32_state_requires_precise_mem_exns;
346 bbToIR = bbToIR_PPC32;
347 specHelper = guest_ppc32_spechelper;
348 guest_sizeB = sizeof(VexGuestPPC32State);
349 guest_word_type = Ity_I32;
350 guest_layout = &ppc32Guest_layout;
sewardj0ec57c52005-02-01 15:24:10 +0000351 vassert(subarch_guest == VexSubArchPPC32_noAV
352 || subarch_guest == VexSubArchPPC32_AV);
cerionaabdfbf2005-01-29 12:56:15 +0000353 break;
354
sewardjf13a16a2004-07-05 17:10:14 +0000355 default:
sewardj887a11a2004-07-05 17:26:47 +0000356 vpanic("LibVEX_Translate: unsupported guest insn set");
sewardjf13a16a2004-07-05 17:10:14 +0000357 }
358
sewardj9df271d2004-12-31 22:37:42 +0000359 /* yet more sanity checks ... */
sewardj0ec57c52005-02-01 15:24:10 +0000360 if (arch_guest == arch_host) {
sewardj9df271d2004-12-31 22:37:42 +0000361 /* doesn't necessarily have to be true, but if it isn't it means
sewardj0ec57c52005-02-01 15:24:10 +0000362 we are simulating one flavour of an architecture a different
363 flavour of the same architecture, which is pretty strange. */
sewardj9df271d2004-12-31 22:37:42 +0000364 vassert(subarch_guest == subarch_host);
365 }
sewardj2a9ad022004-11-25 02:46:58 +0000366
sewardjf48ac192004-10-29 00:41:29 +0000367 if (vex_traceflags & VEX_TRACE_FE)
368 vex_printf("\n------------------------"
369 " Front end "
370 "------------------------\n\n");
371
sewardjf13a16a2004-07-05 17:10:14 +0000372 irbb = bbToIR ( guest_bytes,
sewardj72c72812005-01-19 11:49:45 +0000373 guest_bytes_addr,
374 guest_extents,
375 byte_accessible,
sewardj5bd4d162004-11-10 13:02:48 +0000376 chase_into_ok,
sewardj72c72812005-01-19 11:49:45 +0000377 host_is_bigendian,
sewardj9df271d2004-12-31 22:37:42 +0000378 subarch_guest );
sewardjf13a16a2004-07-05 17:10:14 +0000379
380 if (irbb == NULL) {
381 /* Access failure. */
sewardjd887b862005-01-17 18:34:34 +0000382 vexClearTEMP();
sewardjf48ac192004-10-29 00:41:29 +0000383 vex_traceflags = 0;
sewardjd887b862005-01-17 18:34:34 +0000384 return VexTransAccessFail;
sewardjf13a16a2004-07-05 17:10:14 +0000385 }
sewardjaa59f942004-10-09 09:34:36 +0000386
sewardj72c72812005-01-19 11:49:45 +0000387 vassert(guest_extents->n_used >= 1 && guest_extents->n_used <= 3);
388 vassert(guest_extents->base[0] == guest_bytes_addr);
389 for (i = 0; i < guest_extents->n_used; i++) {
390 vassert(guest_extents->len[i] < 10000); /* sanity */
391 }
392
sewardjaa59f942004-10-09 09:34:36 +0000393 /* If debugging, show the raw guest bytes for this bb. */
sewardj109ffdb2004-12-10 21:45:38 +0000394 if (0 || (vex_traceflags & VEX_TRACE_FE)) {
sewardj72c72812005-01-19 11:49:45 +0000395 if (guest_extents->n_used > 1) {
396 vex_printf("can't show code due to extents > 1\n");
397 } else {
398 /* HACK */
399 UChar* p = (UChar*)guest_bytes;
400 UInt guest_bytes_read = (UInt)guest_extents->len[0];
401 vex_printf(". 0 %llx %d\n.", guest_bytes_addr, guest_bytes_read );
402 for (i = 0; i < guest_bytes_read; i++)
sewardjaa59f942004-10-09 09:34:36 +0000403 vex_printf(" %02x", (Int)p[i] );
sewardj72c72812005-01-19 11:49:45 +0000404 vex_printf("\n\n");
405 }
sewardjaa59f942004-10-09 09:34:36 +0000406 }
407
408 /* Sanity check the initial IR. */
sewardjb9230752004-12-29 19:25:06 +0000409 sanityCheckIRBB( irbb, "initial IR",
410 False/*can be non-flat*/, guest_word_type );
sewardje8e9d732004-07-16 21:03:45 +0000411
sewardjedf4d692004-08-17 13:52:58 +0000412 /* Clean it up, hopefully a lot. */
sewardj8d2291c2004-10-25 14:50:21 +0000413 irbb = do_iropt_BB ( irbb, specHelper, preciseMemExnsFn,
414 guest_bytes_addr );
sewardjb9230752004-12-29 19:25:06 +0000415 sanityCheckIRBB( irbb, "after initial iropt",
416 True/*must be flat*/, guest_word_type );
sewardjedf4d692004-08-17 13:52:58 +0000417
sewardjf48ac192004-10-29 00:41:29 +0000418 if (vex_traceflags & VEX_TRACE_OPT1) {
419 vex_printf("\n------------------------"
420 " After pre-instr IR optimisation "
421 "------------------------\n\n");
sewardjedf4d692004-08-17 13:52:58 +0000422 ppIRBB ( irbb );
423 vex_printf("\n");
424 }
425
sewardjf13a16a2004-07-05 17:10:14 +0000426 /* Get the thing instrumented. */
sewardj49651f42004-10-28 22:11:04 +0000427 if (instrument1)
sewardjcf787902004-11-03 09:08:33 +0000428 irbb = (*instrument1)(irbb, guest_layout, host_word_type);
sewardj49651f42004-10-28 22:11:04 +0000429 if (instrument2)
sewardjcf787902004-11-03 09:08:33 +0000430 irbb = (*instrument2)(irbb, guest_layout, host_word_type);
sewardj49651f42004-10-28 22:11:04 +0000431
sewardjf48ac192004-10-29 00:41:29 +0000432 if (vex_traceflags & VEX_TRACE_INST) {
433 vex_printf("\n------------------------"
434 " After instrumentation "
435 "------------------------\n\n");
436 ppIRBB ( irbb );
437 vex_printf("\n");
438 }
439
sewardj49651f42004-10-28 22:11:04 +0000440 if (instrument1 || instrument2)
sewardjb9230752004-12-29 19:25:06 +0000441 sanityCheckIRBB( irbb, "after instrumentation",
442 True/*must be flat*/, guest_word_type );
sewardjf13a16a2004-07-05 17:10:14 +0000443
sewardj9578a8b2004-11-04 19:44:48 +0000444 /* Do a post-instrumentation cleanup pass. */
445 if (cleanup_after_instrumentation) {
446 do_deadcode_BB( irbb );
447 irbb = cprop_BB( irbb );
448 do_deadcode_BB( irbb );
sewardjb9230752004-12-29 19:25:06 +0000449 sanityCheckIRBB( irbb, "after post-instrumentation cleanup",
450 True/*must be flat*/, guest_word_type );
sewardj9578a8b2004-11-04 19:44:48 +0000451 }
452
453 if (vex_traceflags & VEX_TRACE_OPT2) {
454 vex_printf("\n------------------------"
455 " After post-instr IR optimisation "
456 "------------------------\n\n");
457 ppIRBB ( irbb );
458 vex_printf("\n");
459 }
460
sewardjf13a16a2004-07-05 17:10:14 +0000461 /* Turn it into virtual-registerised code. */
sewardj49651f42004-10-28 22:11:04 +0000462 do_deadcode_BB( irbb );
463 do_treebuild_BB( irbb );
sewardjf48ac192004-10-29 00:41:29 +0000464
465 if (vex_traceflags & VEX_TRACE_TREES) {
466 vex_printf("\n------------------------"
467 " After tree-building "
468 "------------------------\n\n");
469 ppIRBB ( irbb );
470 vex_printf("\n");
471 }
472
cerion54560812005-02-03 13:40:49 +0000473 if (0) { *host_bytes_used = 0; return VexTransOK; }
sewardjc33671d2005-02-01 20:30:00 +0000474
sewardjf48ac192004-10-29 00:41:29 +0000475 if (vex_traceflags & VEX_TRACE_VCODE)
476 vex_printf("\n------------------------"
477 " Instruction selection "
478 "------------------------\n");
479
sewardj9df271d2004-12-31 22:37:42 +0000480 vcode = iselBB ( irbb, subarch_host );
sewardjf13a16a2004-07-05 17:10:14 +0000481
sewardjf48ac192004-10-29 00:41:29 +0000482 if (vex_traceflags & VEX_TRACE_VCODE)
483 vex_printf("\n");
484
sewardjf48ac192004-10-29 00:41:29 +0000485 if (vex_traceflags & VEX_TRACE_VCODE) {
sewardj1f40a0a2004-07-21 12:28:07 +0000486 for (i = 0; i < vcode->arr_used; i++) {
487 vex_printf("%3d ", i);
488 ppInstr(vcode->arr[i]);
489 vex_printf("\n");
490 }
sewardjfbcaf332004-07-08 01:46:01 +0000491 vex_printf("\n");
492 }
sewardjfbcaf332004-07-08 01:46:01 +0000493
sewardjf13a16a2004-07-05 17:10:14 +0000494 /* Register allocate. */
495 rcode = doRegisterAllocation ( vcode, available_real_regs,
sewardj72c72812005-01-19 11:49:45 +0000496 n_available_real_regs,
497 isMove, getRegUsage, mapRegs,
498 genSpill, genReload, guest_sizeB,
499 ppInstr, ppReg );
sewardjf13a16a2004-07-05 17:10:14 +0000500
sewardjf48ac192004-10-29 00:41:29 +0000501 if (vex_traceflags & VEX_TRACE_RCODE) {
502 vex_printf("\n------------------------"
503 " Register-allocated code "
504 "------------------------\n\n");
sewardj1f40a0a2004-07-21 12:28:07 +0000505 for (i = 0; i < rcode->arr_used; i++) {
506 vex_printf("%3d ", i);
507 ppInstr(rcode->arr[i]);
508 vex_printf("\n");
509 }
sewardjfbcaf332004-07-08 01:46:01 +0000510 vex_printf("\n");
511 }
sewardjfbcaf332004-07-08 01:46:01 +0000512
sewardj81bd5502004-07-21 18:49:27 +0000513 /* Assemble */
sewardjf48ac192004-10-29 00:41:29 +0000514 if (vex_traceflags & VEX_TRACE_ASM) {
515 vex_printf("\n------------------------"
516 " Assembly "
517 "------------------------\n\n");
518 }
519
sewardj81bd5502004-07-21 18:49:27 +0000520 out_used = 0; /* tracks along the host_bytes array */
521 for (i = 0; i < rcode->arr_used; i++) {
sewardjf48ac192004-10-29 00:41:29 +0000522 if (vex_traceflags & VEX_TRACE_ASM) {
sewardjbad34a92004-07-22 01:14:11 +0000523 ppInstr(rcode->arr[i]);
524 vex_printf("\n");
525 }
sewardj81bd5502004-07-21 18:49:27 +0000526 j = (*emit)( insn_bytes, 32, rcode->arr[i] );
sewardjf48ac192004-10-29 00:41:29 +0000527 if (vex_traceflags & VEX_TRACE_ASM) {
sewardjbad34a92004-07-22 01:14:11 +0000528 for (k = 0; k < j; k++)
sewardj72c72812005-01-19 11:49:45 +0000529 if (insn_bytes[k] < 16)
sewardj86898e82004-07-22 17:26:12 +0000530 vex_printf("0%x ", (UInt)insn_bytes[k]);
531 else
532 vex_printf("%x ", (UInt)insn_bytes[k]);
sewardjbad34a92004-07-22 01:14:11 +0000533 vex_printf("\n\n");
534 }
sewardj81bd5502004-07-21 18:49:27 +0000535 if (out_used + j > host_bytes_size) {
sewardjd887b862005-01-17 18:34:34 +0000536 vexClearTEMP();
sewardjf48ac192004-10-29 00:41:29 +0000537 vex_traceflags = 0;
sewardjd887b862005-01-17 18:34:34 +0000538 return VexTransOutputFull;
sewardj81bd5502004-07-21 18:49:27 +0000539 }
540 for (k = 0; k < j; k++) {
541 host_bytes[out_used] = insn_bytes[k];
542 out_used++;
543 }
544 vassert(out_used <= host_bytes_size);
545 }
546 *host_bytes_used = out_used;
547
sewardjd887b862005-01-17 18:34:34 +0000548 vexClearTEMP();
sewardjf13a16a2004-07-05 17:10:14 +0000549
sewardjf48ac192004-10-29 00:41:29 +0000550 vex_traceflags = 0;
sewardjd887b862005-01-17 18:34:34 +0000551 return VexTransOK;
sewardj35421a32004-07-05 13:12:34 +0000552}
553
554
sewardj893aada2004-11-29 19:57:54 +0000555/* --------- Emulation warnings. --------- */
556
557HChar* LibVEX_EmWarn_string ( VexEmWarn ew )
558{
559 switch (ew) {
560 case EmWarn_NONE:
561 return "none";
562 case EmWarn_X86_x87exns:
563 return "Unmasking x87 FP exceptions";
sewardj893aada2004-11-29 19:57:54 +0000564 case EmWarn_X86_x87precision:
565 return "Selection of non-80-bit x87 FP precision";
566 case EmWarn_X86_sseExns:
sewardj5edfc262004-12-15 12:13:52 +0000567 return "Unmasking SSE FP exceptions";
568 case EmWarn_X86_fz:
569 return "Setting %mxcsr.fz (SSE flush-underflows-to-zero mode)";
570 case EmWarn_X86_daz:
571 return "Setting %mxcsr.daz (SSE treat-denormals-as-zero mode)";
sewardj893aada2004-11-29 19:57:54 +0000572 default:
573 vpanic("LibVEX_EmWarn_string: unknown warning");
574 }
575}
sewardj35421a32004-07-05 13:12:34 +0000576
sewardjbef170b2004-12-21 01:23:00 +0000577/* --------- Arch/Subarch names. --------- */
578
579const HChar* LibVEX_ppVexArch ( VexArch arch )
580{
581 switch (arch) {
582 case VexArch_INVALID: return "INVALID";
583 case VexArchX86: return "X86";
584 case VexArchAMD64: return "AMD64";
585 case VexArchARM: return "ARM";
sewardj0ec57c52005-02-01 15:24:10 +0000586 case VexArchPPC32: return "PPC32";
sewardjbef170b2004-12-21 01:23:00 +0000587 default: return "VexArch???";
588 }
589}
590
591const HChar* LibVEX_ppVexSubArch ( VexSubArch subarch )
592{
593 switch (subarch) {
sewardj0ec57c52005-02-01 15:24:10 +0000594 case VexSubArch_INVALID: return "INVALID";
595 case VexSubArch_NONE: return "NONE";
596 case VexSubArchX86_sse0: return "x86-sse0";
597 case VexSubArchX86_sse1: return "x86-sse1";
598 case VexSubArchX86_sse2: return "x86-sse2";
599 case VexSubArchARM_v4: return "arm-v4";
600 case VexSubArchPPC32_noAV: return "ppc32-noAltivec";
601 case VexSubArchPPC32_AV: return "ppc32-Altivec";
602 default: return "VexSubArch???";
sewardjbef170b2004-12-21 01:23:00 +0000603 }
604}
605
sewardj35421a32004-07-05 13:12:34 +0000606/*---------------------------------------------------------------*/
sewardjc0ee2ed2004-07-27 10:29:41 +0000607/*--- end main/vex_main.c ---*/
sewardj35421a32004-07-05 13:12:34 +0000608/*---------------------------------------------------------------*/