1 2 /*---------------------------------------------------------------*/ 3 /*--- begin libvex_guest_arm.h ---*/ 4 /*---------------------------------------------------------------*/ 5 6 /* 7 This file is part of Valgrind, a dynamic binary instrumentation 8 framework. 9 10 Copyright (C) 2004-2012 OpenWorks LLP 11 info@open-works.net 12 13 This program is free software; you can redistribute it and/or 14 modify it under the terms of the GNU General Public License as 15 published by the Free Software Foundation; either version 2 of the 16 License, or (at your option) any later version. 17 18 This program is distributed in the hope that it will be useful, but 19 WITHOUT ANY WARRANTY; without even the implied warranty of 20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 General Public License for more details. 22 23 You should have received a copy of the GNU General Public License 24 along with this program; if not, write to the Free Software 25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 26 02110-1301, USA. 27 28 The GNU General Public License is contained in the file COPYING. 29 */ 30 31 #ifndef __LIBVEX_PUB_GUEST_ARM_H 32 #define __LIBVEX_PUB_GUEST_ARM_H 33 34 #include "libvex_basictypes.h" 35 #include "libvex_emwarn.h" 36 37 38 /*---------------------------------------------------------------*/ 39 /*--- Vex's representation of the ARM CPU state. ---*/ 40 /*---------------------------------------------------------------*/ 41 42 typedef 43 struct { 44 /* 0 */ 45 /* Event check fail addr and counter. */ 46 UInt host_EvC_FAILADDR; /* 0 */ 47 UInt host_EvC_COUNTER; /* 4 */ 48 UInt guest_R0; 49 UInt guest_R1; 50 UInt guest_R2; 51 UInt guest_R3; 52 UInt guest_R4; 53 UInt guest_R5; 54 UInt guest_R6; 55 UInt guest_R7; 56 UInt guest_R8; 57 UInt guest_R9; 58 UInt guest_R10; 59 UInt guest_R11; 60 UInt guest_R12; 61 UInt guest_R13; /* stack pointer */ 62 UInt guest_R14; /* link register */ 63 UInt guest_R15T; 64 /* program counter[31:1] ++ [T], encoding both the current 65 instruction address and the ARM vs Thumb state of the 66 machine. T==1 is Thumb, T==0 is ARM. Hence values of the 67 form X--(31)--X1 denote a Thumb instruction at location 68 X--(31)--X0, values of the form X--(30)--X00 denote an ARM 69 instruction at precisely that address, and values of the form 70 X--(30)--10 are invalid since they would imply an ARM 71 instruction at a non-4-aligned address. */ 72 73 /* 4-word thunk used to calculate N(sign) Z(zero) C(carry, 74 unsigned overflow) and V(signed overflow) flags. */ 75 /* 72 */ 76 UInt guest_CC_OP; 77 UInt guest_CC_DEP1; 78 UInt guest_CC_DEP2; 79 UInt guest_CC_NDEP; 80 81 /* A 32-bit value which is used to compute the APSR.Q (sticky 82 saturation) flag, when necessary. If the value stored here 83 is zero, APSR.Q is currently zero. If it is any other value, 84 APSR.Q is currently one. */ 85 UInt guest_QFLAG32; 86 87 /* 32-bit values to represent APSR.GE0 .. GE3. Same 88 zero-vs-nonzero scheme as for QFLAG32. */ 89 UInt guest_GEFLAG0; 90 UInt guest_GEFLAG1; 91 UInt guest_GEFLAG2; 92 UInt guest_GEFLAG3; 93 94 /* Various pseudo-regs mandated by Vex or Valgrind. */ 95 /* Emulation warnings */ 96 UInt guest_EMWARN; 97 98 /* For clflush: record start and length of area to invalidate */ 99 UInt guest_TISTART; 100 UInt guest_TILEN; 101 102 /* Used to record the unredirected guest address at the start of 103 a translation whose start has been redirected. By reading 104 this pseudo-register shortly afterwards, the translation can 105 find out what the corresponding no-redirection address was. 106 Note, this is only set for wrap-style redirects, not for 107 replace-style ones. */ 108 UInt guest_NRADDR; 109 110 /* Needed for Darwin (but mandated for all guest architectures): 111 program counter at the last syscall insn (int 0x80/81/82, 112 sysenter, syscall, svc). Used when backing up to restart a 113 syscall that has been interrupted by a signal. */ 114 /* 124 */ 115 UInt guest_IP_AT_SYSCALL; 116 117 /* VFP state. D0 .. D15 must be 8-aligned. */ 118 /* 128 */ 119 ULong guest_D0; 120 ULong guest_D1; 121 ULong guest_D2; 122 ULong guest_D3; 123 ULong guest_D4; 124 ULong guest_D5; 125 ULong guest_D6; 126 ULong guest_D7; 127 ULong guest_D8; 128 ULong guest_D9; 129 ULong guest_D10; 130 ULong guest_D11; 131 ULong guest_D12; 132 ULong guest_D13; 133 ULong guest_D14; 134 ULong guest_D15; 135 ULong guest_D16; 136 ULong guest_D17; 137 ULong guest_D18; 138 ULong guest_D19; 139 ULong guest_D20; 140 ULong guest_D21; 141 ULong guest_D22; 142 ULong guest_D23; 143 ULong guest_D24; 144 ULong guest_D25; 145 ULong guest_D26; 146 ULong guest_D27; 147 ULong guest_D28; 148 ULong guest_D29; 149 ULong guest_D30; 150 ULong guest_D31; 151 UInt guest_FPSCR; 152 153 /* Not a town in Cornwall, but instead the TPIDRURO, on of the 154 Thread ID registers present in CP15 (the system control 155 coprocessor), register set "c13", register 3 (the User 156 Read-only Thread ID Register). arm-linux apparently uses it 157 to hold the TLS pointer for the thread. It's read-only in 158 user space. On Linux it is set in user space by various 159 thread-related syscalls. */ 160 UInt guest_TPIDRURO; 161 162 /* Representation of the Thumb IT state. ITSTATE is a 32-bit 163 value with 4 8-bit lanes. [7:0] pertain to the next insn to 164 execute, [15:8] for the one after that, etc. The per-insn 165 update to ITSTATE is to unsignedly shift it right 8 bits, 166 hence introducing a zero byte for the furthest ahead 167 instruction. As per the next para, a zero byte denotes the 168 condition ALWAYS. 169 170 Each byte lane has one of the two following formats: 171 172 cccc 0001 for an insn which is part of an IT block. cccc is 173 the guarding condition (standard ARM condition 174 code) XORd with 0xE, so as to cause 'cccc == 0' 175 to encode the condition ALWAYS. 176 177 0000 0000 for an insn which is not part of an IT block. 178 179 If the bottom 4 bits are zero then the top 4 must be too. 180 181 Given the byte lane for an instruction, the guarding 182 condition for the instruction is (((lane >> 4) & 0xF) ^ 0xE). 183 This is not as stupid as it sounds, because the front end 184 elides the shift. And the am-I-in-an-IT-block check is 185 (lane != 0). 186 187 In the case where (by whatever means) we know at JIT time 188 that an instruction is not in an IT block, we can prefix its 189 IR with assignments ITSTATE = 0 and hence have iropt fold out 190 the testing code. 191 192 The condition "is outside or last in IT block" corresponds 193 to the top 24 bits of ITSTATE being zero. 194 */ 195 UInt guest_ITSTATE; 196 197 /* Padding to make it have an 32-aligned size */ 198 UInt padding1; 199 UInt padding2; 200 UInt padding3; 201 UInt padding4; 202 UInt padding5; 203 } 204 VexGuestARMState; 205 206 207 /*---------------------------------------------------------------*/ 208 /*--- Utility functions for ARM guest stuff. ---*/ 209 /*---------------------------------------------------------------*/ 210 211 /* ALL THE FOLLOWING ARE VISIBLE TO LIBRARY CLIENT */ 212 213 /* Initialise all guest ARM state. */ 214 215 extern 216 void LibVEX_GuestARM_initialise ( /*OUT*/VexGuestARMState* vex_state ); 217 218 /* Calculate the ARM flag state from the saved data. */ 219 220 extern 221 UInt LibVEX_GuestARM_get_cpsr ( /*IN*/VexGuestARMState* vex_state ); 222 223 224 #endif /* ndef __LIBVEX_PUB_GUEST_ARM_H */ 225 226 227 /*---------------------------------------------------------------*/ 228 /*--- libvex_guest_arm.h ---*/ 229 /*---------------------------------------------------------------*/ 230