libvex_ir.h revision 636ad762e49597ef608323f27c7b8eb66962cd90
1 2/*---------------------------------------------------------------*/ 3/*--- ---*/ 4/*--- This file (libvex_ir.h) is ---*/ 5/*--- Copyright (c) 2004 OpenWorks LLP. All rights reserved. ---*/ 6/*--- ---*/ 7/*---------------------------------------------------------------*/ 8 9/* 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 36#ifndef __LIBVEX_IR_H 37#define __LIBVEX_IR_H 38 39#include "libvex_basictypes.h" 40 41 42/*---------------------------------------------------------------*/ 43/*--- Type definitions for the IR ---*/ 44/*---------------------------------------------------------------*/ 45 46/* ------------------ Types ------------------ */ 47 48typedef 49 enum { 50 Ity_INVALID=0x10FFF, 51 Ity_I1=0x11000, 52 Ity_I8, 53 Ity_I16, 54 Ity_I32, 55 Ity_I64, 56 Ity_F32, /* IEEE 754 float */ 57 Ity_F64, /* IEEE 754 double */ 58 Ity_V128 /* 128-bit SIMD */ 59 } 60 IRType; 61 62extern void ppIRType ( IRType ); 63extern Int sizeofIRType ( IRType ); 64 65 66/* ------------------ Constants ------------------ */ 67 68typedef 69 enum { 70 Ico_U1=0x12000, 71 Ico_U8, 72 Ico_U16, 73 Ico_U32, 74 Ico_U64, 75 Ico_F64, /* 64-bit IEEE754 floating */ 76 Ico_F64i, /* 64-bit unsigned int to be interpreted literally 77 as a IEEE754 double value. */ 78 Ico_V128 /* 128-bit restricted vector constant, with 1 bit for 79 each of 16 byte lanes */ 80 } 81 IRConstTag; 82 83typedef 84 struct _IRConst { 85 IRConstTag tag; 86 union { 87 Bool U1; 88 UChar U8; 89 UShort U16; 90 UInt U32; 91 ULong U64; 92 Double F64; 93 ULong F64i; 94 UShort V128; 95 } Ico; 96 } 97 IRConst; 98 99extern IRConst* IRConst_U1 ( Bool ); 100extern IRConst* IRConst_U8 ( UChar ); 101extern IRConst* IRConst_U16 ( UShort ); 102extern IRConst* IRConst_U32 ( UInt ); 103extern IRConst* IRConst_U64 ( ULong ); 104extern IRConst* IRConst_F64 ( Double ); 105extern IRConst* IRConst_F64i ( ULong ); 106extern IRConst* IRConst_V128 ( UShort ); 107 108extern IRConst* dopyIRConst ( IRConst* ); 109 110extern void ppIRConst ( IRConst* ); 111extern Bool eqIRConst ( IRConst*, IRConst* ); 112 113 114/* ------------------ Call targets ------------------ */ 115 116/* Describes a helper function to call. The name part is purely for 117 pretty printing and not actually used. regparms=n tells the back 118 end that the callee has been declared 119 "__attribute__((regparm(n)))". On some targets (x86) the back end 120 will need to construct a non-standard sequence to call a function 121 declared like this. 122 123 mcx_mask is a sop to Memcheck. It indicates which args should be 124 considered 'always defined' when lazily computing definedness of 125 the result. Bit 0 of mcx_mask corresponds to args[0], bit 1 to 126 args[1], etc. If a bit is set, the corresponding arg is excluded 127 (hence "x" in "mcx") from definedness checking. 128*/ 129 130typedef 131 struct { 132 Int regparms; 133 Char* name; 134 void* addr; 135 UInt mcx_mask; 136 } 137 IRCallee; 138 139extern IRCallee* mkIRCallee ( Int regparms, Char* name, void* addr ); 140 141extern IRCallee* dopyIRCallee ( IRCallee* ); 142 143extern void ppIRCallee ( IRCallee* ); 144 145 146/* ------------------ Guest state arrays ------------------ */ 147 148typedef 149 struct { 150 Int base; 151 IRType elemTy; 152 Int nElems; 153 } 154 IRArray; 155 156extern IRArray* mkIRArray ( Int, IRType, Int ); 157 158extern IRArray* dopyIRArray ( IRArray* ); 159 160extern void ppIRArray ( IRArray* ); 161extern Bool eqIRArray ( IRArray*, IRArray* ); 162 163 164/* ------------------ Temporaries ------------------ */ 165 166/* The IR optimiser relies on the fact that IRTemps are 32-bit 167 ints. Do not change them to be ints of any other size. */ 168typedef UInt IRTemp; 169 170extern void ppIRTemp ( IRTemp ); 171 172#define IRTemp_INVALID ((IRTemp)0xFFFFFFFF) 173 174 175/* ------------------ Binary and unary ops ------------------ */ 176 177typedef 178 enum { 179 /* Do not change this ordering. The IR generators 180 rely on (eg) Iop_Add64 == IopAdd8 + 3. */ 181 Iop_INVALID=0x13000, 182 Iop_Add8, Iop_Add16, Iop_Add32, Iop_Add64, 183 Iop_Sub8, Iop_Sub16, Iop_Sub32, Iop_Sub64, 184 /* Signless mul. MullS/MullU is elsewhere. */ 185 Iop_Mul8, Iop_Mul16, Iop_Mul32, Iop_Mul64, 186 Iop_Or8, Iop_Or16, Iop_Or32, Iop_Or64, 187 Iop_And8, Iop_And16, Iop_And32, Iop_And64, 188 Iop_Xor8, Iop_Xor16, Iop_Xor32, Iop_Xor64, 189 Iop_Shl8, Iop_Shl16, Iop_Shl32, Iop_Shl64, 190 Iop_Shr8, Iop_Shr16, Iop_Shr32, Iop_Shr64, 191 Iop_Sar8, Iop_Sar16, Iop_Sar32, Iop_Sar64, 192 /* Integer comparisons. */ 193 Iop_CmpEQ8, Iop_CmpEQ16, Iop_CmpEQ32, Iop_CmpEQ64, 194 Iop_CmpNE8, Iop_CmpNE16, Iop_CmpNE32, Iop_CmpNE64, 195 /* Tags for unary ops */ 196 Iop_Not8, Iop_Not16, Iop_Not32, Iop_Not64, 197 /* Widening multiplies */ 198 Iop_MullS8, Iop_MullS16, Iop_MullS32, 199 Iop_MullU8, Iop_MullU16, Iop_MullU32, 200 201 /* Wierdo integer stuff */ 202 Iop_Clz32, /* count leading zeroes */ 203 Iop_Ctz32, /* count trailing zeros */ 204 /* Ctz32/Clz32 are UNDEFINED when given arguments of zero. 205 You must ensure they are never given a zero argument. 206 */ 207 208 /* Ordering not important after here. */ 209 Iop_CmpLT32S, 210 Iop_CmpLE32S, 211 Iop_CmpLT32U, 212 Iop_CmpLE32U, 213 /* Division */ 214 /* TODO: clarify semantics wrt rounding, negative values, whatever */ 215 Iop_DivModU64to32, // :: I64,I32 -> I64 216 // of which lo half is div and hi half is mod 217 Iop_DivModS64to32, // ditto, signed 218 219 /* Widening conversions */ 220 Iop_8Uto16, Iop_8Uto32, Iop_16Uto32, Iop_32Uto64, 221 Iop_8Sto16, Iop_8Sto32, Iop_16Sto32, Iop_32Sto64, 222 /* Narrowing conversions */ 223 Iop_32to8, 224 /* 8 <-> 16 bit conversions */ 225 Iop_16to8, // :: I16 -> I8, low half 226 Iop_16HIto8, // :: I16 -> I8, high half 227 Iop_8HLto16, // :: (I8,I8) -> I16 228 /* 16 <-> 32 bit conversions */ 229 Iop_32to16, // :: I32 -> I16, low half 230 Iop_32HIto16, // :: I32 -> I16, high half 231 Iop_16HLto32, // :: (I16,I16) -> I32 232 /* 32 <-> 64 bit conversions */ 233 Iop_64to32, // :: I64 -> I32, low half 234 Iop_64HIto32, // :: I64 -> I32, high half 235 Iop_32HLto64, // :: (I32,I32) -> I64 236 /* 1-bit stuff */ 237 Iop_Not1, /* :: Ity_Bit -> Ity_Bit */ 238 Iop_32to1, /* :: Ity_I32 -> Ity_Bit, just select bit[0] */ 239 Iop_1Uto8, /* :: Ity_Bit -> Ity_I8, unsigned widen */ 240 Iop_1Uto32, /* :: Ity_Bit -> Ity_I32, unsigned widen */ 241 Iop_1Sto8, /* :: Ity_Bit -> Ity_I8, signed widen */ 242 Iop_1Sto16, /* :: Ity_Bit -> Ity_I16, signed widen */ 243 Iop_1Sto32, /* :: Ity_Bit -> Ity_I32, signed widen */ 244 Iop_1Sto64, /* :: Ity_Bit -> Ity_I64, signed widen */ 245 246 /* ------ Floating point. We try and be IEEE754 compliant. ------ */ 247 248 /* Binary operations mandated by IEEE754. */ 249 Iop_AddF64, Iop_SubF64, Iop_MulF64, Iop_DivF64, /* Iop_RemF64, */ 250 251 /* Binary ops supported by IA32 but not mandated by 754. */ 252 Iop_AtanF64, /* FPATAN, arctan(arg1/arg2) */ 253 Iop_Yl2xF64, /* FYL2X, arg1 * log2(arg2) */ 254 Iop_Yl2xp1F64, /* FYL2XP1, arg1 * log2(arg2+1.0) */ 255 Iop_PRemF64, /* FPREM, non-IEEE remainder(arg1/arg2) */ 256 Iop_PRemC3210F64, /* C3210 flags resulting from FPREM, :: I32 */ 257 Iop_PRem1F64, /* FPREM1, IEEE remainder(arg1/arg2) */ 258 Iop_PRem1C3210F64, /* C3210 flags resulting from FPREM1, :: I32 */ 259 Iop_ScaleF64, /* FSCALE, arg1 * (2^RoundTowardsZero(arg2)) */ 260 /* Note that on x86 guest, PRem1{C3210} has the same behaviour 261 as the IEEE mandated RemF64, except it is limited in the 262 range of its operand. Hence the partialness. */ 263 264 /* Unary operations mandated by IEEE754. */ 265 Iop_NegF64, Iop_SqrtF64, 266 267 /* Unary ops supported by IA32 but not mandated by 754. */ 268 Iop_AbsF64, /* FABS */ 269 Iop_SinF64, /* FSIN */ 270 Iop_CosF64, /* FCOS */ 271 Iop_TanF64, /* FTAN */ 272 Iop_2xm1F64, /* (2^arg - 1.0) */ 273 274 /* Comparison, yielding GT/LT/EQ/UN(ordered), as per the following: 275 0x45 Unordered 276 0x01 LT 277 0x00 GT 278 0x40 EQ 279 This just happens to be the Intel encoding. The values 280 are recorded in the type IRCmpF64Result. 281 */ 282 Iop_CmpF64, 283 284 /* --- Int to/from FP conversions. --- */ 285 /* For the most part, these take a first argument :: Ity_I32 286 (as IRRoundingMode) which is an indication of the rounding 287 mode to use, as per the following encoding: 288 00b to nearest (the default) 289 01b to -infinity 290 10b to +infinity 291 11b to zero 292 This just happens to be the Intel encoding. For reference only, 293 the PPC encoding is: 294 00b to nearest (the default) 295 01b to zero 296 10b to +infinity 297 11b to -infinity 298 Any PPC -> IR front end will have to translate these PPC 299 encodings to the standard encodings. 300 301 If one of these conversions gets an out-of-range condition, 302 or a NaN, as an argument, the result is host-defined. On x86 303 the "integer indefinite" value 0x80..00 is produced. 304 On PPC it is either 0x80..00 or 0x7F..FF depending on the sign 305 of the argument. 306 307 Rounding is required whenever the destination type cannot 308 represent exactly all values of the source type. 309 */ 310 Iop_F64toI16, /* IRRoundingMode(I32) x F64 -> I16 */ 311 Iop_F64toI32, /* IRRoundingMode(I32) x F64 -> I32 */ 312 Iop_F64toI64, /* IRRoundingMode(I32) x F64 -> I64 */ 313 314 Iop_I16toF64, /* I16 -> F64 */ 315 Iop_I32toF64, /* I32 -> F64 */ 316 Iop_I64toF64, /* IRRoundingMode(I32) x I64 -> F64 */ 317 318 Iop_F32toF64, /* F32 -> F64 */ 319 Iop_F64toF32, /* IRRoundingMode(I32) x F64 -> F32 */ 320 321 /* F64 -> F64, also takes an I32 first argument encoding the 322 rounding mode. */ 323 Iop_RoundF64, 324 325 /* Reinterpretation. Take an F64 and produce an I64 with 326 the same bit pattern, or vice versa. */ 327 Iop_ReinterpF64asI64, Iop_ReinterpI64asF64, 328 329 /* ------------------ 128-bit SIMD. ------------------ */ 330 331 /* 128-bit ops */ 332 Iop_And128, Iop_Or128, Iop_Xor128, 333 334 /* --- 32x4 vector FP --- */ 335 336 /* binary */ 337 Iop_Add32Fx4, Iop_Sub32Fx4, Iop_Mul32Fx4, Iop_Div32Fx4, 338 Iop_Max32Fx4, Iop_Min32Fx4, 339 Iop_CmpEQ32Fx4, Iop_CmpLT32Fx4, Iop_CmpLE32Fx4, Iop_CmpUN32Fx4, 340 341 /* unary */ 342 Iop_Recip32Fx4, Iop_Sqrt32Fx4, Iop_RSqrt32Fx4, 343 344 /* --- 32x4 lowest-lane-only scalar FP --- */ 345 346 /* In binary cases, upper 3/4 is copied from first operand. In 347 unary cases, upper 3/4 is copied from the operand. */ 348 349 /* binary */ 350 Iop_Add32F0x4, Iop_Sub32F0x4, Iop_Mul32F0x4, Iop_Div32F0x4, 351 Iop_Max32F0x4, Iop_Min32F0x4, 352 Iop_CmpEQ32F0x4, Iop_CmpLT32F0x4, Iop_CmpLE32F0x4, Iop_CmpUN32F0x4, 353 354 /* unary */ 355 Iop_Recip32F0x4, Iop_Sqrt32F0x4, Iop_RSqrt32F0x4, 356 357 /* --- 64x2 vector FP --- */ 358 359 /* binary */ 360 Iop_Add64Fx2, Iop_Sub64Fx2, Iop_Mul64Fx2, Iop_Div64Fx2, 361 Iop_Max64Fx2, Iop_Min64Fx2, 362 Iop_CmpEQ64Fx2, Iop_CmpLT64Fx2, Iop_CmpLE64Fx2, Iop_CmpUN64Fx2, 363 364 /* unary */ 365 Iop_Recip64Fx2, Iop_Sqrt64Fx2, Iop_RSqrt64Fx2, 366 367 /* --- 64x2 lowest-lane-only scalar FP --- */ 368 369 /* In binary cases, upper half is copied from first operand. In 370 unary cases, upper half is copied from the operand. */ 371 372 /* binary */ 373 Iop_Add64F0x2, Iop_Sub64F0x2, Iop_Mul64F0x2, Iop_Div64F0x2, 374 Iop_Max64F0x2, Iop_Min64F0x2, 375 Iop_CmpEQ64F0x2, Iop_CmpLT64F0x2, Iop_CmpLE64F0x2, Iop_CmpUN64F0x2, 376 377 /* unary */ 378 Iop_Recip64F0x2, Iop_Sqrt64F0x2, Iop_RSqrt64F0x2, 379 380 /* --- pack / unpack --- */ 381 382 /* 64 <-> 128 bit pack/unpack */ 383 Iop_128to64, // :: V128 -> I64, low half 384 Iop_128HIto64, // :: V128 -> I64, high half 385 Iop_64HLto128, // :: (I64,I64) -> V128 386 387 Iop_32Uto128, 388 Iop_64Uto128, 389 Iop_Set128lo32, 390 /* 128 -> 32 bit unpack */ 391 //Iop_128W3to32, // :: V128 -> I32, bits 127-96 392 //Iop_128W2to32, // :: V128 -> I32, bits 95-64 393 //Iop_128W1to32, // :: V128 -> I32, bits 63-32 394 //Iop_128W0to32 // :: V128 -> I32, bits 31-0 395 } 396 IROp; 397 398extern void ppIROp ( IROp ); 399 400 401/* Encoding of IEEE754-specified rounding modes in Float -> Int 402 conversions. This is the same as the encoding used by Intel IA32 403 to indicate x87 rounding mode. */ 404typedef 405 enum { Irrm_NEAREST=0, Irrm_NegINF=1, Irrm_PosINF=2, Irrm_ZERO=3 } 406 IRRoundingMode; 407 408/* Floating point comparison result values, as created by Iop_CmpF64. 409 This is also derived from what IA32 does. */ 410typedef 411 enum { 412 Ircr_UN = 0x45, 413 Ircr_LT = 0x01, 414 Ircr_GT = 0x00, 415 Ircr_EQ = 0x40 416 } 417 IRCmpF64Result; 418 419 420/* ------------------ Expressions ------------------ */ 421/* 422 Some details of expression semantics: 423 424 IRExpr_GetI (also IRStmt_PutI) 425 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 426 This carries two ints, which give the lowest and highest possible 427 byte offsets that the GetI can possibly reference. For example, if 428 the type is Ity_I32, and the Expr may have a value of M, M+4 or 429 M+8, where M is a translation-time known constant, then the low and 430 high limits are M and M+11 respectively. 431 432 PutI's limit values are interpreted identically. 433 434 The limit values are used by IR optimisers to establish 435 aliasing/non-aliasing between seperate GetI and PutI events, which 436 could be used to do reordering of them, or suchlike things. 437 Clearly it's critical to give the correct limit values -- this is 438 something that can't be automatically checked (in general), and so 439 the front-end writers must be very careful to tell the truth, since 440 not doing so could lead to obscure IR optimisation bugs. 441 442 IRExpr_CCall 443 ~~~~~~~~~~~~ 444 The name is the C helper function; the backends will call back to 445 the front ends to get the address of a host-code helper function to 446 be called. 447 448 The args are a NULL-terminated array of arguments. The stated 449 return IRType, and the implied argument types, must match that of 450 the function being called well enough so that the back end can 451 actually generate correct code for the call. 452 453 The called function **must** satisfy the following: 454 455 * no side effects -- must be a pure function, the result of which 456 depends only on the passed parameters. 457 458 * it may not look at, nor modify, any of the guest state since that 459 would hide guest state transitions from instrumenters 460 461 * it may not access guest memory, since that would hide guest 462 memory transactions from the instrumenters 463 464 This is restrictive, but makes the semantics clean, and does 465 not interfere with IR optimisation. 466 467 If you want to call a helper which can mess with guest state and/or 468 memory, instead use IRStmt_Dirty. This is a lot more flexible, but 469 you pay for that flexibility in that you have to give a bunch of 470 details about what the helper does (and you better be telling the 471 truth, otherwise any derived instrumentation will be wrong). Also 472 IRStmt_Dirty inhibits various IR optimisations and so can cause 473 quite poor code to be generated. Try to avoid it. 474*/ 475 476/* The possible kinds of expressions are as follows: */ 477typedef 478 enum { 479 Iex_Binder, /* Used only in pattern matching. 480 Not an expression. */ 481 Iex_Get, /* read guest state, fixed offset */ 482 Iex_GetI, /* read guest state, run-time offset */ 483 Iex_Tmp, /* value of temporary */ 484 Iex_Binop, /* binary operation */ 485 Iex_Unop, /* unary operation */ 486 Iex_LDle, /* little-endian read from memory */ 487 Iex_Const, /* constant-valued expression */ 488 Iex_Mux0X, /* ternary if-then-else operator (STRICT) */ 489 Iex_CCall /* call to pure (side-effect-free) helper fn */ 490 } 491 IRExprTag; 492 493typedef 494 struct _IRExpr { 495 IRExprTag tag; 496 union { 497 struct { 498 Int binder; 499 } Binder; 500 struct { 501 Int offset; 502 IRType ty; 503 } Get; 504 struct { 505 IRArray* descr; 506 struct _IRExpr* ix; 507 Int bias; 508 } GetI; 509 struct { 510 IRTemp tmp; 511 } Tmp; 512 struct { 513 IROp op; 514 struct _IRExpr* arg1; 515 struct _IRExpr* arg2; 516 } Binop; 517 struct { 518 IROp op; 519 struct _IRExpr* arg; 520 } Unop; 521 struct { 522 IRType ty; 523 struct _IRExpr* addr; 524 } LDle; 525 struct { 526 IRConst* con; 527 } Const; 528 struct { 529 IRCallee* cee; 530 IRType retty; 531 struct _IRExpr** args; 532 } CCall; 533 struct { 534 struct _IRExpr* cond; 535 struct _IRExpr* expr0; 536 struct _IRExpr* exprX; 537 } Mux0X; 538 } Iex; 539 } 540 IRExpr; 541 542extern IRExpr* IRExpr_Binder ( Int binder ); 543extern IRExpr* IRExpr_Get ( Int off, IRType ty ); 544extern IRExpr* IRExpr_GetI ( IRArray* descr, IRExpr* ix, Int bias ); 545extern IRExpr* IRExpr_Tmp ( IRTemp tmp ); 546extern IRExpr* IRExpr_Binop ( IROp op, IRExpr* arg1, IRExpr* arg2 ); 547extern IRExpr* IRExpr_Unop ( IROp op, IRExpr* arg ); 548extern IRExpr* IRExpr_LDle ( IRType ty, IRExpr* addr ); 549extern IRExpr* IRExpr_Const ( IRConst* con ); 550extern IRExpr* IRExpr_CCall ( IRCallee* cee, IRType retty, IRExpr** args ); 551extern IRExpr* IRExpr_Mux0X ( IRExpr* cond, IRExpr* expr0, IRExpr* exprX ); 552 553extern IRExpr* dopyIRExpr ( IRExpr* ); 554 555extern void ppIRExpr ( IRExpr* ); 556 557/* NULL-terminated IRExpr expression vectors, suitable for use as arg 558 lists in clean/dirty helper calls. */ 559 560extern IRExpr** mkIRExprVec_0 ( void ); 561extern IRExpr** mkIRExprVec_1 ( IRExpr* ); 562extern IRExpr** mkIRExprVec_2 ( IRExpr*, IRExpr* ); 563extern IRExpr** mkIRExprVec_3 ( IRExpr*, IRExpr*, IRExpr* ); 564extern IRExpr** mkIRExprVec_4 ( IRExpr*, IRExpr*, IRExpr*, IRExpr* ); 565extern IRExpr** mkIRExprVec_5 ( IRExpr*, IRExpr*, 566 IRExpr*, IRExpr*, IRExpr* ); 567 568extern IRExpr** sopyIRExprVec ( IRExpr** ); 569extern IRExpr** dopyIRExprVec ( IRExpr** ); 570 571/* Make a constant expression from the given host word taking into 572 account of course the host word size. */ 573extern IRExpr* mkIRExpr_HWord ( HWord ); 574 575/* Convenience function for constructing clean helper calls. */ 576extern 577IRExpr* mkIRExprCCall ( IRType retty, 578 Int regparms, Char* name, void* addr, 579 IRExpr** args ); 580 581 582inline static Bool isAtom ( IRExpr* e ) { 583 return e->tag == Iex_Tmp || e->tag == Iex_Const; 584} 585 586 587/* ------------------ Jump kinds ------------------ */ 588 589/* This describes hints which can be passed to the dispatcher at guest 590 control-flow transfer points. 591*/ 592typedef 593 enum { 594 Ijk_Boring=0x14000, /* not interesting; just goto next */ 595 Ijk_Call, /* guest is doing a call */ 596 Ijk_Ret, /* guest is doing a return */ 597 Ijk_ClientReq, /* do guest client req before continuing */ 598 Ijk_Syscall, /* do guest syscall before continuing */ 599 Ijk_Yield, /* client is yielding to thread scheduler */ 600 Ijk_EmWarn /* report emulation warning before continuing */ 601 } 602 IRJumpKind; 603 604extern void ppIRJumpKind ( IRJumpKind ); 605 606 607/* ------------------ Dirty helper calls ------------------ */ 608 609/* A dirty call is a flexible mechanism for calling a helper function 610 or procedure. The helper function may read, write or modify client 611 memory, and may read, write or modify client state. It can take 612 arguments and optionally return a value. It may return different 613 results and/or do different things when called repeated with the 614 same arguments, by means of storing private state. 615 616 If a value is returned, it is assigned to the nominated return 617 temporary. 618 619 Dirty calls are statements rather than expressions for obvious 620 reasons. If a dirty call is stated as writing guest state, any 621 values derived from the written parts of the guest state are 622 invalid. Similarly, if the dirty call is stated as writing 623 memory, any loaded values are invalidated by it. 624 625 In order that instrumentation is possible, the call must state, and 626 state correctly 627 628 * whether it reads, writes or modifies memory, and if so where 629 (only one chunk can be stated) 630 631 * whether it reads, writes or modifies guest state, and if so which 632 pieces (several pieces may be stated, and currently their extents 633 must be known at translation-time). 634 635 Normally, code is generated to pass just the args to the helper. 636 However, if .needsBBP is set, then an extra first argument is 637 passed, which is the baseblock pointer, so that the callee can 638 access the guest state. It is invalid for .nFxState to be zero 639 but .needsBBP to be True, since .nFxState==0 is a claim that the 640 call does not access guest state. 641 642 IMPORTANT NOTE re GUARDS: Dirty calls are strict, very strict. The 643 arguments are evaluated REGARDLESS of the guard value. It is 644 unspecified the relative order of arg evaluation and guard 645 evaluation. 646*/ 647 648#define VEX_N_FXSTATE 5 /* enough for FSAVE/FRSTOR on x86 */ 649 650typedef 651 enum { 652 Ifx_None = 0x15000, /* no effect */ 653 Ifx_Read, /* reads the resource */ 654 Ifx_Write, /* writes the resource */ 655 Ifx_Modify, /* modifies the resource */ 656 } 657 IREffect; 658 659extern void ppIREffect ( IREffect ); 660 661 662typedef 663 struct { 664 /* What to call, and details of args/results */ 665 IRCallee* cee; /* where to call */ 666 IRExpr* guard; /* :: Ity_Bit. Controls whether call happens */ 667 IRExpr** args; /* arg list, ends in NULL */ 668 IRTemp tmp; /* to assign result to, or IRTemp_INVALID if none */ 669 670 /* Mem effects; we allow only one R/W/M region to be stated */ 671 IREffect mFx; /* indicates memory effects, if any */ 672 IRExpr* mAddr; /* of access, or NULL if mFx==Ifx_None */ 673 Int mSize; /* of access, or zero if mFx==Ifx_None */ 674 675 /* Guest state effects; up to N allowed */ 676 Bool needsBBP; /* True => also pass guest state ptr to callee */ 677 Int nFxState; /* must be 0 .. VEX_N_FXSTATE */ 678 struct { 679 IREffect fx; /* read, write or modify? Ifx_None is invalid. */ 680 Int offset; 681 Int size; 682 } fxState[VEX_N_FXSTATE]; 683 } 684 IRDirty; 685 686extern void ppIRDirty ( IRDirty* ); 687extern IRDirty* emptyIRDirty ( void ); 688 689extern IRDirty* dopyIRDirty ( IRDirty* ); 690 691/* A handy function which takes some of the tedium out of constructing 692 dirty helper calls. The called function impliedly does not return 693 any value and has a constant-True guard. The call is marked as 694 accessing neither guest state nor memory (hence the "unsafe" 695 designation) -- you can mess with this later if need be. A 696 suitable IRCallee is constructed from the supplied bits. */ 697extern 698IRDirty* unsafeIRDirty_0_N ( Int regparms, Char* name, void* addr, 699 IRExpr** args ); 700 701/* Similarly, make a zero-annotation dirty call which returns a value, 702 and assign that to the given temp. */ 703extern 704IRDirty* unsafeIRDirty_1_N ( IRTemp dst, 705 Int regparms, Char* name, void* addr, 706 IRExpr** args ); 707 708 709/* ------------------ Statements ------------------ */ 710 711/* The possible kinds of statements are as follows: */ 712typedef 713 enum { 714 Ist_Put, /* write guest state, fixed offset */ 715 Ist_PutI, /* write guest state, run-time offset */ 716 Ist_Tmp, /* assign value to temporary */ 717 Ist_STle, /* little-endian write to memory */ 718 Ist_Dirty, /* call complex ("dirty") helper function */ 719 Ist_Exit /* conditional exit from BB */ 720 } 721 IRStmtTag; 722 723typedef 724 struct _IRStmt { 725 IRStmtTag tag; 726 union { 727 struct { 728 Int offset; 729 IRExpr* data; 730 } Put; 731 struct { 732 IRArray* descr; 733 IRExpr* ix; 734 Int bias; 735 IRExpr* data; 736 } PutI; 737 struct { 738 IRTemp tmp; 739 IRExpr* data; 740 } Tmp; 741 struct { 742 IRExpr* addr; 743 IRExpr* data; 744 } STle; 745 struct { 746 IRDirty* details; 747 } Dirty; 748 struct { 749 IRExpr* guard; 750 IRJumpKind jk; 751 IRConst* dst; 752 } Exit; 753 } Ist; 754 } 755 IRStmt; 756 757extern IRStmt* IRStmt_Put ( Int off, IRExpr* data ); 758extern IRStmt* IRStmt_PutI ( IRArray* descr, IRExpr* ix, Int bias, 759 IRExpr* data ); 760extern IRStmt* IRStmt_Tmp ( IRTemp tmp, IRExpr* data ); 761extern IRStmt* IRStmt_STle ( IRExpr* addr, IRExpr* data ); 762extern IRStmt* IRStmt_Dirty ( IRDirty* details ); 763extern IRStmt* IRStmt_Exit ( IRExpr* guard, IRJumpKind jk, IRConst* dst ); 764 765extern IRStmt* dopyIRStmt ( IRStmt* ); 766 767extern void ppIRStmt ( IRStmt* ); 768 769 770/* ------------------ Basic Blocks ------------------ */ 771 772/* A bunch of statements, expressions, etc, are incomplete without an 773 environment indicating the type of each IRTemp. So this provides 774 one. IR temporaries are really just unsigned ints and so this 775 provides an array, 0 .. n_types_used-1 of them. 776*/ 777typedef 778 struct { 779 IRType* types; 780 Int types_size; 781 Int types_used; 782 } 783 IRTypeEnv; 784 785extern IRTemp newIRTemp ( IRTypeEnv*, IRType ); 786extern IRTypeEnv* dopyIRTypeEnv ( IRTypeEnv* ); 787 788extern void ppIRTypeEnv ( IRTypeEnv* ); 789 790 791/* Basic blocks contain: 792 - A table giving a type for each temp 793 - An expandable array of statements 794 - An expression of type 32 or 64 bits, depending on the 795 guest's word size, indicating the next destination. 796 - An indication of any special actions (JumpKind) needed 797 for this final jump. 798*/ 799typedef 800 struct _IRBB { 801 IRTypeEnv* tyenv; 802 IRStmt** stmts; 803 Int stmts_size; 804 Int stmts_used; 805 IRExpr* next; 806 IRJumpKind jumpkind; 807 } 808 IRBB; 809 810extern IRBB* emptyIRBB ( void ); 811 812extern IRBB* dopyIRBB ( IRBB* ); 813 814extern void ppIRBB ( IRBB* ); 815 816extern void addStmtToIRBB ( IRBB*, IRStmt* ); 817 818 819/*---------------------------------------------------------------*/ 820/*--- Helper functions for the IR ---*/ 821/*---------------------------------------------------------------*/ 822 823/* For messing with IR type environments */ 824extern IRTypeEnv* emptyIRTypeEnv ( void ); 825 826/* What is the type of this expression? */ 827extern IRType typeOfIRConst ( IRConst* ); 828extern IRType typeOfIRTemp ( IRTypeEnv*, IRTemp ); 829extern IRType typeOfIRExpr ( IRTypeEnv*, IRExpr* ); 830 831/* Sanity check a BB of IR */ 832extern void sanityCheckIRBB ( IRBB* bb, IRType guest_word_size ); 833extern Bool isFlatIRStmt ( IRStmt* ); 834 835/* Is this any value actually in the enumeration 'IRType' ? */ 836extern Bool isPlausibleType ( IRType ty ); 837 838#endif /* ndef __LIBVEX_IR_H */ 839 840 841/*---------------------------------------------------------------*/ 842/*--- libvex_ir.h ---*/ 843/*---------------------------------------------------------------*/ 844