1 2 /*---------------------------------------------------------------*/ 3 /*--- begin guest_ppc_helpers.c ---*/ 4 /*---------------------------------------------------------------*/ 5 6 /* 7 This file is part of Valgrind, a dynamic binary instrumentation 8 framework. 9 10 Copyright (C) 2004-2010 OpenWorks LLP 11 info (at) 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 Neither the names of the U.S. Department of Energy nor the 31 University of California nor the names of its contributors may be 32 used to endorse or promote products derived from this software 33 without prior written permission. 34 */ 35 36 #include "libvex_basictypes.h" 37 #include "libvex_emwarn.h" 38 #include "libvex_guest_ppc32.h" 39 #include "libvex_guest_ppc64.h" 40 #include "libvex_ir.h" 41 #include "libvex.h" 42 43 #include "main_util.h" 44 #include "guest_generic_bb_to_IR.h" 45 #include "guest_ppc_defs.h" 46 47 48 /* This file contains helper functions for ppc32 and ppc64 guest code. 49 Calls to these functions are generated by the back end. These 50 calls are of course in the host machine code and this file will be 51 compiled to host machine code, so that all makes sense. 52 53 Only change the signatures of these helper functions very 54 carefully. If you change the signature here, you'll have to change 55 the parameters passed to it in the IR calls constructed by 56 guest-ppc/toIR.c. 57 */ 58 59 60 /*---------------------------------------------------------------*/ 61 /*--- Misc integer helpers. ---*/ 62 /*---------------------------------------------------------------*/ 63 64 /* CALLED FROM GENERATED CODE */ 65 /* DIRTY HELPER (non-referentially-transparent) */ 66 /* Horrible hack. On non-ppc platforms, return 1. */ 67 /* Reads a complete, consistent 64-bit TB value. */ 68 ULong ppcg_dirtyhelper_MFTB ( void ) 69 { 70 # if defined(__powerpc__) || defined(_AIX) 71 ULong res; 72 UInt lo, hi1, hi2; 73 while (1) { 74 __asm__ __volatile__ ("\n" 75 "\tmftbu %0\n" 76 "\tmftb %1\n" 77 "\tmftbu %2\n" 78 : "=r" (hi1), "=r" (lo), "=r" (hi2) 79 ); 80 if (hi1 == hi2) break; 81 } 82 res = ((ULong)hi1) << 32; 83 res |= (ULong)lo; 84 return res; 85 # else 86 return 1ULL; 87 # endif 88 } 89 90 91 /* CALLED FROM GENERATED CODE */ 92 /* DIRTY HELPER (non-referentially transparent) */ 93 UInt ppc32g_dirtyhelper_MFSPR_268_269 ( UInt r269 ) 94 { 95 # if defined(__powerpc__) || defined(_AIX) 96 UInt spr; 97 if (r269) { 98 __asm__ __volatile__("mfspr %0,269" : "=b"(spr)); 99 } else { 100 __asm__ __volatile__("mfspr %0,268" : "=b"(spr)); 101 } 102 return spr; 103 # else 104 return 0; 105 # endif 106 } 107 108 109 /* CALLED FROM GENERATED CODE */ 110 /* DIRTY HELPER (I'm not really sure what the side effects are) */ 111 UInt ppc32g_dirtyhelper_MFSPR_287 ( void ) 112 { 113 # if defined(__powerpc__) || defined(_AIX) 114 UInt spr; 115 __asm__ __volatile__("mfspr %0,287" : "=b"(spr)); 116 return spr; 117 # else 118 return 0; 119 # endif 120 } 121 122 123 /* CALLED FROM GENERATED CODE */ 124 /* DIRTY HELPER (reads guest state, writes guest mem) */ 125 void ppc32g_dirtyhelper_LVS ( VexGuestPPC32State* gst, 126 UInt vD_off, UInt sh, UInt shift_right ) 127 { 128 static 129 UChar ref[32] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 130 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 131 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 132 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }; 133 U128* pU128_src; 134 U128* pU128_dst; 135 136 vassert( vD_off <= sizeof(VexGuestPPC32State)-8 ); 137 vassert( sh <= 15 ); 138 vassert( shift_right <= 1 ); 139 if (shift_right) 140 sh = 16-sh; 141 /* else shift left */ 142 143 pU128_src = (U128*)&ref[sh]; 144 pU128_dst = (U128*)( ((UChar*)gst) + vD_off ); 145 146 (*pU128_dst)[0] = (*pU128_src)[0]; 147 (*pU128_dst)[1] = (*pU128_src)[1]; 148 (*pU128_dst)[2] = (*pU128_src)[2]; 149 (*pU128_dst)[3] = (*pU128_src)[3]; 150 } 151 152 /* CALLED FROM GENERATED CODE */ 153 /* DIRTY HELPER (reads guest state, writes guest mem) */ 154 void ppc64g_dirtyhelper_LVS ( VexGuestPPC64State* gst, 155 UInt vD_off, UInt sh, UInt shift_right ) 156 { 157 UChar ref[32]; 158 ULong i; 159 /* ref[] used to be a static const array, but this doesn't work on 160 ppc64 because VEX doesn't load the TOC pointer for the call here, 161 and so we wind up picking up some totally random other data. 162 (It's a wonder we don't segfault.) So, just to be clear, this 163 "fix" (vex r2073) is really a kludgearound for the fact that 164 VEX's 64-bit ppc code generation doesn't provide a valid TOC 165 pointer for helper function calls. Ick. (Bug 250038) */ 166 for (i = 0; i < 32; i++) ref[i] = i; 167 168 U128* pU128_src; 169 U128* pU128_dst; 170 171 vassert( vD_off <= sizeof(VexGuestPPC64State)-8 ); 172 vassert( sh <= 15 ); 173 vassert( shift_right <= 1 ); 174 if (shift_right) 175 sh = 16-sh; 176 /* else shift left */ 177 178 pU128_src = (U128*)&ref[sh]; 179 pU128_dst = (U128*)( ((UChar*)gst) + vD_off ); 180 181 (*pU128_dst)[0] = (*pU128_src)[0]; 182 (*pU128_dst)[1] = (*pU128_src)[1]; 183 (*pU128_dst)[2] = (*pU128_src)[2]; 184 (*pU128_dst)[3] = (*pU128_src)[3]; 185 } 186 187 188 /* Helper-function specialiser. */ 189 190 IRExpr* guest_ppc32_spechelper ( HChar* function_name, 191 IRExpr** args, 192 IRStmt** precedingStmts, 193 Int n_precedingStmts ) 194 { 195 return NULL; 196 } 197 198 IRExpr* guest_ppc64_spechelper ( HChar* function_name, 199 IRExpr** args, 200 IRStmt** precedingStmts, 201 Int n_precedingStmts ) 202 { 203 return NULL; 204 } 205 206 207 /*----------------------------------------------*/ 208 /*--- The exported fns .. ---*/ 209 /*----------------------------------------------*/ 210 211 /* VISIBLE TO LIBVEX CLIENT */ 212 UInt LibVEX_GuestPPC32_get_CR ( /*IN*/VexGuestPPC32State* vex_state ) 213 { 214 # define FIELD(_n) \ 215 ( ( (UInt) \ 216 ( (vex_state->guest_CR##_n##_321 & (7<<1)) \ 217 | (vex_state->guest_CR##_n##_0 & 1) \ 218 ) \ 219 ) \ 220 << (4 * (7-(_n))) \ 221 ) 222 223 return 224 FIELD(0) | FIELD(1) | FIELD(2) | FIELD(3) 225 | FIELD(4) | FIELD(5) | FIELD(6) | FIELD(7); 226 227 # undef FIELD 228 } 229 230 231 /* VISIBLE TO LIBVEX CLIENT */ 232 /* Note: %CR is 32 bits even for ppc64 */ 233 UInt LibVEX_GuestPPC64_get_CR ( /*IN*/VexGuestPPC64State* vex_state ) 234 { 235 # define FIELD(_n) \ 236 ( ( (UInt) \ 237 ( (vex_state->guest_CR##_n##_321 & (7<<1)) \ 238 | (vex_state->guest_CR##_n##_0 & 1) \ 239 ) \ 240 ) \ 241 << (4 * (7-(_n))) \ 242 ) 243 244 return 245 FIELD(0) | FIELD(1) | FIELD(2) | FIELD(3) 246 | FIELD(4) | FIELD(5) | FIELD(6) | FIELD(7); 247 248 # undef FIELD 249 } 250 251 252 /* VISIBLE TO LIBVEX CLIENT */ 253 void LibVEX_GuestPPC32_put_CR ( UInt cr_native, 254 /*OUT*/VexGuestPPC32State* vex_state ) 255 { 256 UInt t; 257 258 # define FIELD(_n) \ 259 do { \ 260 t = cr_native >> (4*(7-(_n))); \ 261 vex_state->guest_CR##_n##_0 = toUChar(t & 1); \ 262 vex_state->guest_CR##_n##_321 = toUChar(t & (7<<1)); \ 263 } while (0) 264 265 FIELD(0); 266 FIELD(1); 267 FIELD(2); 268 FIELD(3); 269 FIELD(4); 270 FIELD(5); 271 FIELD(6); 272 FIELD(7); 273 274 # undef FIELD 275 } 276 277 278 /* VISIBLE TO LIBVEX CLIENT */ 279 /* Note: %CR is 32 bits even for ppc64 */ 280 void LibVEX_GuestPPC64_put_CR ( UInt cr_native, 281 /*OUT*/VexGuestPPC64State* vex_state ) 282 { 283 UInt t; 284 285 # define FIELD(_n) \ 286 do { \ 287 t = cr_native >> (4*(7-(_n))); \ 288 vex_state->guest_CR##_n##_0 = toUChar(t & 1); \ 289 vex_state->guest_CR##_n##_321 = toUChar(t & (7<<1)); \ 290 } while (0) 291 292 FIELD(0); 293 FIELD(1); 294 FIELD(2); 295 FIELD(3); 296 FIELD(4); 297 FIELD(5); 298 FIELD(6); 299 FIELD(7); 300 301 # undef FIELD 302 } 303 304 305 /* VISIBLE TO LIBVEX CLIENT */ 306 UInt LibVEX_GuestPPC32_get_XER ( /*IN*/VexGuestPPC32State* vex_state ) 307 { 308 UInt w = 0; 309 w |= ( ((UInt)vex_state->guest_XER_BC) & 0xFF ); 310 w |= ( (((UInt)vex_state->guest_XER_SO) & 0x1) << 31 ); 311 w |= ( (((UInt)vex_state->guest_XER_OV) & 0x1) << 30 ); 312 w |= ( (((UInt)vex_state->guest_XER_CA) & 0x1) << 29 ); 313 return w; 314 } 315 316 317 /* VISIBLE TO LIBVEX CLIENT */ 318 /* Note: %XER is 32 bits even for ppc64 */ 319 UInt LibVEX_GuestPPC64_get_XER ( /*IN*/VexGuestPPC64State* vex_state ) 320 { 321 UInt w = 0; 322 w |= ( ((UInt)vex_state->guest_XER_BC) & 0xFF ); 323 w |= ( (((UInt)vex_state->guest_XER_SO) & 0x1) << 31 ); 324 w |= ( (((UInt)vex_state->guest_XER_OV) & 0x1) << 30 ); 325 w |= ( (((UInt)vex_state->guest_XER_CA) & 0x1) << 29 ); 326 return w; 327 } 328 329 330 /* VISIBLE TO LIBVEX CLIENT */ 331 void LibVEX_GuestPPC32_put_XER ( UInt xer_native, 332 /*OUT*/VexGuestPPC32State* vex_state ) 333 { 334 vex_state->guest_XER_BC = toUChar(xer_native & 0xFF); 335 vex_state->guest_XER_SO = toUChar((xer_native >> 31) & 0x1); 336 vex_state->guest_XER_OV = toUChar((xer_native >> 30) & 0x1); 337 vex_state->guest_XER_CA = toUChar((xer_native >> 29) & 0x1); 338 } 339 340 /* VISIBLE TO LIBVEX CLIENT */ 341 /* Note: %XER is 32 bits even for ppc64 */ 342 void LibVEX_GuestPPC64_put_XER ( UInt xer_native, 343 /*OUT*/VexGuestPPC64State* vex_state ) 344 { 345 vex_state->guest_XER_BC = toUChar(xer_native & 0xFF); 346 vex_state->guest_XER_SO = toUChar((xer_native >> 31) & 0x1); 347 vex_state->guest_XER_OV = toUChar((xer_native >> 30) & 0x1); 348 vex_state->guest_XER_CA = toUChar((xer_native >> 29) & 0x1); 349 } 350 351 /* VISIBLE TO LIBVEX CLIENT */ 352 void LibVEX_GuestPPC32_initialise ( /*OUT*/VexGuestPPC32State* vex_state ) 353 { 354 Int i; 355 vex_state->guest_GPR0 = 0; 356 vex_state->guest_GPR1 = 0; 357 vex_state->guest_GPR2 = 0; 358 vex_state->guest_GPR3 = 0; 359 vex_state->guest_GPR4 = 0; 360 vex_state->guest_GPR5 = 0; 361 vex_state->guest_GPR6 = 0; 362 vex_state->guest_GPR7 = 0; 363 vex_state->guest_GPR8 = 0; 364 vex_state->guest_GPR9 = 0; 365 vex_state->guest_GPR10 = 0; 366 vex_state->guest_GPR11 = 0; 367 vex_state->guest_GPR12 = 0; 368 vex_state->guest_GPR13 = 0; 369 vex_state->guest_GPR14 = 0; 370 vex_state->guest_GPR15 = 0; 371 vex_state->guest_GPR16 = 0; 372 vex_state->guest_GPR17 = 0; 373 vex_state->guest_GPR18 = 0; 374 vex_state->guest_GPR19 = 0; 375 vex_state->guest_GPR20 = 0; 376 vex_state->guest_GPR21 = 0; 377 vex_state->guest_GPR22 = 0; 378 vex_state->guest_GPR23 = 0; 379 vex_state->guest_GPR24 = 0; 380 vex_state->guest_GPR25 = 0; 381 vex_state->guest_GPR26 = 0; 382 vex_state->guest_GPR27 = 0; 383 vex_state->guest_GPR28 = 0; 384 vex_state->guest_GPR29 = 0; 385 vex_state->guest_GPR30 = 0; 386 vex_state->guest_GPR31 = 0; 387 388 vex_state->guest_FPR0 = 0; 389 vex_state->guest_FPR1 = 0; 390 vex_state->guest_FPR2 = 0; 391 vex_state->guest_FPR3 = 0; 392 vex_state->guest_FPR4 = 0; 393 vex_state->guest_FPR5 = 0; 394 vex_state->guest_FPR6 = 0; 395 vex_state->guest_FPR7 = 0; 396 vex_state->guest_FPR8 = 0; 397 vex_state->guest_FPR9 = 0; 398 vex_state->guest_FPR10 = 0; 399 vex_state->guest_FPR11 = 0; 400 vex_state->guest_FPR12 = 0; 401 vex_state->guest_FPR13 = 0; 402 vex_state->guest_FPR14 = 0; 403 vex_state->guest_FPR15 = 0; 404 vex_state->guest_FPR16 = 0; 405 vex_state->guest_FPR17 = 0; 406 vex_state->guest_FPR18 = 0; 407 vex_state->guest_FPR19 = 0; 408 vex_state->guest_FPR20 = 0; 409 vex_state->guest_FPR21 = 0; 410 vex_state->guest_FPR22 = 0; 411 vex_state->guest_FPR23 = 0; 412 vex_state->guest_FPR24 = 0; 413 vex_state->guest_FPR25 = 0; 414 vex_state->guest_FPR26 = 0; 415 vex_state->guest_FPR27 = 0; 416 vex_state->guest_FPR28 = 0; 417 vex_state->guest_FPR29 = 0; 418 vex_state->guest_FPR30 = 0; 419 vex_state->guest_FPR31 = 0; 420 421 /* Initialise the vector state. */ 422 # define VECZERO(_vr) _vr[0]=_vr[1]=_vr[2]=_vr[3] = 0; 423 424 VECZERO(vex_state->guest_VR0 ); 425 VECZERO(vex_state->guest_VR1 ); 426 VECZERO(vex_state->guest_VR2 ); 427 VECZERO(vex_state->guest_VR3 ); 428 VECZERO(vex_state->guest_VR4 ); 429 VECZERO(vex_state->guest_VR5 ); 430 VECZERO(vex_state->guest_VR6 ); 431 VECZERO(vex_state->guest_VR7 ); 432 VECZERO(vex_state->guest_VR8 ); 433 VECZERO(vex_state->guest_VR9 ); 434 VECZERO(vex_state->guest_VR10); 435 VECZERO(vex_state->guest_VR11); 436 VECZERO(vex_state->guest_VR12); 437 VECZERO(vex_state->guest_VR13); 438 VECZERO(vex_state->guest_VR14); 439 VECZERO(vex_state->guest_VR15); 440 VECZERO(vex_state->guest_VR16); 441 VECZERO(vex_state->guest_VR17); 442 VECZERO(vex_state->guest_VR18); 443 VECZERO(vex_state->guest_VR19); 444 VECZERO(vex_state->guest_VR20); 445 VECZERO(vex_state->guest_VR21); 446 VECZERO(vex_state->guest_VR22); 447 VECZERO(vex_state->guest_VR23); 448 VECZERO(vex_state->guest_VR24); 449 VECZERO(vex_state->guest_VR25); 450 VECZERO(vex_state->guest_VR26); 451 VECZERO(vex_state->guest_VR27); 452 VECZERO(vex_state->guest_VR28); 453 VECZERO(vex_state->guest_VR29); 454 VECZERO(vex_state->guest_VR30); 455 VECZERO(vex_state->guest_VR31); 456 457 # undef VECZERO 458 459 vex_state->guest_CIA = 0; 460 vex_state->guest_LR = 0; 461 vex_state->guest_CTR = 0; 462 463 vex_state->guest_XER_SO = 0; 464 vex_state->guest_XER_OV = 0; 465 vex_state->guest_XER_CA = 0; 466 vex_state->guest_XER_BC = 0; 467 468 vex_state->guest_CR0_321 = 0; 469 vex_state->guest_CR0_0 = 0; 470 vex_state->guest_CR1_321 = 0; 471 vex_state->guest_CR1_0 = 0; 472 vex_state->guest_CR2_321 = 0; 473 vex_state->guest_CR2_0 = 0; 474 vex_state->guest_CR3_321 = 0; 475 vex_state->guest_CR3_0 = 0; 476 vex_state->guest_CR4_321 = 0; 477 vex_state->guest_CR4_0 = 0; 478 vex_state->guest_CR5_321 = 0; 479 vex_state->guest_CR5_0 = 0; 480 vex_state->guest_CR6_321 = 0; 481 vex_state->guest_CR6_0 = 0; 482 vex_state->guest_CR7_321 = 0; 483 vex_state->guest_CR7_0 = 0; 484 485 vex_state->guest_FPROUND = (UInt)PPCrm_NEAREST; 486 487 vex_state->guest_VRSAVE = 0; 488 489 vex_state->guest_VSCR = 0x0; // Non-Java mode = 0 490 491 vex_state->guest_EMWARN = EmWarn_NONE; 492 493 vex_state->guest_TISTART = 0; 494 vex_state->guest_TILEN = 0; 495 496 vex_state->guest_NRADDR = 0; 497 vex_state->guest_NRADDR_GPR2 = 0; 498 499 vex_state->guest_REDIR_SP = -1; 500 for (i = 0; i < VEX_GUEST_PPC32_REDIR_STACK_SIZE; i++) 501 vex_state->guest_REDIR_STACK[i] = 0; 502 503 vex_state->guest_IP_AT_SYSCALL = 0; 504 vex_state->guest_SPRG3_RO = 0; 505 } 506 507 508 /* VISIBLE TO LIBVEX CLIENT */ 509 void LibVEX_GuestPPC64_initialise ( /*OUT*/VexGuestPPC64State* vex_state ) 510 { 511 Int i; 512 vex_state->guest_GPR0 = 0; 513 vex_state->guest_GPR1 = 0; 514 vex_state->guest_GPR2 = 0; 515 vex_state->guest_GPR3 = 0; 516 vex_state->guest_GPR4 = 0; 517 vex_state->guest_GPR5 = 0; 518 vex_state->guest_GPR6 = 0; 519 vex_state->guest_GPR7 = 0; 520 vex_state->guest_GPR8 = 0; 521 vex_state->guest_GPR9 = 0; 522 vex_state->guest_GPR10 = 0; 523 vex_state->guest_GPR11 = 0; 524 vex_state->guest_GPR12 = 0; 525 vex_state->guest_GPR13 = 0; 526 vex_state->guest_GPR14 = 0; 527 vex_state->guest_GPR15 = 0; 528 vex_state->guest_GPR16 = 0; 529 vex_state->guest_GPR17 = 0; 530 vex_state->guest_GPR18 = 0; 531 vex_state->guest_GPR19 = 0; 532 vex_state->guest_GPR20 = 0; 533 vex_state->guest_GPR21 = 0; 534 vex_state->guest_GPR22 = 0; 535 vex_state->guest_GPR23 = 0; 536 vex_state->guest_GPR24 = 0; 537 vex_state->guest_GPR25 = 0; 538 vex_state->guest_GPR26 = 0; 539 vex_state->guest_GPR27 = 0; 540 vex_state->guest_GPR28 = 0; 541 vex_state->guest_GPR29 = 0; 542 vex_state->guest_GPR30 = 0; 543 vex_state->guest_GPR31 = 0; 544 545 vex_state->guest_FPR0 = 0; 546 vex_state->guest_FPR1 = 0; 547 vex_state->guest_FPR2 = 0; 548 vex_state->guest_FPR3 = 0; 549 vex_state->guest_FPR4 = 0; 550 vex_state->guest_FPR5 = 0; 551 vex_state->guest_FPR6 = 0; 552 vex_state->guest_FPR7 = 0; 553 vex_state->guest_FPR8 = 0; 554 vex_state->guest_FPR9 = 0; 555 vex_state->guest_FPR10 = 0; 556 vex_state->guest_FPR11 = 0; 557 vex_state->guest_FPR12 = 0; 558 vex_state->guest_FPR13 = 0; 559 vex_state->guest_FPR14 = 0; 560 vex_state->guest_FPR15 = 0; 561 vex_state->guest_FPR16 = 0; 562 vex_state->guest_FPR17 = 0; 563 vex_state->guest_FPR18 = 0; 564 vex_state->guest_FPR19 = 0; 565 vex_state->guest_FPR20 = 0; 566 vex_state->guest_FPR21 = 0; 567 vex_state->guest_FPR22 = 0; 568 vex_state->guest_FPR23 = 0; 569 vex_state->guest_FPR24 = 0; 570 vex_state->guest_FPR25 = 0; 571 vex_state->guest_FPR26 = 0; 572 vex_state->guest_FPR27 = 0; 573 vex_state->guest_FPR28 = 0; 574 vex_state->guest_FPR29 = 0; 575 vex_state->guest_FPR30 = 0; 576 vex_state->guest_FPR31 = 0; 577 578 /* Initialise the vector state. */ 579 # define VECZERO(_vr) _vr[0]=_vr[1]=_vr[2]=_vr[3] = 0; 580 581 VECZERO(vex_state->guest_VR0 ); 582 VECZERO(vex_state->guest_VR1 ); 583 VECZERO(vex_state->guest_VR2 ); 584 VECZERO(vex_state->guest_VR3 ); 585 VECZERO(vex_state->guest_VR4 ); 586 VECZERO(vex_state->guest_VR5 ); 587 VECZERO(vex_state->guest_VR6 ); 588 VECZERO(vex_state->guest_VR7 ); 589 VECZERO(vex_state->guest_VR8 ); 590 VECZERO(vex_state->guest_VR9 ); 591 VECZERO(vex_state->guest_VR10); 592 VECZERO(vex_state->guest_VR11); 593 VECZERO(vex_state->guest_VR12); 594 VECZERO(vex_state->guest_VR13); 595 VECZERO(vex_state->guest_VR14); 596 VECZERO(vex_state->guest_VR15); 597 VECZERO(vex_state->guest_VR16); 598 VECZERO(vex_state->guest_VR17); 599 VECZERO(vex_state->guest_VR18); 600 VECZERO(vex_state->guest_VR19); 601 VECZERO(vex_state->guest_VR20); 602 VECZERO(vex_state->guest_VR21); 603 VECZERO(vex_state->guest_VR22); 604 VECZERO(vex_state->guest_VR23); 605 VECZERO(vex_state->guest_VR24); 606 VECZERO(vex_state->guest_VR25); 607 VECZERO(vex_state->guest_VR26); 608 VECZERO(vex_state->guest_VR27); 609 VECZERO(vex_state->guest_VR28); 610 VECZERO(vex_state->guest_VR29); 611 VECZERO(vex_state->guest_VR30); 612 VECZERO(vex_state->guest_VR31); 613 614 # undef VECZERO 615 616 vex_state->guest_CIA = 0; 617 vex_state->guest_LR = 0; 618 vex_state->guest_CTR = 0; 619 620 vex_state->guest_XER_SO = 0; 621 vex_state->guest_XER_OV = 0; 622 vex_state->guest_XER_CA = 0; 623 vex_state->guest_XER_BC = 0; 624 625 vex_state->guest_CR0_321 = 0; 626 vex_state->guest_CR0_0 = 0; 627 vex_state->guest_CR1_321 = 0; 628 vex_state->guest_CR1_0 = 0; 629 vex_state->guest_CR2_321 = 0; 630 vex_state->guest_CR2_0 = 0; 631 vex_state->guest_CR3_321 = 0; 632 vex_state->guest_CR3_0 = 0; 633 vex_state->guest_CR4_321 = 0; 634 vex_state->guest_CR4_0 = 0; 635 vex_state->guest_CR5_321 = 0; 636 vex_state->guest_CR5_0 = 0; 637 vex_state->guest_CR6_321 = 0; 638 vex_state->guest_CR6_0 = 0; 639 vex_state->guest_CR7_321 = 0; 640 vex_state->guest_CR7_0 = 0; 641 642 vex_state->guest_FPROUND = (UInt)PPCrm_NEAREST; 643 644 vex_state->guest_VRSAVE = 0; 645 646 vex_state->guest_VSCR = 0x0; // Non-Java mode = 0 647 648 vex_state->guest_EMWARN = EmWarn_NONE; 649 650 vex_state->padding = 0; 651 652 vex_state->guest_TISTART = 0; 653 vex_state->guest_TILEN = 0; 654 655 vex_state->guest_NRADDR = 0; 656 vex_state->guest_NRADDR_GPR2 = 0; 657 658 vex_state->guest_REDIR_SP = -1; 659 for (i = 0; i < VEX_GUEST_PPC64_REDIR_STACK_SIZE; i++) 660 vex_state->guest_REDIR_STACK[i] = 0; 661 662 vex_state->guest_IP_AT_SYSCALL = 0; 663 vex_state->guest_SPRG3_RO = 0; 664 665 vex_state->padding2 = 0; 666 } 667 668 669 /*-----------------------------------------------------------*/ 670 /*--- Describing the ppc guest state, for the benefit ---*/ 671 /*--- of iropt and instrumenters. ---*/ 672 /*-----------------------------------------------------------*/ 673 674 /* Figure out if any part of the guest state contained in minoff 675 .. maxoff requires precise memory exceptions. If in doubt return 676 True (but this is generates significantly slower code). 677 678 By default we enforce precise exns for guest R1 (stack pointer), 679 CIA (current insn address) and LR (link register). These are the 680 minimum needed to extract correct stack backtraces from ppc 681 code. [[NB: not sure if keeping LR up to date is actually 682 necessary.]] 683 */ 684 Bool guest_ppc32_state_requires_precise_mem_exns ( Int minoff, 685 Int maxoff ) 686 { 687 Int lr_min = offsetof(VexGuestPPC32State, guest_LR); 688 Int lr_max = lr_min + 4 - 1; 689 Int r1_min = offsetof(VexGuestPPC32State, guest_GPR1); 690 Int r1_max = r1_min + 4 - 1; 691 Int cia_min = offsetof(VexGuestPPC32State, guest_CIA); 692 Int cia_max = cia_min + 4 - 1; 693 694 if (maxoff < lr_min || minoff > lr_max) { 695 /* no overlap with LR */ 696 } else { 697 return True; 698 } 699 700 if (maxoff < r1_min || minoff > r1_max) { 701 /* no overlap with R1 */ 702 } else { 703 return True; 704 } 705 706 if (maxoff < cia_min || minoff > cia_max) { 707 /* no overlap with CIA */ 708 } else { 709 return True; 710 } 711 712 return False; 713 } 714 715 Bool guest_ppc64_state_requires_precise_mem_exns ( Int minoff, 716 Int maxoff ) 717 { 718 /* Given that R2 is a Big Deal in the ELF ppc64 ABI, it seems 719 prudent to be conservative with it, even though thus far there 720 is no evidence to suggest that it actually needs to be kept up 721 to date wrt possible exceptions. */ 722 Int lr_min = offsetof(VexGuestPPC64State, guest_LR); 723 Int lr_max = lr_min + 8 - 1; 724 Int r1_min = offsetof(VexGuestPPC64State, guest_GPR1); 725 Int r1_max = r1_min + 8 - 1; 726 Int r2_min = offsetof(VexGuestPPC64State, guest_GPR2); 727 Int r2_max = r2_min + 8 - 1; 728 Int cia_min = offsetof(VexGuestPPC64State, guest_CIA); 729 Int cia_max = cia_min + 8 - 1; 730 731 if (maxoff < lr_min || minoff > lr_max) { 732 /* no overlap with LR */ 733 } else { 734 return True; 735 } 736 737 if (maxoff < r1_min || minoff > r1_max) { 738 /* no overlap with R1 */ 739 } else { 740 return True; 741 } 742 743 if (maxoff < r2_min || minoff > r2_max) { 744 /* no overlap with R2 */ 745 } else { 746 return True; 747 } 748 749 if (maxoff < cia_min || minoff > cia_max) { 750 /* no overlap with CIA */ 751 } else { 752 return True; 753 } 754 755 return False; 756 } 757 758 759 #define ALWAYSDEFD32(field) \ 760 { offsetof(VexGuestPPC32State, field), \ 761 (sizeof ((VexGuestPPC32State*)0)->field) } 762 763 VexGuestLayout 764 ppc32Guest_layout 765 = { 766 /* Total size of the guest state, in bytes. */ 767 .total_sizeB = sizeof(VexGuestPPC32State), 768 769 /* Describe the stack pointer. */ 770 .offset_SP = offsetof(VexGuestPPC32State,guest_GPR1), 771 .sizeof_SP = 4, 772 773 /* Describe the frame pointer. */ 774 .offset_FP = offsetof(VexGuestPPC32State,guest_GPR1), 775 .sizeof_FP = 4, 776 777 /* Describe the instruction pointer. */ 778 .offset_IP = offsetof(VexGuestPPC32State,guest_CIA), 779 .sizeof_IP = 4, 780 781 /* Describe any sections to be regarded by Memcheck as 782 'always-defined'. */ 783 .n_alwaysDefd = 11, 784 785 .alwaysDefd 786 = { /* 0 */ ALWAYSDEFD32(guest_CIA), 787 /* 1 */ ALWAYSDEFD32(guest_EMWARN), 788 /* 2 */ ALWAYSDEFD32(guest_TISTART), 789 /* 3 */ ALWAYSDEFD32(guest_TILEN), 790 /* 4 */ ALWAYSDEFD32(guest_VSCR), 791 /* 5 */ ALWAYSDEFD32(guest_FPROUND), 792 /* 6 */ ALWAYSDEFD32(guest_NRADDR), 793 /* 7 */ ALWAYSDEFD32(guest_NRADDR_GPR2), 794 /* 8 */ ALWAYSDEFD32(guest_REDIR_SP), 795 /* 9 */ ALWAYSDEFD32(guest_REDIR_STACK), 796 /* 10 */ ALWAYSDEFD32(guest_IP_AT_SYSCALL) 797 } 798 }; 799 800 #define ALWAYSDEFD64(field) \ 801 { offsetof(VexGuestPPC64State, field), \ 802 (sizeof ((VexGuestPPC64State*)0)->field) } 803 804 VexGuestLayout 805 ppc64Guest_layout 806 = { 807 /* Total size of the guest state, in bytes. */ 808 .total_sizeB = sizeof(VexGuestPPC64State), 809 810 /* Describe the stack pointer. */ 811 .offset_SP = offsetof(VexGuestPPC64State,guest_GPR1), 812 .sizeof_SP = 8, 813 814 /* Describe the frame pointer. */ 815 .offset_FP = offsetof(VexGuestPPC64State,guest_GPR1), 816 .sizeof_FP = 8, 817 818 /* Describe the instruction pointer. */ 819 .offset_IP = offsetof(VexGuestPPC64State,guest_CIA), 820 .sizeof_IP = 8, 821 822 /* Describe any sections to be regarded by Memcheck as 823 'always-defined'. */ 824 .n_alwaysDefd = 11, 825 826 .alwaysDefd 827 = { /* 0 */ ALWAYSDEFD64(guest_CIA), 828 /* 1 */ ALWAYSDEFD64(guest_EMWARN), 829 /* 2 */ ALWAYSDEFD64(guest_TISTART), 830 /* 3 */ ALWAYSDEFD64(guest_TILEN), 831 /* 4 */ ALWAYSDEFD64(guest_VSCR), 832 /* 5 */ ALWAYSDEFD64(guest_FPROUND), 833 /* 6 */ ALWAYSDEFD64(guest_NRADDR), 834 /* 7 */ ALWAYSDEFD64(guest_NRADDR_GPR2), 835 /* 8 */ ALWAYSDEFD64(guest_REDIR_SP), 836 /* 9 */ ALWAYSDEFD64(guest_REDIR_STACK), 837 /* 10 */ ALWAYSDEFD64(guest_IP_AT_SYSCALL) 838 } 839 }; 840 841 /*---------------------------------------------------------------*/ 842 /*--- end guest_ppc_helpers.c ---*/ 843 /*---------------------------------------------------------------*/ 844