sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 1 | |
| 2 | /*---------------------------------------------------------------*/ |
| 3 | /*--- ---*/ |
sewardj | 887a11a | 2004-07-05 17:26:47 +0000 | [diff] [blame] | 4 | /*--- This file (libvex.h) is ---*/ |
sewardj | dbcfae7 | 2005-08-02 11:14:04 +0000 | [diff] [blame] | 5 | /*--- Copyright (C) OpenWorks LLP. All rights reserved. ---*/ |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 6 | /*--- ---*/ |
| 7 | /*---------------------------------------------------------------*/ |
| 8 | |
sewardj | f8ed9d8 | 2004-11-12 17:40:23 +0000 | [diff] [blame] | 9 | /* |
| 10 | This file is part of LibVEX, a library for dynamic binary |
| 11 | instrumentation and translation. |
| 12 | |
sewardj | 7bd6ffe | 2005-08-03 16:07:36 +0000 | [diff] [blame] | 13 | Copyright (C) 2004-2005 OpenWorks LLP. All rights reserved. |
sewardj | f8ed9d8 | 2004-11-12 17:40:23 +0000 | [diff] [blame] | 14 | |
sewardj | 7bd6ffe | 2005-08-03 16:07:36 +0000 | [diff] [blame] | 15 | This library is made available under a dual licensing scheme. |
sewardj | f8ed9d8 | 2004-11-12 17:40:23 +0000 | [diff] [blame] | 16 | |
sewardj | 7bd6ffe | 2005-08-03 16:07:36 +0000 | [diff] [blame] | 17 | 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. |
sewardj | f8ed9d8 | 2004-11-12 17:40:23 +0000 | [diff] [blame] | 40 | |
| 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. |
sewardj | f8ed9d8 | 2004-11-12 17:40:23 +0000 | [diff] [blame] | 45 | */ |
| 46 | |
sewardj | 887a11a | 2004-07-05 17:26:47 +0000 | [diff] [blame] | 47 | #ifndef __LIBVEX_H |
| 48 | #define __LIBVEX_H |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 49 | |
| 50 | |
sewardj | 887a11a | 2004-07-05 17:26:47 +0000 | [diff] [blame] | 51 | #include "libvex_basictypes.h" |
| 52 | #include "libvex_ir.h" |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 53 | |
| 54 | |
| 55 | /*---------------------------------------------------------------*/ |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 56 | /*--- This file defines the top-level interface to LibVEX. ---*/ |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 57 | /*---------------------------------------------------------------*/ |
| 58 | |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 59 | /*-------------------------------------------------------*/ |
sewardj | 27e1dd6 | 2005-06-30 11:49:14 +0000 | [diff] [blame] | 60 | /*--- Architectures, variants, and other arch info ---*/ |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 61 | /*-------------------------------------------------------*/ |
sewardj | bef170b | 2004-12-21 01:23:00 +0000 | [diff] [blame] | 62 | |
| 63 | typedef |
| 64 | enum { |
| 65 | VexArch_INVALID, |
| 66 | VexArchX86, |
| 67 | VexArchAMD64, |
cerion | 896a137 | 2005-01-25 12:24:25 +0000 | [diff] [blame] | 68 | VexArchARM, |
cerion | aabdfbf | 2005-01-29 12:56:15 +0000 | [diff] [blame] | 69 | VexArchPPC32 |
sewardj | bef170b | 2004-12-21 01:23:00 +0000 | [diff] [blame] | 70 | } |
| 71 | VexArch; |
| 72 | |
| 73 | typedef |
| 74 | enum { |
| 75 | VexSubArch_INVALID, |
sewardj | 0ec57c5 | 2005-02-01 15:24:10 +0000 | [diff] [blame] | 76 | VexSubArch_NONE, /* Arch has no variants */ |
| 77 | VexSubArchX86_sse0, /* has SSE state but no insns (Pentium II) */ |
| 78 | VexSubArchX86_sse1, /* SSE1 support (Pentium III) */ |
| 79 | VexSubArchX86_sse2, /* SSE2 support (Pentium 4) */ |
| 80 | VexSubArchARM_v4, /* ARM version 4 */ |
| 81 | VexSubArchPPC32_noAV, /* 32-bit PowerPC, no Altivec */ |
| 82 | VexSubArchPPC32_AV /* 32-bit PowerPC with Altivec */ |
sewardj | bef170b | 2004-12-21 01:23:00 +0000 | [diff] [blame] | 83 | } |
| 84 | VexSubArch; |
| 85 | |
| 86 | /* These return statically allocated strings. */ |
| 87 | |
| 88 | extern const HChar* LibVEX_ppVexArch ( VexArch ); |
| 89 | extern const HChar* LibVEX_ppVexSubArch ( VexSubArch ); |
| 90 | |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 91 | |
sewardj | 27e1dd6 | 2005-06-30 11:49:14 +0000 | [diff] [blame] | 92 | /* This struct is a bit of a hack, but is needed to carry misc |
| 93 | important bits of info about an arch. Fields which are optional or |
| 94 | ignored on some arch should be set to zero. */ |
| 95 | |
| 96 | typedef |
| 97 | struct { |
| 98 | /* This is the only mandatory field. */ |
| 99 | VexSubArch subarch; |
| 100 | /* PPC32 only: size of cache line */ |
| 101 | Int ppc32_cache_line_szB; |
| 102 | } |
| 103 | VexArchInfo; |
| 104 | |
| 105 | /* Write default settings info *vai. */ |
| 106 | extern |
| 107 | void LibVEX_default_VexArchInfo ( /*OUT*/VexArchInfo* vai ); |
| 108 | |
| 109 | |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 110 | /*-------------------------------------------------------*/ |
| 111 | /*--- Control of Vex's optimiser (iropt). ---*/ |
| 112 | /*-------------------------------------------------------*/ |
| 113 | |
sewardj | 0861374 | 2004-10-25 13:01:45 +0000 | [diff] [blame] | 114 | /* Control of Vex's optimiser. */ |
| 115 | |
| 116 | typedef |
| 117 | struct { |
| 118 | /* Controls verbosity of iropt. 0 = no output. */ |
| 119 | Int iropt_verbosity; |
| 120 | /* Control aggressiveness of iropt. 0 = no opt, 1 = simple |
| 121 | opts, 2 (default) = max optimisation. */ |
| 122 | Int iropt_level; |
| 123 | /* Ensure all integer registers are up to date at potential |
| 124 | memory exception points? True(default)=yes, False=no, only |
| 125 | the guest's stack pointer. */ |
| 126 | Bool iropt_precise_memory_exns; |
| 127 | /* How aggressive should iropt be in unrolling loops? Higher |
| 128 | numbers make it more enthusiastic about loop unrolling. |
| 129 | Default=120. A setting of zero disables unrolling. */ |
| 130 | Int iropt_unroll_thresh; |
| 131 | /* What's the maximum basic block length the front end(s) allow? |
| 132 | BBs longer than this are split up. Default=50 (guest |
| 133 | insns). */ |
| 134 | Int guest_max_insns; |
| 135 | /* How aggressive should front ends be in following |
| 136 | unconditional branches to known destinations? Default=10, |
| 137 | meaning that if a block contains less than 10 guest insns so |
| 138 | far, the front end(s) will attempt to chase into its |
| 139 | successor. A setting of zero disables chasing. */ |
| 140 | Int guest_chase_thresh; |
| 141 | } |
| 142 | VexControl; |
| 143 | |
| 144 | |
| 145 | /* Write the default settings into *vcon. */ |
sewardj | bef170b | 2004-12-21 01:23:00 +0000 | [diff] [blame] | 146 | |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 147 | extern |
| 148 | void LibVEX_default_VexControl ( /*OUT*/ VexControl* vcon ); |
sewardj | 0861374 | 2004-10-25 13:01:45 +0000 | [diff] [blame] | 149 | |
| 150 | |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 151 | /*-------------------------------------------------------*/ |
| 152 | /*--- Version information ---*/ |
| 153 | /*-------------------------------------------------------*/ |
sewardj | 80f5fce | 2004-12-20 04:37:50 +0000 | [diff] [blame] | 154 | |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 155 | /* Returns the Vex SVN version, as a statically allocated string. */ |
| 156 | |
| 157 | extern const HChar* LibVEX_Version ( void ); |
sewardj | 80f5fce | 2004-12-20 04:37:50 +0000 | [diff] [blame] | 158 | |
| 159 | |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 160 | /*-------------------------------------------------------*/ |
| 161 | /*--- Storage management control ---*/ |
| 162 | /*-------------------------------------------------------*/ |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 163 | |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 164 | /* Allocate in Vex's temporary allocation area. Be careful with this. |
| 165 | You can only call it inside an instrumentation or optimisation |
| 166 | callback that you have previously specified in a call to |
| 167 | LibVEX_Translate. The storage allocated will only stay alive until |
| 168 | translation of the current basic block is complete. |
| 169 | */ |
sewardj | 35421a3 | 2004-07-05 13:12:34 +0000 | [diff] [blame] | 170 | extern void* LibVEX_Alloc ( Int nbytes ); |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 171 | |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 172 | /* Show Vex allocation statistics. */ |
| 173 | extern void LibVEX_ShowAllocStats ( void ); |
| 174 | |
| 175 | |
| 176 | /*-------------------------------------------------------*/ |
| 177 | /*--- Describing guest state layout ---*/ |
| 178 | /*-------------------------------------------------------*/ |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 179 | |
sewardj | 49651f4 | 2004-10-28 22:11:04 +0000 | [diff] [blame] | 180 | /* Describe the guest state enough that the instrumentation |
| 181 | functions can work. */ |
| 182 | |
sewardj | eeac841 | 2004-11-02 00:26:55 +0000 | [diff] [blame] | 183 | /* The max number of guest state chunks which we can describe as |
| 184 | always defined (for the benefit of Memcheck). */ |
sewardj | 6d26984 | 2005-08-06 11:45:02 +0000 | [diff] [blame^] | 185 | #define VEXGLO_N_ALWAYSDEFD 22 |
sewardj | eeac841 | 2004-11-02 00:26:55 +0000 | [diff] [blame] | 186 | |
sewardj | 49651f4 | 2004-10-28 22:11:04 +0000 | [diff] [blame] | 187 | typedef |
| 188 | struct { |
sewardj | cf78790 | 2004-11-03 09:08:33 +0000 | [diff] [blame] | 189 | /* Total size of the guest state, in bytes. Must be |
| 190 | 8-aligned. */ |
sewardj | eeac841 | 2004-11-02 00:26:55 +0000 | [diff] [blame] | 191 | Int total_sizeB; |
sewardj | 49651f4 | 2004-10-28 22:11:04 +0000 | [diff] [blame] | 192 | /* Whereabouts is the stack pointer? */ |
| 193 | Int offset_SP; |
| 194 | Int sizeof_SP; /* 4 or 8 */ |
sewardj | cf78790 | 2004-11-03 09:08:33 +0000 | [diff] [blame] | 195 | /* Whereabouts is the instruction pointer? */ |
| 196 | Int offset_IP; |
| 197 | Int sizeof_IP; /* 4 or 8 */ |
sewardj | eeac841 | 2004-11-02 00:26:55 +0000 | [diff] [blame] | 198 | /* Describe parts of the guest state regarded as 'always |
| 199 | defined'. */ |
| 200 | Int n_alwaysDefd; |
| 201 | struct { |
| 202 | Int offset; |
| 203 | Int size; |
| 204 | } alwaysDefd[VEXGLO_N_ALWAYSDEFD]; |
sewardj | 49651f4 | 2004-10-28 22:11:04 +0000 | [diff] [blame] | 205 | } |
sewardj | eeac841 | 2004-11-02 00:26:55 +0000 | [diff] [blame] | 206 | VexGuestLayout; |
sewardj | 49651f4 | 2004-10-28 22:11:04 +0000 | [diff] [blame] | 207 | |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 208 | /* A note about guest state layout. |
sewardj | 49651f4 | 2004-10-28 22:11:04 +0000 | [diff] [blame] | 209 | |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 210 | LibVEX defines the layout for the guest state, in the file |
| 211 | pub/libvex_guest_<arch>.h. The struct will have an 8-aligned size. |
| 212 | Each translated bb is assumed to be entered with a specified |
| 213 | register pointing at such a struct. Beyond that is a shadow |
| 214 | state area with the same size as the struct. Beyond that is |
| 215 | a spill area that LibVEX may spill into. It must have size |
| 216 | LibVEX_N_SPILL_BYTES, and this must be a 16-aligned number. |
| 217 | |
| 218 | On entry, the baseblock pointer register must be 8-aligned. |
| 219 | */ |
| 220 | |
sewardj | 84a2c38 | 2005-05-03 09:08:23 +0000 | [diff] [blame] | 221 | #define LibVEX_N_SPILL_BYTES 1024 |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 222 | |
| 223 | |
| 224 | /*-------------------------------------------------------*/ |
| 225 | /*--- Initialisation of the library ---*/ |
| 226 | /*-------------------------------------------------------*/ |
| 227 | |
| 228 | /* Initialise the library. You must call this first. */ |
| 229 | |
| 230 | extern void LibVEX_Init ( |
| 231 | /* failure exit function */ |
| 232 | __attribute__ ((noreturn)) |
| 233 | void (*failure_exit) ( void ), |
| 234 | /* logging output function */ |
sewardj | 5827784 | 2005-02-07 03:11:17 +0000 | [diff] [blame] | 235 | void (*log_bytes) ( HChar*, Int nbytes ), |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 236 | /* debug paranoia level */ |
| 237 | Int debuglevel, |
| 238 | /* Are we supporting valgrind checking? */ |
| 239 | Bool valgrind_support, |
| 240 | /* Control ... */ |
| 241 | /*READONLY*/VexControl* vcon |
| 242 | ); |
| 243 | |
| 244 | |
| 245 | /*-------------------------------------------------------*/ |
| 246 | /*--- Make a translation ---*/ |
| 247 | /*-------------------------------------------------------*/ |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 248 | |
sewardj | 72c7281 | 2005-01-19 11:49:45 +0000 | [diff] [blame] | 249 | /* Describes the outcome of a translation attempt. */ |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 250 | typedef |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 251 | enum { |
| 252 | VexTransOK, |
| 253 | VexTransAccessFail, |
| 254 | VexTransOutputFull |
| 255 | } |
| 256 | VexTranslateResult; |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 257 | |
sewardj | 72c7281 | 2005-01-19 11:49:45 +0000 | [diff] [blame] | 258 | |
| 259 | /* Describes precisely the pieces of guest code that a translation |
| 260 | covers. Now that Vex can chase across BB boundaries, the old |
| 261 | scheme of describing a chunk of guest code merely by its start |
| 262 | address and length is inadequate. |
| 263 | |
| 264 | Hopefully this struct is only 32 bytes long. Space is important as |
| 265 | clients will have to store one of these for each translation made. |
| 266 | */ |
| 267 | typedef |
| 268 | struct { |
| 269 | Addr64 base[3]; |
| 270 | UShort len[3]; |
| 271 | UShort n_used; |
| 272 | } |
| 273 | VexGuestExtents; |
| 274 | |
| 275 | |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 276 | extern |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 277 | VexTranslateResult LibVEX_Translate ( |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 278 | /* The instruction sets we are translating from and to. */ |
sewardj | 27e1dd6 | 2005-06-30 11:49:14 +0000 | [diff] [blame] | 279 | VexArch arch_guest, |
| 280 | VexArchInfo* archinfo_guest, |
| 281 | VexArch arch_host, |
| 282 | VexArchInfo* archinfo_host, |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 283 | /* IN: the block to translate, and its guest address. */ |
sewardj | bef170b | 2004-12-21 01:23:00 +0000 | [diff] [blame] | 284 | UChar* guest_bytes, |
| 285 | Addr64 guest_bytes_addr, |
| 286 | Bool (*chase_into_ok) ( Addr64 ), |
sewardj | 72c7281 | 2005-01-19 11:49:45 +0000 | [diff] [blame] | 287 | /* OUT: which bits of guest code actually got translated */ |
| 288 | VexGuestExtents* guest_extents, |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 289 | /* IN: a place to put the resulting code, and its size */ |
sewardj | bef170b | 2004-12-21 01:23:00 +0000 | [diff] [blame] | 290 | UChar* host_bytes, |
| 291 | Int host_bytes_size, |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 292 | /* OUT: how much of the output area is used. */ |
sewardj | bef170b | 2004-12-21 01:23:00 +0000 | [diff] [blame] | 293 | Int* host_bytes_used, |
sewardj | 49651f4 | 2004-10-28 22:11:04 +0000 | [diff] [blame] | 294 | /* IN: optionally, two instrumentation functions. */ |
sewardj | 918c8f3 | 2005-03-21 00:54:33 +0000 | [diff] [blame] | 295 | IRBB* (*instrument1) ( IRBB*, VexGuestLayout*, |
| 296 | IRType gWordTy, IRType hWordTy ), |
| 297 | IRBB* (*instrument2) ( IRBB*, VexGuestLayout*, |
| 298 | IRType gWordTy, IRType hWordTy ), |
sewardj | bef170b | 2004-12-21 01:23:00 +0000 | [diff] [blame] | 299 | Bool cleanup_after_instrumentation, |
sewardj | ec3c885 | 2005-07-07 09:56:24 +0000 | [diff] [blame] | 300 | /* IN: should this translation be self-checking? */ |
| 301 | Bool do_self_check, |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 302 | /* IN: optionally, an access check function for guest code. */ |
sewardj | bef170b | 2004-12-21 01:23:00 +0000 | [diff] [blame] | 303 | Bool (*byte_accessible) ( Addr64 ), |
sewardj | f48ac19 | 2004-10-29 00:41:29 +0000 | [diff] [blame] | 304 | /* IN: debug: trace vex activity at various points */ |
sewardj | bef170b | 2004-12-21 01:23:00 +0000 | [diff] [blame] | 305 | Int traceflags |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 306 | ); |
| 307 | |
sewardj | c24824a | 2005-07-07 13:52:03 +0000 | [diff] [blame] | 308 | /* A subtlety re interaction between self-checking translations and |
| 309 | bb-chasing. The supplied chase_into_ok function should say NO |
| 310 | (False) when presented with any address for which you might want to |
| 311 | make a self-checking translation. |
| 312 | |
| 313 | If it doesn't do that, you may end up with Vex chasing from BB #1 |
| 314 | to BB #2 (fine); but if you wanted checking for #2 and not #1, that |
| 315 | would not be the result. Therefore chase_into_ok should disallow |
| 316 | following into #2. That will force the caller to eventually |
| 317 | request a new translation starting at #2, at which point Vex will |
| 318 | correctly observe the make-a-self-check flag. */ |
| 319 | |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 320 | |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 321 | /*-------------------------------------------------------*/ |
| 322 | /*--- Show accumulated statistics ---*/ |
| 323 | /*-------------------------------------------------------*/ |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 324 | |
sewardj | 887a11a | 2004-07-05 17:26:47 +0000 | [diff] [blame] | 325 | extern void LibVEX_ShowStats ( void ); |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 326 | |
| 327 | |
sewardj | d887b86 | 2005-01-17 18:34:34 +0000 | [diff] [blame] | 328 | /*-------------------------------------------------------*/ |
| 329 | /*--- Notes ---*/ |
| 330 | /*-------------------------------------------------------*/ |
sewardj | 812a858 | 2005-01-13 16:33:19 +0000 | [diff] [blame] | 331 | |
| 332 | /* Code generation conventions that need to be recorded somewhere. |
| 333 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 334 | |
| 335 | x86 |
| 336 | ~~~ |
| 337 | Generated code should be entered using a CALL instruction. On |
| 338 | entry, %ebp should point to the guest state, and %esp should be a |
| 339 | valid stack pointer. The generated code may change %eax, %ebx, |
| 340 | %ecx, %edx, %esi, %edi, all the FP registers and control state, and |
| 341 | all the XMM registers. |
| 342 | |
sewardj | 6915b97 | 2005-01-13 16:36:42 +0000 | [diff] [blame] | 343 | On entry, the FPU control word should be set to 0x027F, and the SSE |
sewardj | 812a858 | 2005-01-13 16:33:19 +0000 | [diff] [blame] | 344 | control word (%mxcsr) should be set to 0x1F80. On exit, they |
| 345 | should still have those values (after masking off the lowest 6 bits |
| 346 | of %mxcsr). If they don't, there is a bug in VEX-generated code. |
| 347 | |
| 348 | Generated code returns to the scheduler using a RET instruction. |
| 349 | %eax (or %eax:%edx, if simulating a 64-bit target) will contain the |
| 350 | guest address of the next block to execute. |
| 351 | |
| 352 | CRITICAL ISSUES in x86 code generation. The only known critical |
| 353 | issue is that the host FPU and SSE state is not properly saved |
| 354 | across calls to helper functions. If any helper references any |
| 355 | such state, it is likely (1) to misbehave itself, since the FP |
| 356 | stack tags will not be as expected, and (2) after returning to |
| 357 | generated code, the generated code is likely to go wrong. This |
| 358 | really should be fixed. |
sewardj | db4738a | 2005-07-07 01:32:16 +0000 | [diff] [blame] | 359 | |
| 360 | ALL GUEST ARCHITECTURES |
| 361 | ~~~~~~~~~~~~~~~~~~~~~~~ |
| 362 | The architecture must contain two pseudo-registers, guest_TISTART |
| 363 | and guest_TILEN. These are used to pass the address of areas of |
| 364 | guest code, translations of which are to be invalidated, back to |
| 365 | the despatcher. Both pseudo-regs must have size equal to the guest |
| 366 | word size. |
sewardj | 812a858 | 2005-01-13 16:33:19 +0000 | [diff] [blame] | 367 | */ |
sewardj | 887a11a | 2004-07-05 17:26:47 +0000 | [diff] [blame] | 368 | #endif /* ndef __LIBVEX_H */ |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 369 | |
| 370 | /*---------------------------------------------------------------*/ |
sewardj | 887a11a | 2004-07-05 17:26:47 +0000 | [diff] [blame] | 371 | /*--- libvex.h ---*/ |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 372 | /*---------------------------------------------------------------*/ |