1 2 /*---------------------------------------------------------------*/ 3 /*--- begin guest_arm_defs.h ---*/ 4 /*---------------------------------------------------------------*/ 5 /* 6 This file is part of Valgrind, a dynamic binary instrumentation 7 framework. 8 9 Copyright (C) 2004-2017 OpenWorks LLP 10 info@open-works.net 11 12 This program is free software; you can redistribute it and/or 13 modify it under the terms of the GNU General Public License as 14 published by the Free Software Foundation; either version 2 of the 15 License, or (at your option) any later version. 16 17 This program is distributed in the hope that it will be useful, but 18 WITHOUT ANY WARRANTY; without even the implied warranty of 19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 General Public License for more details. 21 22 You should have received a copy of the GNU General Public License 23 along with this program; if not, write to the Free Software 24 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 25 02110-1301, USA. 26 27 The GNU General Public License is contained in the file COPYING. 28 */ 29 30 /* Only to be used within the guest-arm directory. */ 31 32 #ifndef __VEX_GUEST_ARM_DEFS_H 33 #define __VEX_GUEST_ARM_DEFS_H 34 35 #include "libvex_basictypes.h" 36 #include "guest_generic_bb_to_IR.h" // DisResult 37 38 /*---------------------------------------------------------*/ 39 /*--- arm to IR conversion ---*/ 40 /*---------------------------------------------------------*/ 41 42 /* Convert one ARM insn to IR. See the type DisOneInstrFn in 43 geust_generic_ bb_to_IR.h. */ 44 extern 45 DisResult disInstr_ARM ( IRSB* irbb, 46 Bool (*resteerOkFn) ( void*, Addr ), 47 Bool resteerCisOk, 48 void* callback_opaque, 49 const UChar* guest_code, 50 Long delta, 51 Addr guest_IP, 52 VexArch guest_arch, 53 const VexArchInfo* archinfo, 54 const VexAbiInfo* abiinfo, 55 VexEndness host_endness, 56 Bool sigill_diag ); 57 58 /* Used by the optimiser to specialise calls to helpers. */ 59 extern 60 IRExpr* guest_arm_spechelper ( const HChar* function_name, 61 IRExpr** args, 62 IRStmt** precedingStmts, 63 Int n_precedingStmts ); 64 65 /* Describes to the optimser which part of the guest state require 66 precise memory exceptions. This is logically part of the guest 67 state description. */ 68 extern 69 Bool guest_arm_state_requires_precise_mem_exns ( Int, Int, 70 VexRegisterUpdates ); 71 72 extern 73 VexGuestLayout armGuest_layout; 74 75 76 /*---------------------------------------------------------*/ 77 /*--- arm guest helpers ---*/ 78 /*---------------------------------------------------------*/ 79 80 /* --- CLEAN HELPERS --- */ 81 82 /* Calculate NZCV from the supplied thunk components, in the positions 83 they appear in the CPSR, viz bits 31:28 for N Z V C respectively. 84 Returned bits 27:0 are zero. */ 85 extern 86 UInt armg_calculate_flags_nzcv ( UInt cc_op, UInt cc_dep1, 87 UInt cc_dep2, UInt cc_dep3 ); 88 89 /* Calculate the C flag from the thunk components, in the lowest bit 90 of the word (bit 0). */ 91 extern 92 UInt armg_calculate_flag_c ( UInt cc_op, UInt cc_dep1, 93 UInt cc_dep2, UInt cc_dep3 ); 94 95 /* Calculate the V flag from the thunk components, in the lowest bit 96 of the word (bit 0). */ 97 extern 98 UInt armg_calculate_flag_v ( UInt cc_op, UInt cc_dep1, 99 UInt cc_dep2, UInt cc_dep3 ); 100 101 /* Calculate the specified condition from the thunk components, in the 102 lowest bit of the word (bit 0). */ 103 extern 104 UInt armg_calculate_condition ( UInt cond_n_op /* ARMCondcode << 4 | cc_op */, 105 UInt cc_dep1, 106 UInt cc_dep2, UInt cc_dep3 ); 107 108 /* Calculate the QC flag from the thunk components, in the lowest bit 109 of the word (bit 0). */ 110 extern 111 UInt armg_calculate_flag_qc ( UInt resL1, UInt resL2, 112 UInt resR1, UInt resR2 ); 113 114 /* --- DIRTY HELPERS --- */ 115 116 /* Confusingly, for the AES insns, the 32-bit ARM docs refers to the 117 one-and-only source register as 'm' whereas the 64-bit docs refer to 118 it as 'n'. We sidestep that here by just calling it 'arg32_*'. */ 119 120 extern 121 void armg_dirtyhelper_AESE ( 122 /*OUT*/V128* res, 123 UInt arg32_3, UInt arg32_2, UInt arg32_1, UInt arg32_0 124 ); 125 126 extern 127 void armg_dirtyhelper_AESD ( 128 /*OUT*/V128* res, 129 UInt arg32_3, UInt arg32_2, UInt arg32_1, UInt arg32_0 130 ); 131 132 extern 133 void armg_dirtyhelper_AESMC ( 134 /*OUT*/V128* res, 135 UInt arg32_3, UInt arg32_2, UInt arg32_1, UInt arg32_0 136 ); 137 138 extern 139 void armg_dirtyhelper_AESIMC ( 140 /*OUT*/V128* res, 141 UInt arg32_3, UInt arg32_2, UInt arg32_1, UInt arg32_0 142 ); 143 144 extern 145 void armg_dirtyhelper_SHA1C ( 146 /*OUT*/V128* res, 147 UInt argD3, UInt argD2, UInt argD1, UInt argD0, 148 UInt argN3, UInt argN2, UInt argN1, UInt argN0, 149 UInt argM3, UInt argM2, UInt argM1, UInt argM0 150 ); 151 152 extern 153 void armg_dirtyhelper_SHA1P ( 154 /*OUT*/V128* res, 155 UInt argD3, UInt argD2, UInt argD1, UInt argD0, 156 UInt argN3, UInt argN2, UInt argN1, UInt argN0, 157 UInt argM3, UInt argM2, UInt argM1, UInt argM0 158 ); 159 160 extern 161 void armg_dirtyhelper_SHA1M ( 162 /*OUT*/V128* res, 163 UInt argD3, UInt argD2, UInt argD1, UInt argD0, 164 UInt argN3, UInt argN2, UInt argN1, UInt argN0, 165 UInt argM3, UInt argM2, UInt argM1, UInt argM0 166 ); 167 168 extern 169 void armg_dirtyhelper_SHA1SU0 ( 170 /*OUT*/V128* res, 171 UInt argD3, UInt argD2, UInt argD1, UInt argD0, 172 UInt argN3, UInt argN2, UInt argN1, UInt argN0, 173 UInt argM3, UInt argM2, UInt argM1, UInt argM0 174 ); 175 176 extern 177 void armg_dirtyhelper_SHA256H ( 178 /*OUT*/V128* res, 179 UInt argD3, UInt argD2, UInt argD1, UInt argD0, 180 UInt argN3, UInt argN2, UInt argN1, UInt argN0, 181 UInt argM3, UInt argM2, UInt argM1, UInt argM0 182 ); 183 184 extern 185 void armg_dirtyhelper_SHA256H2 ( 186 /*OUT*/V128* res, 187 UInt argD3, UInt argD2, UInt argD1, UInt argD0, 188 UInt argN3, UInt argN2, UInt argN1, UInt argN0, 189 UInt argM3, UInt argM2, UInt argM1, UInt argM0 190 ); 191 192 extern 193 void armg_dirtyhelper_SHA256SU1 ( 194 /*OUT*/V128* res, 195 UInt argD3, UInt argD2, UInt argD1, UInt argD0, 196 UInt argN3, UInt argN2, UInt argN1, UInt argN0, 197 UInt argM3, UInt argM2, UInt argM1, UInt argM0 198 ); 199 200 extern 201 void armg_dirtyhelper_SHA1SU1 ( 202 /*OUT*/V128* res, 203 UInt argD3, UInt argD2, UInt argD1, UInt argD0, 204 UInt argM3, UInt argM2, UInt argM1, UInt argM0 205 ); 206 207 extern 208 void armg_dirtyhelper_SHA256SU0 ( 209 /*OUT*/V128* res, 210 UInt argD3, UInt argD2, UInt argD1, UInt argD0, 211 UInt argM3, UInt argM2, UInt argM1, UInt argM0 212 ); 213 214 extern 215 void armg_dirtyhelper_SHA1H ( 216 /*OUT*/V128* res, 217 UInt argM3, UInt argM2, UInt argM1, UInt argM0 218 ); 219 220 extern 221 void armg_dirtyhelper_VMULLP64 ( 222 /*OUT*/V128* res, 223 UInt argN1, UInt argN0, UInt argM1, UInt argM0 224 ); 225 226 227 /*---------------------------------------------------------*/ 228 /*--- Condition code stuff ---*/ 229 /*---------------------------------------------------------*/ 230 231 /* Flags masks. Defines positions of flags bits in the CPSR. */ 232 #define ARMG_CC_SHIFT_N 31 233 #define ARMG_CC_SHIFT_Z 30 234 #define ARMG_CC_SHIFT_C 29 235 #define ARMG_CC_SHIFT_V 28 236 #define ARMG_CC_SHIFT_Q 27 237 238 #define ARMG_CC_MASK_N (1 << ARMG_CC_SHIFT_N) 239 #define ARMG_CC_MASK_Z (1 << ARMG_CC_SHIFT_Z) 240 #define ARMG_CC_MASK_C (1 << ARMG_CC_SHIFT_C) 241 #define ARMG_CC_MASK_V (1 << ARMG_CC_SHIFT_V) 242 #define ARMG_CC_MASK_Q (1 << ARMG_CC_SHIFT_Q) 243 244 /* Flag thunk descriptors. A four-word thunk is used to record 245 details of the most recent flag-setting operation, so NZCV can 246 be computed later if needed. 247 248 The four words are: 249 250 CC_OP, which describes the operation. 251 252 CC_DEP1, CC_DEP2, CC_DEP3. These are arguments to the 253 operation. We want set up the mcx_masks in flag helper calls 254 involving these fields so that Memcheck "believes" that the 255 resulting flags are data-dependent on both CC_DEP1 and 256 CC_DEP2. Hence the name DEP. 257 258 When building the thunk, it is always necessary to write words into 259 CC_DEP1/2/3, even if those args are not used given the 260 CC_OP field. This is important because otherwise Memcheck could 261 give false positives as it does not understand the relationship 262 between the CC_OP field and CC_DEP1/2/3, and so believes 263 that the definedness of the stored flags always depends on 264 all 3 DEP values. 265 266 Fields carrying only 1 or 2 bits of useful information (old_C, 267 shifter_co, old_V, oldC:oldV) must have their top 31 or 30 bits 268 (respectively) zero. The text "31x0:" or "30x0:" denotes this. 269 270 A summary of the field usages is: 271 272 OP DEP1 DEP2 DEP3 273 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 274 275 OP_COPY curr_NZCV:28x0 unused unused 276 OP_ADD argL argR unused 277 OP_SUB argL argR unused 278 OP_ADC argL argR 31x0:old_C 279 OP_SBB argL argR 31x0:old_C 280 OP_LOGIC result 31x0:shifter_co 31x0:old_V 281 OP_MUL result unused 30x0:old_C:old_V 282 OP_MULL resLO32 resHI32 30x0:old_C:old_V 283 */ 284 285 enum { 286 ARMG_CC_OP_COPY=0, /* DEP1 = NZCV in 31:28, DEP2 = 0, DEP3 = 0 287 just copy DEP1 to output */ 288 289 ARMG_CC_OP_ADD, /* DEP1 = argL (Rn), DEP2 = argR (shifter_op), 290 DEP3 = 0 */ 291 292 ARMG_CC_OP_SUB, /* DEP1 = argL (Rn), DEP2 = argR (shifter_op), 293 DEP3 = 0 */ 294 295 ARMG_CC_OP_ADC, /* DEP1 = argL (Rn), DEP2 = arg2 (shifter_op), 296 DEP3 = oldC (in LSB) */ 297 298 ARMG_CC_OP_SBB, /* DEP1 = argL (Rn), DEP2 = arg2 (shifter_op), 299 DEP3 = oldC (in LSB) */ 300 301 ARMG_CC_OP_LOGIC, /* DEP1 = result, DEP2 = shifter_carry_out (in LSB), 302 DEP3 = old V flag (in LSB) */ 303 304 ARMG_CC_OP_MUL, /* DEP1 = result, DEP2 = 0, DEP3 = oldC:old_V 305 (in bits 1:0) */ 306 307 ARMG_CC_OP_MULL, /* DEP1 = resLO32, DEP2 = resHI32, DEP3 = oldC:old_V 308 (in bits 1:0) */ 309 310 ARMG_CC_OP_NUMBER 311 }; 312 313 /* XXXX because of the calling conventions for 314 armg_calculate_condition, all this OP values MUST be in the range 315 0 .. 15 only (viz, 4-bits). */ 316 317 318 319 /* Defines conditions which we can ask for (ARM ARM 2e page A3-6) */ 320 321 typedef 322 enum { 323 ARMCondEQ = 0, /* equal : Z=1 */ 324 ARMCondNE = 1, /* not equal : Z=0 */ 325 326 ARMCondHS = 2, /* >=u (higher or same) : C=1 */ 327 ARMCondLO = 3, /* <u (lower) : C=0 */ 328 329 ARMCondMI = 4, /* minus (negative) : N=1 */ 330 ARMCondPL = 5, /* plus (zero or +ve) : N=0 */ 331 332 ARMCondVS = 6, /* overflow : V=1 */ 333 ARMCondVC = 7, /* no overflow : V=0 */ 334 335 ARMCondHI = 8, /* >u (higher) : C=1 && Z=0 */ 336 ARMCondLS = 9, /* <=u (lower or same) : C=0 || Z=1 */ 337 338 ARMCondGE = 10, /* >=s (signed greater or equal) : N=V */ 339 ARMCondLT = 11, /* <s (signed less than) : N!=V */ 340 341 ARMCondGT = 12, /* >s (signed greater) : Z=0 && N=V */ 342 ARMCondLE = 13, /* <=s (signed less or equal) : Z=1 || N!=V */ 343 344 ARMCondAL = 14, /* always (unconditional) : 1 */ 345 ARMCondNV = 15 /* never (unconditional): : 0 */ 346 /* NB: ARM have deprecated the use of the NV condition code. 347 You are now supposed to use MOV R0,R0 as a noop rather than 348 MOVNV R0,R0 as was previously recommended. Future processors 349 may have the NV condition code reused to do other things. */ 350 } 351 ARMCondcode; 352 353 #endif /* ndef __VEX_GUEST_ARM_DEFS_H */ 354 355 /*---------------------------------------------------------------*/ 356 /*--- end guest_arm_defs.h ---*/ 357 /*---------------------------------------------------------------*/ 358