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 | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 5 | /*--- Copyright (c) 2004 OpenWorks LLP. All rights reserved. ---*/ |
| 6 | /*--- ---*/ |
| 7 | /*---------------------------------------------------------------*/ |
| 8 | |
sewardj | 887a11a | 2004-07-05 17:26:47 +0000 | [diff] [blame] | 9 | #ifndef __LIBVEX_H |
| 10 | #define __LIBVEX_H |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 11 | |
| 12 | |
sewardj | 887a11a | 2004-07-05 17:26:47 +0000 | [diff] [blame] | 13 | #include "libvex_basictypes.h" |
| 14 | #include "libvex_ir.h" |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 15 | |
| 16 | |
| 17 | /*---------------------------------------------------------------*/ |
| 18 | /*--- Top-level interface to the library. ---*/ |
| 19 | /*---------------------------------------------------------------*/ |
| 20 | |
| 21 | |
sewardj | 0861374 | 2004-10-25 13:01:45 +0000 | [diff] [blame] | 22 | /* Control of Vex's optimiser. */ |
| 23 | |
| 24 | typedef |
| 25 | struct { |
| 26 | /* Controls verbosity of iropt. 0 = no output. */ |
| 27 | Int iropt_verbosity; |
| 28 | /* Control aggressiveness of iropt. 0 = no opt, 1 = simple |
| 29 | opts, 2 (default) = max optimisation. */ |
| 30 | Int iropt_level; |
| 31 | /* Ensure all integer registers are up to date at potential |
| 32 | memory exception points? True(default)=yes, False=no, only |
| 33 | the guest's stack pointer. */ |
| 34 | Bool iropt_precise_memory_exns; |
| 35 | /* How aggressive should iropt be in unrolling loops? Higher |
| 36 | numbers make it more enthusiastic about loop unrolling. |
| 37 | Default=120. A setting of zero disables unrolling. */ |
| 38 | Int iropt_unroll_thresh; |
| 39 | /* What's the maximum basic block length the front end(s) allow? |
| 40 | BBs longer than this are split up. Default=50 (guest |
| 41 | insns). */ |
| 42 | Int guest_max_insns; |
| 43 | /* How aggressive should front ends be in following |
| 44 | unconditional branches to known destinations? Default=10, |
| 45 | meaning that if a block contains less than 10 guest insns so |
| 46 | far, the front end(s) will attempt to chase into its |
| 47 | successor. A setting of zero disables chasing. */ |
| 48 | Int guest_chase_thresh; |
| 49 | } |
| 50 | VexControl; |
| 51 | |
| 52 | |
| 53 | /* Write the default settings into *vcon. */ |
| 54 | extern void LibVEX_default_VexControl ( /*OUT*/ VexControl* vcon ); |
| 55 | |
| 56 | |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 57 | /* Initialise the translator. */ |
| 58 | |
sewardj | 887a11a | 2004-07-05 17:26:47 +0000 | [diff] [blame] | 59 | extern void LibVEX_Init ( |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 60 | /* failure exit function */ |
sewardj | 2b51587 | 2004-07-05 20:50:45 +0000 | [diff] [blame] | 61 | __attribute__ ((noreturn)) |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 62 | void (*failure_exit) ( void ), |
| 63 | /* logging output function */ |
| 64 | void (*log_bytes) ( Char*, Int nbytes ), |
| 65 | /* debug paranoia level */ |
| 66 | Int debuglevel, |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 67 | /* Are we supporting valgrind checking? */ |
| 68 | Bool valgrind_support, |
sewardj | 0861374 | 2004-10-25 13:01:45 +0000 | [diff] [blame] | 69 | /* Control ... */ |
| 70 | /*READONLY*/VexControl* vcon |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 71 | ); |
| 72 | |
| 73 | |
| 74 | /* Storage management: clear the area, and allocate from it. */ |
| 75 | |
sewardj | 443cd9d | 2004-07-18 23:06:45 +0000 | [diff] [blame] | 76 | /* By default allocation occurs in the temporary area. However, it is |
| 77 | possible to switch to permanent area allocation if that's what you |
| 78 | want. Permanent area allocation is very limited, tho. */ |
| 79 | |
| 80 | typedef |
| 81 | enum { AllocModeTEMPORARY, AllocModePERMANENT } |
| 82 | AllocMode; |
| 83 | |
| 84 | extern void LibVEX_SetAllocMode ( AllocMode ); |
| 85 | extern AllocMode LibVEX_GetAllocMode ( void ); |
| 86 | |
| 87 | extern void LibVEX_ClearTemporary ( Bool show_stats ); |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 88 | |
sewardj | 35421a3 | 2004-07-05 13:12:34 +0000 | [diff] [blame] | 89 | extern void* LibVEX_Alloc ( Int nbytes ); |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 90 | |
| 91 | |
sewardj | 49651f4 | 2004-10-28 22:11:04 +0000 | [diff] [blame] | 92 | /* Describe the guest state enough that the instrumentation |
| 93 | functions can work. */ |
| 94 | |
sewardj | eeac841 | 2004-11-02 00:26:55 +0000 | [diff] [blame] | 95 | /* The max number of indexable guest state sections we can describe. |
| 96 | 2 is enough for x86. */ |
| 97 | #define VEXGLO_N_DESCRS 2 |
| 98 | |
| 99 | /* The max number of guest state chunks which we can describe as |
| 100 | always defined (for the benefit of Memcheck). */ |
| 101 | #define VEXGLO_N_ALWAYSDEFD 14 |
| 102 | |
sewardj | 49651f4 | 2004-10-28 22:11:04 +0000 | [diff] [blame] | 103 | typedef |
| 104 | struct { |
sewardj | cf78790 | 2004-11-03 09:08:33 +0000 | [diff] [blame] | 105 | /* Total size of the guest state, in bytes. Must be |
| 106 | 8-aligned. */ |
sewardj | eeac841 | 2004-11-02 00:26:55 +0000 | [diff] [blame] | 107 | Int total_sizeB; |
sewardj | 49651f4 | 2004-10-28 22:11:04 +0000 | [diff] [blame] | 108 | /* Whereabouts is the stack pointer? */ |
| 109 | Int offset_SP; |
| 110 | Int sizeof_SP; /* 4 or 8 */ |
sewardj | cf78790 | 2004-11-03 09:08:33 +0000 | [diff] [blame] | 111 | /* Whereabouts is the instruction pointer? */ |
| 112 | Int offset_IP; |
| 113 | Int sizeof_IP; /* 4 or 8 */ |
sewardj | eeac841 | 2004-11-02 00:26:55 +0000 | [diff] [blame] | 114 | /* Describe parts of the guest state regarded as 'always |
| 115 | defined'. */ |
| 116 | Int n_alwaysDefd; |
| 117 | struct { |
| 118 | Int offset; |
| 119 | Int size; |
| 120 | } alwaysDefd[VEXGLO_N_ALWAYSDEFD]; |
sewardj | 49651f4 | 2004-10-28 22:11:04 +0000 | [diff] [blame] | 121 | } |
sewardj | eeac841 | 2004-11-02 00:26:55 +0000 | [diff] [blame] | 122 | VexGuestLayout; |
sewardj | 49651f4 | 2004-10-28 22:11:04 +0000 | [diff] [blame] | 123 | |
| 124 | |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 125 | /* Translate a basic block. */ |
| 126 | |
| 127 | typedef |
| 128 | enum { InsnSetX86, InsnSetARM } |
| 129 | InsnSet; |
| 130 | |
| 131 | typedef |
| 132 | enum { TransOK, TransAccessFail, TransOutputFull } |
| 133 | TranslateResult; |
| 134 | |
| 135 | extern |
sewardj | 887a11a | 2004-07-05 17:26:47 +0000 | [diff] [blame] | 136 | TranslateResult LibVEX_Translate ( |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 137 | /* The instruction sets we are translating from and to. */ |
| 138 | InsnSet iset_guest, |
| 139 | InsnSet iset_host, |
| 140 | /* IN: the block to translate, and its guest address. */ |
sewardj | 81bd550 | 2004-07-21 18:49:27 +0000 | [diff] [blame] | 141 | UChar* guest_bytes, |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 142 | Addr64 guest_bytes_addr, |
| 143 | /* OUT: the number of bytes actually read */ |
| 144 | Int* guest_bytes_read, |
| 145 | /* IN: a place to put the resulting code, and its size */ |
sewardj | 81bd550 | 2004-07-21 18:49:27 +0000 | [diff] [blame] | 146 | UChar* host_bytes, |
| 147 | Int host_bytes_size, |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 148 | /* OUT: how much of the output area is used. */ |
| 149 | Int* host_bytes_used, |
sewardj | 49651f4 | 2004-10-28 22:11:04 +0000 | [diff] [blame] | 150 | /* IN: optionally, two instrumentation functions. */ |
sewardj | cf78790 | 2004-11-03 09:08:33 +0000 | [diff] [blame] | 151 | IRBB* (*instrument1) ( IRBB*, VexGuestLayout*, IRType hWordTy ), |
| 152 | IRBB* (*instrument2) ( IRBB*, VexGuestLayout*, IRType hWordTy ), |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 153 | /* IN: optionally, an access check function for guest code. */ |
sewardj | 58800ff | 2004-07-28 01:51:10 +0000 | [diff] [blame] | 154 | Bool (*byte_accessible) ( Addr64 ), |
sewardj | f48ac19 | 2004-10-29 00:41:29 +0000 | [diff] [blame] | 155 | /* IN: debug: trace vex activity at various points */ |
| 156 | Int traceflags |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 157 | ); |
| 158 | |
| 159 | |
| 160 | /* Show accumulated statistics. */ |
| 161 | |
sewardj | 887a11a | 2004-07-05 17:26:47 +0000 | [diff] [blame] | 162 | extern void LibVEX_ShowStats ( void ); |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 163 | |
| 164 | |
sewardj | 81ec418 | 2004-10-25 23:15:52 +0000 | [diff] [blame] | 165 | |
| 166 | /* A note about baseblock layout. |
| 167 | |
| 168 | LibVEX defines the layout for the guest state, in the file |
| 169 | pub/libvex_guest_<arch>.h. The struct will have an 8-aligned size. |
| 170 | Each translated bb is assumed to be entered with a specified |
| 171 | register pointing at such a struct. Beyond that is a shadow |
| 172 | state area with the same size as the struct. Beyond that is |
| 173 | a spill area that LibVEX may spill into. It must have size |
| 174 | LibVEX_N_SPILL_BYTES, and this will be a 16-aligned number. |
| 175 | |
| 176 | On entry, the baseblock pointer register must be 8-aligned. |
| 177 | */ |
| 178 | |
| 179 | #define LibVEX_N_SPILL_BYTES 256 |
| 180 | |
| 181 | |
sewardj | 887a11a | 2004-07-05 17:26:47 +0000 | [diff] [blame] | 182 | #endif /* ndef __LIBVEX_H */ |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 183 | |
| 184 | /*---------------------------------------------------------------*/ |
sewardj | 887a11a | 2004-07-05 17:26:47 +0000 | [diff] [blame] | 185 | /*--- libvex.h ---*/ |
sewardj | ac9af02 | 2004-07-05 01:15:34 +0000 | [diff] [blame] | 186 | /*---------------------------------------------------------------*/ |