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-2017 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_emnote.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 "main_globals.h" 45 #include "guest_generic_bb_to_IR.h" 46 #include "guest_ppc_defs.h" 47 48 49 /* This file contains helper functions for ppc32 and ppc64 guest code. 50 Calls to these functions are generated by the back end. These 51 calls are of course in the host machine code and this file will be 52 compiled to host machine code, so that all makes sense. 53 54 Only change the signatures of these helper functions very 55 carefully. If you change the signature here, you'll have to change 56 the parameters passed to it in the IR calls constructed by 57 guest-ppc/toIR.c. 58 */ 59 60 61 /*---------------------------------------------------------------*/ 62 /*--- Misc integer helpers. ---*/ 63 /*---------------------------------------------------------------*/ 64 65 /* CALLED FROM GENERATED CODE */ 66 /* DIRTY HELPER (non-referentially-transparent) */ 67 /* Horrible hack. On non-ppc platforms, return 1. */ 68 /* Reads a complete, consistent 64-bit TB value. */ 69 ULong ppcg_dirtyhelper_MFTB ( void ) 70 { 71 # if defined(__powerpc__) 72 ULong res; 73 UInt lo, hi1, hi2; 74 while (1) { 75 __asm__ __volatile__ ("\n" 76 "\tmftbu %0\n" 77 "\tmftb %1\n" 78 "\tmftbu %2\n" 79 : "=r" (hi1), "=r" (lo), "=r" (hi2) 80 ); 81 if (hi1 == hi2) break; 82 } 83 res = ((ULong)hi1) << 32; 84 res |= (ULong)lo; 85 return res; 86 # else 87 return 1ULL; 88 # endif 89 } 90 91 92 /* CALLED FROM GENERATED CODE */ 93 /* DIRTY HELPER (non-referentially transparent) */ 94 UInt ppc32g_dirtyhelper_MFSPR_268_269 ( UInt r269 ) 95 { 96 # if defined(__powerpc__) 97 UInt spr; 98 if (r269) { 99 __asm__ __volatile__("mfspr %0,269" : "=b"(spr)); 100 } else { 101 __asm__ __volatile__("mfspr %0,268" : "=b"(spr)); 102 } 103 return spr; 104 # else 105 return 0; 106 # endif 107 } 108 109 110 /* CALLED FROM GENERATED CODE */ 111 /* DIRTY HELPER (I'm not really sure what the side effects are) */ 112 UInt ppc32g_dirtyhelper_MFSPR_287 ( void ) 113 { 114 # if defined(__powerpc__) 115 UInt spr; 116 __asm__ __volatile__("mfspr %0,287" : "=b"(spr)); 117 return spr; 118 # else 119 return 0; 120 # endif 121 } 122 123 124 /* CALLED FROM GENERATED CODE */ 125 /* DIRTY HELPER (reads guest state, writes guest mem) */ 126 void ppc32g_dirtyhelper_LVS ( VexGuestPPC32State* gst, 127 UInt vD_off, UInt sh, UInt shift_right ) 128 { 129 static 130 UChar ref[32] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 131 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 132 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 133 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }; 134 U128* pU128_src; 135 U128* pU128_dst; 136 137 vassert( vD_off <= sizeof(VexGuestPPC32State)-8 ); 138 vassert( sh <= 15 ); 139 vassert( shift_right <= 1 ); 140 if (shift_right) 141 sh = 16-sh; 142 /* else shift left */ 143 144 pU128_src = (U128*)&ref[sh]; 145 pU128_dst = (U128*)( ((UChar*)gst) + vD_off ); 146 147 (*pU128_dst)[0] = (*pU128_src)[0]; 148 (*pU128_dst)[1] = (*pU128_src)[1]; 149 (*pU128_dst)[2] = (*pU128_src)[2]; 150 (*pU128_dst)[3] = (*pU128_src)[3]; 151 } 152 153 /* CALLED FROM GENERATED CODE */ 154 /* DIRTY HELPER (reads guest state, writes guest mem) */ 155 void ppc64g_dirtyhelper_LVS ( VexGuestPPC64State* gst, 156 UInt vD_off, UInt sh, UInt shift_right, 157 UInt endness ) 158 { 159 UChar ref[32]; 160 ULong i; 161 Int k; 162 /* ref[] used to be a static const array, but this doesn't work on 163 ppc64 because VEX doesn't load the TOC pointer for the call here, 164 and so we wind up picking up some totally random other data. 165 (It's a wonder we don't segfault.) So, just to be clear, this 166 "fix" (vex r2073) is really a kludgearound for the fact that 167 VEX's 64-bit ppc code generation doesn't provide a valid TOC 168 pointer for helper function calls. Ick. (Bug 250038) */ 169 for (i = 0; i < 32; i++) ref[i] = i; 170 171 U128* pU128_src; 172 U128* pU128_dst; 173 174 vassert( vD_off <= sizeof(VexGuestPPC64State)-8 ); 175 vassert( sh <= 15 ); 176 vassert( shift_right <= 1 ); 177 if (shift_right) 178 sh = 16-sh; 179 /* else shift left */ 180 181 pU128_src = (U128*)&ref[sh]; 182 pU128_dst = (U128*)( ((UChar*)gst) + vD_off ); 183 184 if ((0x1 & endness) == 0x0) { 185 /* Little endian */ 186 unsigned char *srcp, *dstp; 187 srcp = (unsigned char *)pU128_src; 188 dstp = (unsigned char *)pU128_dst; 189 for (k = 15; k >= 0; k--, srcp++) 190 dstp[k] = *srcp; 191 } else { 192 (*pU128_dst)[0] = (*pU128_src)[0]; 193 (*pU128_dst)[1] = (*pU128_src)[1]; 194 (*pU128_dst)[2] = (*pU128_src)[2]; 195 (*pU128_dst)[3] = (*pU128_src)[3]; 196 } 197 } 198 199 200 /* Helper-function specialiser. */ 201 202 IRExpr* guest_ppc32_spechelper ( const HChar* function_name, 203 IRExpr** args, 204 IRStmt** precedingStmts, 205 Int n_precedingStmts ) 206 { 207 return NULL; 208 } 209 210 IRExpr* guest_ppc64_spechelper ( const HChar* function_name, 211 IRExpr** args, 212 IRStmt** precedingStmts, 213 Int n_precedingStmts ) 214 { 215 return NULL; 216 } 217 218 219 /*---------------------------------------------------------------*/ 220 /*--- Misc BCD clean helpers. ---*/ 221 /*---------------------------------------------------------------*/ 222 223 /* NOTE, the clean and dirty helpers need to called using the 224 * fnptr_to_fnentry() function wrapper to handle the Big Endian 225 * pointer-to-function ABI and the Little Endian ABI. 226 */ 227 228 /* This C-helper takes a 128-bit BCD value as two 64-bit pieces. 229 * It checks the string to see if it is a valid 128-bit BCD value. 230 * A valid BCD value has a sign value in bits [3:0] between 0xA 231 * and 0xF inclusive. each of the BCD digits represented as a 4-bit 232 * hex number in bits BCD value[128:4] mut be between 0 and 9 233 * inclusive. Returns an unsigned 64-bit value if valid. 234 */ 235 ULong is_BCDstring128_helper( ULong Signed, ULong bcd_string_hi, 236 ULong bcd_string_low ) { 237 Int i; 238 ULong valid_bcd, sign_valid = False; 239 ULong digit; 240 UInt sign; 241 242 if ( Signed == True ) { 243 sign = bcd_string_low & 0xF; 244 if( ( sign >= 0xA ) && ( sign <= 0xF ) ) 245 sign_valid = True; 246 247 /* Change the sign digit to a zero 248 * so the for loop below works the same 249 * for signed and unsigned BCD stings 250 */ 251 bcd_string_low &= 0xFFFFFFFFFFFFFFF0ULL; 252 253 } else { 254 sign_valid = True; /* set sign to True so result is only 255 based on the validity of the digits */ 256 } 257 258 valid_bcd = True; // Assume true to start 259 for( i = 0; i < 32; i++ ) { 260 /* check high and low 64-bit strings in parallel */ 261 digit = bcd_string_low & 0xF; 262 if ( digit > 0x9 ) 263 valid_bcd = False; 264 bcd_string_low = bcd_string_low >> 4; 265 266 digit = bcd_string_hi & 0xF; 267 if ( digit > 0x9 ) 268 valid_bcd = False; 269 bcd_string_hi = bcd_string_hi >> 4; 270 } 271 272 return valid_bcd & sign_valid; 273 } 274 275 /* This clean helper takes a signed 32-bit BCD value and a carry in 276 * and adds 1 to the value of the BCD value. The BCD value is passed 277 * in as a single 64-bit value. The incremented value is returned in 278 * the lower 32 bits of the result. If the input was signed the sign of 279 * the result is the same as the input. The carry out is returned in 280 * bits [35:32] of the result. 281 */ 282 ULong increment_BCDstring32_helper( ULong Signed, 283 ULong bcd_string, ULong carry_in ) { 284 UInt i, num_digits = 8; 285 ULong bcd_value, result = 0; 286 ULong carry, digit, new_digit; 287 288 carry = carry_in; 289 290 if ( Signed == True ) { 291 bcd_value = bcd_string >> 4; /* remove sign */ 292 num_digits = num_digits - 1; 293 } else { 294 bcd_value = bcd_string; 295 } 296 297 for( i = 0; i < num_digits; i++ ) { 298 digit = bcd_value & 0xF; 299 bcd_value = bcd_value >> 4; 300 new_digit = digit + carry; 301 302 if ( new_digit > 10 ) { 303 carry = 1; 304 new_digit = new_digit - 10; 305 306 } else { 307 carry = 0; 308 } 309 result = result | (new_digit << (i*4) ); 310 } 311 312 if ( Signed == True ) { 313 result = ( carry << 32) | ( result << 4 ) | ( bcd_string & 0xF ); 314 } else { 315 result = ( carry << 32) | result; 316 } 317 318 return result; 319 } 320 321 /*---------------------------------------------------------------*/ 322 /*--- Misc packed decimal clean helpers. ---*/ 323 /*---------------------------------------------------------------*/ 324 325 /* This C-helper takes a 64-bit packed decimal value stored in a 326 * 64-bit value. It converts the zoned decimal format. The lower 327 * byte may contain a sign value, set it to zero. If return_upper 328 * is zero, return lower 64 bits of result, otherwise return upper 329 * 64 bits of the result. 330 */ 331 ULong convert_to_zoned_helper( ULong src_hi, ULong src_low, 332 ULong upper_byte, ULong return_upper ) { 333 UInt i, sh; 334 ULong tmp = 0, new_value; 335 336 /* Remove the sign from the source. Put in the upper byte of result. 337 * Sign inserted later. 338 */ 339 if ( return_upper == 0 ) { /* return lower 64-bit result */ 340 for(i = 0; i < 7; i++) { 341 sh = ( 8 - i ) * 4; 342 new_value = ( ( src_low >> sh ) & 0xf ) | upper_byte; 343 tmp = tmp | ( new_value << ( ( 7 - i ) * 8 ) ); 344 } 345 346 } else { 347 /* Byte for i=0 is in upper 64-bit of the source, do it separately */ 348 new_value = ( src_hi & 0xf ) | upper_byte; 349 tmp = tmp | new_value << 56; 350 351 for( i = 1; i < 8; i++ ) { 352 sh = ( 16 - i ) * 4; 353 new_value = ( ( src_low >> sh ) & 0xf ) | upper_byte; 354 tmp = tmp | ( new_value << ( ( 7 - i ) * 8 ) ); 355 } 356 } 357 return tmp; 358 } 359 360 /* This C-helper takes the lower 64-bits of the 128-bit packed decimal 361 * src value. It converts the src value to a 128-bit national format. 362 * If return_upper is zero, the helper returns lower 64 bits of result, 363 * otherwise it returns the upper 64-bits of the result. 364 */ 365 ULong convert_to_national_helper( ULong src, ULong return_upper ) { 366 367 UInt i; 368 UInt sh = 3, max = 4, min = 0; /* initialize max, min for return upper */ 369 ULong tmp = 0, new_value; 370 371 if ( return_upper == 0 ) { /* return lower 64-bit result */ 372 min = 4; 373 max = 7; 374 sh = 7; 375 } 376 377 for( i = min; i < max; i++ ) { 378 new_value = ( ( src >> ( ( 7 - i ) * 4 ) ) & 0xf ) | 0x0030; 379 tmp = tmp | ( new_value << ( ( sh - i ) * 16 ) ); 380 } 381 return tmp; 382 } 383 384 /* This C-helper takes a 128-bit zoned value stored in a 128-bit 385 * value. It converts it to the packed 64-bit decimal format without a 386 * a sign value. The sign is supposed to be in bits [3:0] and the packed 387 * value in bits [67:4]. This helper leaves it to the caller to put the 388 * result into a V128 and shift the returned value over and put the sign 389 * in. 390 */ 391 ULong convert_from_zoned_helper( ULong src_hi, ULong src_low ) { 392 UInt i; 393 ULong tmp = 0, nibble; 394 395 /* Unroll the i = 0 iteration so the sizes of the loop for the upper 396 * and lower extraction match. Skip sign in lease significant byte. 397 */ 398 nibble = ( src_hi >> 56 ) & 0xF; 399 tmp = tmp | ( nibble << 60 ); 400 401 for( i = 1; i < 8; i++ ) { 402 /* get the high nibbles, put into result */ 403 nibble = ( src_hi >> ( ( 7 - i ) * 8 ) ) & 0xF; 404 tmp = tmp | ( nibble << ( ( 15 - i ) * 4 ) ); 405 406 /* get the low nibbles, put into result */ 407 nibble = ( src_low >> ( ( 8 - i ) * 8 ) ) & 0xF; 408 tmp = tmp | ( nibble << ( ( 8 - i ) * 4 ) ); 409 } 410 return tmp; 411 } 412 413 /* This C-helper takes a 128-bit national value stored in a 128-bit 414 * value. It converts it to a signless packed 64-bit decimal format. 415 */ 416 ULong convert_from_national_helper( ULong src_hi, ULong src_low ) { 417 UInt i; 418 ULong tmp = 0, hword; 419 420 src_low = src_low & 0xFFFFFFFFFFFFFFF0ULL; /* remove the sign */ 421 422 for( i = 0; i < 4; i++ ) { 423 /* get the high half-word, put into result */ 424 hword = ( src_hi >> ( ( 3 - i ) * 16 ) ) & 0xF; 425 tmp = tmp | ( hword << ( ( 7 - i ) * 4 ) ); 426 427 /* get the low half-word, put into result */ 428 hword = ( src_low >> ( ( 3 - i ) * 16 ) ) & 0xF; 429 tmp = tmp | ( hword << ( ( 3 - i ) * 4 ) ); 430 } 431 return tmp; 432 } 433 434 /*----------------------------------------------*/ 435 /*--- The exported fns .. ---*/ 436 /*----------------------------------------------*/ 437 438 /* VISIBLE TO LIBVEX CLIENT */ 439 UInt LibVEX_GuestPPC32_get_CR ( /*IN*/const VexGuestPPC32State* vex_state ) 440 { 441 # define FIELD(_n) \ 442 ( ( (UInt) \ 443 ( (vex_state->guest_CR##_n##_321 & (7<<1)) \ 444 | (vex_state->guest_CR##_n##_0 & 1) \ 445 ) \ 446 ) \ 447 << (4 * (7-(_n))) \ 448 ) 449 450 return 451 FIELD(0) | FIELD(1) | FIELD(2) | FIELD(3) 452 | FIELD(4) | FIELD(5) | FIELD(6) | FIELD(7); 453 454 # undef FIELD 455 } 456 457 458 /* VISIBLE TO LIBVEX CLIENT */ 459 /* Note: %CR is 32 bits even for ppc64 */ 460 UInt LibVEX_GuestPPC64_get_CR ( /*IN*/const VexGuestPPC64State* vex_state ) 461 { 462 # define FIELD(_n) \ 463 ( ( (UInt) \ 464 ( (vex_state->guest_CR##_n##_321 & (7<<1)) \ 465 | (vex_state->guest_CR##_n##_0 & 1) \ 466 ) \ 467 ) \ 468 << (4 * (7-(_n))) \ 469 ) 470 471 return 472 FIELD(0) | FIELD(1) | FIELD(2) | FIELD(3) 473 | FIELD(4) | FIELD(5) | FIELD(6) | FIELD(7); 474 475 # undef FIELD 476 } 477 478 479 /* VISIBLE TO LIBVEX CLIENT */ 480 void LibVEX_GuestPPC32_put_CR ( UInt cr_native, 481 /*OUT*/VexGuestPPC32State* vex_state ) 482 { 483 UInt t; 484 485 # define FIELD(_n) \ 486 do { \ 487 t = cr_native >> (4*(7-(_n))); \ 488 vex_state->guest_CR##_n##_0 = toUChar(t & 1); \ 489 vex_state->guest_CR##_n##_321 = toUChar(t & (7<<1)); \ 490 } while (0) 491 492 FIELD(0); 493 FIELD(1); 494 FIELD(2); 495 FIELD(3); 496 FIELD(4); 497 FIELD(5); 498 FIELD(6); 499 FIELD(7); 500 501 # undef FIELD 502 } 503 504 505 /* VISIBLE TO LIBVEX CLIENT */ 506 /* Note: %CR is 32 bits even for ppc64 */ 507 void LibVEX_GuestPPC64_put_CR ( UInt cr_native, 508 /*OUT*/VexGuestPPC64State* vex_state ) 509 { 510 UInt t; 511 512 # define FIELD(_n) \ 513 do { \ 514 t = cr_native >> (4*(7-(_n))); \ 515 vex_state->guest_CR##_n##_0 = toUChar(t & 1); \ 516 vex_state->guest_CR##_n##_321 = toUChar(t & (7<<1)); \ 517 } while (0) 518 519 FIELD(0); 520 FIELD(1); 521 FIELD(2); 522 FIELD(3); 523 FIELD(4); 524 FIELD(5); 525 FIELD(6); 526 FIELD(7); 527 528 # undef FIELD 529 } 530 531 532 /* VISIBLE TO LIBVEX CLIENT */ 533 UInt LibVEX_GuestPPC32_get_XER ( /*IN*/const VexGuestPPC32State* vex_state ) 534 { 535 UInt w = 0; 536 w |= ( ((UInt)vex_state->guest_XER_BC) & 0xFF ); 537 w |= ( (((UInt)vex_state->guest_XER_SO) & 0x1) << 31 ); 538 w |= ( (((UInt)vex_state->guest_XER_OV) & 0x1) << 30 ); 539 w |= ( (((UInt)vex_state->guest_XER_CA) & 0x1) << 29 ); 540 w |= ( (((UInt)vex_state->guest_XER_OV32) & 0x1) << 19 ); 541 w |= ( (((UInt)vex_state->guest_XER_CA32) & 0x1) << 18 ); 542 return w; 543 } 544 545 546 /* VISIBLE TO LIBVEX CLIENT */ 547 /* Note: %XER is 32 bits even for ppc64 */ 548 UInt LibVEX_GuestPPC64_get_XER ( /*IN*/const VexGuestPPC64State* vex_state ) 549 { 550 UInt w = 0; 551 w |= ( ((UInt)vex_state->guest_XER_BC) & 0xFF ); 552 w |= ( (((UInt)vex_state->guest_XER_SO) & 0x1) << 31 ); 553 w |= ( (((UInt)vex_state->guest_XER_OV) & 0x1) << 30 ); 554 w |= ( (((UInt)vex_state->guest_XER_CA) & 0x1) << 29 ); 555 w |= ( (((UInt)vex_state->guest_XER_OV32) & 0x1) << 19 ); 556 w |= ( (((UInt)vex_state->guest_XER_CA32) & 0x1) << 18 ); 557 return w; 558 } 559 560 561 /* VISIBLE TO LIBVEX CLIENT */ 562 void LibVEX_GuestPPC32_put_XER ( UInt xer_native, 563 /*OUT*/VexGuestPPC32State* vex_state ) 564 { 565 vex_state->guest_XER_BC = toUChar(xer_native & 0xFF); 566 vex_state->guest_XER_SO = toUChar((xer_native >> 31) & 0x1); 567 vex_state->guest_XER_OV = toUChar((xer_native >> 30) & 0x1); 568 vex_state->guest_XER_CA = toUChar((xer_native >> 29) & 0x1); 569 vex_state->guest_XER_OV32 = toUChar((xer_native >> 19) & 0x1); 570 vex_state->guest_XER_CA32 = toUChar((xer_native >> 18) & 0x1); 571 } 572 573 /* VISIBLE TO LIBVEX CLIENT */ 574 /* Note: %XER is 32 bits even for ppc64 */ 575 void LibVEX_GuestPPC64_put_XER ( UInt xer_native, 576 /*OUT*/VexGuestPPC64State* vex_state ) 577 { 578 vex_state->guest_XER_BC = toUChar(xer_native & 0xFF); 579 vex_state->guest_XER_SO = toUChar((xer_native >> 31) & 0x1); 580 vex_state->guest_XER_OV = toUChar((xer_native >> 30) & 0x1); 581 vex_state->guest_XER_CA = toUChar((xer_native >> 29) & 0x1); 582 vex_state->guest_XER_OV32 = toUChar((xer_native >> 19) & 0x1); 583 vex_state->guest_XER_CA32 = toUChar((xer_native >> 18) & 0x1); 584 } 585 586 /* VISIBLE TO LIBVEX CLIENT */ 587 void LibVEX_GuestPPC32_initialise ( /*OUT*/VexGuestPPC32State* vex_state ) 588 { 589 Int i; 590 vex_state->host_EvC_FAILADDR = 0; 591 vex_state->host_EvC_COUNTER = 0; 592 vex_state->pad3 = 0; 593 vex_state->pad4 = 0; 594 595 vex_state->guest_GPR0 = 0; 596 vex_state->guest_GPR1 = 0; 597 vex_state->guest_GPR2 = 0; 598 vex_state->guest_GPR3 = 0; 599 vex_state->guest_GPR4 = 0; 600 vex_state->guest_GPR5 = 0; 601 vex_state->guest_GPR6 = 0; 602 vex_state->guest_GPR7 = 0; 603 vex_state->guest_GPR8 = 0; 604 vex_state->guest_GPR9 = 0; 605 vex_state->guest_GPR10 = 0; 606 vex_state->guest_GPR11 = 0; 607 vex_state->guest_GPR12 = 0; 608 vex_state->guest_GPR13 = 0; 609 vex_state->guest_GPR14 = 0; 610 vex_state->guest_GPR15 = 0; 611 vex_state->guest_GPR16 = 0; 612 vex_state->guest_GPR17 = 0; 613 vex_state->guest_GPR18 = 0; 614 vex_state->guest_GPR19 = 0; 615 vex_state->guest_GPR20 = 0; 616 vex_state->guest_GPR21 = 0; 617 vex_state->guest_GPR22 = 0; 618 vex_state->guest_GPR23 = 0; 619 vex_state->guest_GPR24 = 0; 620 vex_state->guest_GPR25 = 0; 621 vex_state->guest_GPR26 = 0; 622 vex_state->guest_GPR27 = 0; 623 vex_state->guest_GPR28 = 0; 624 vex_state->guest_GPR29 = 0; 625 vex_state->guest_GPR30 = 0; 626 vex_state->guest_GPR31 = 0; 627 628 /* Initialise the vector state. */ 629 # define VECZERO(_vr) _vr[0]=_vr[1]=_vr[2]=_vr[3] = 0; 630 631 VECZERO(vex_state->guest_VSR0 ); 632 VECZERO(vex_state->guest_VSR1 ); 633 VECZERO(vex_state->guest_VSR2 ); 634 VECZERO(vex_state->guest_VSR3 ); 635 VECZERO(vex_state->guest_VSR4 ); 636 VECZERO(vex_state->guest_VSR5 ); 637 VECZERO(vex_state->guest_VSR6 ); 638 VECZERO(vex_state->guest_VSR7 ); 639 VECZERO(vex_state->guest_VSR8 ); 640 VECZERO(vex_state->guest_VSR9 ); 641 VECZERO(vex_state->guest_VSR10); 642 VECZERO(vex_state->guest_VSR11); 643 VECZERO(vex_state->guest_VSR12); 644 VECZERO(vex_state->guest_VSR13); 645 VECZERO(vex_state->guest_VSR14); 646 VECZERO(vex_state->guest_VSR15); 647 VECZERO(vex_state->guest_VSR16); 648 VECZERO(vex_state->guest_VSR17); 649 VECZERO(vex_state->guest_VSR18); 650 VECZERO(vex_state->guest_VSR19); 651 VECZERO(vex_state->guest_VSR20); 652 VECZERO(vex_state->guest_VSR21); 653 VECZERO(vex_state->guest_VSR22); 654 VECZERO(vex_state->guest_VSR23); 655 VECZERO(vex_state->guest_VSR24); 656 VECZERO(vex_state->guest_VSR25); 657 VECZERO(vex_state->guest_VSR26); 658 VECZERO(vex_state->guest_VSR27); 659 VECZERO(vex_state->guest_VSR28); 660 VECZERO(vex_state->guest_VSR29); 661 VECZERO(vex_state->guest_VSR30); 662 VECZERO(vex_state->guest_VSR31); 663 VECZERO(vex_state->guest_VSR32); 664 VECZERO(vex_state->guest_VSR33); 665 VECZERO(vex_state->guest_VSR34); 666 VECZERO(vex_state->guest_VSR35); 667 VECZERO(vex_state->guest_VSR36); 668 VECZERO(vex_state->guest_VSR37); 669 VECZERO(vex_state->guest_VSR38); 670 VECZERO(vex_state->guest_VSR39); 671 VECZERO(vex_state->guest_VSR40); 672 VECZERO(vex_state->guest_VSR41); 673 VECZERO(vex_state->guest_VSR42); 674 VECZERO(vex_state->guest_VSR43); 675 VECZERO(vex_state->guest_VSR44); 676 VECZERO(vex_state->guest_VSR45); 677 VECZERO(vex_state->guest_VSR46); 678 VECZERO(vex_state->guest_VSR47); 679 VECZERO(vex_state->guest_VSR48); 680 VECZERO(vex_state->guest_VSR49); 681 VECZERO(vex_state->guest_VSR50); 682 VECZERO(vex_state->guest_VSR51); 683 VECZERO(vex_state->guest_VSR52); 684 VECZERO(vex_state->guest_VSR53); 685 VECZERO(vex_state->guest_VSR54); 686 VECZERO(vex_state->guest_VSR55); 687 VECZERO(vex_state->guest_VSR56); 688 VECZERO(vex_state->guest_VSR57); 689 VECZERO(vex_state->guest_VSR58); 690 VECZERO(vex_state->guest_VSR59); 691 VECZERO(vex_state->guest_VSR60); 692 VECZERO(vex_state->guest_VSR61); 693 VECZERO(vex_state->guest_VSR62); 694 VECZERO(vex_state->guest_VSR63); 695 696 # undef VECZERO 697 698 vex_state->guest_CIA = 0; 699 vex_state->guest_LR = 0; 700 vex_state->guest_CTR = 0; 701 702 vex_state->guest_XER_SO = 0; 703 vex_state->guest_XER_OV = 0; 704 vex_state->guest_XER_CA = 0; 705 vex_state->guest_XER_BC = 0; 706 707 vex_state->guest_XER_OV32 = 0; 708 vex_state->guest_XER_CA32 = 0; 709 710 vex_state->guest_CR0_321 = 0; 711 vex_state->guest_CR0_0 = 0; 712 vex_state->guest_CR1_321 = 0; 713 vex_state->guest_CR1_0 = 0; 714 vex_state->guest_CR2_321 = 0; 715 vex_state->guest_CR2_0 = 0; 716 vex_state->guest_CR3_321 = 0; 717 vex_state->guest_CR3_0 = 0; 718 vex_state->guest_CR4_321 = 0; 719 vex_state->guest_CR4_0 = 0; 720 vex_state->guest_CR5_321 = 0; 721 vex_state->guest_CR5_0 = 0; 722 vex_state->guest_CR6_321 = 0; 723 vex_state->guest_CR6_0 = 0; 724 vex_state->guest_CR7_321 = 0; 725 vex_state->guest_CR7_0 = 0; 726 727 vex_state->guest_FPROUND = PPCrm_NEAREST; 728 vex_state->guest_DFPROUND = PPCrm_NEAREST; 729 vex_state->guest_C_FPCC = 0; 730 vex_state->pad2 = 0; 731 732 vex_state->guest_VRSAVE = 0; 733 734 vex_state->guest_VSCR = 0x0; // Non-Java mode = 0 735 736 vex_state->guest_EMNOTE = EmNote_NONE; 737 738 vex_state->guest_CMSTART = 0; 739 vex_state->guest_CMLEN = 0; 740 741 vex_state->guest_NRADDR = 0; 742 vex_state->guest_NRADDR_GPR2 = 0; 743 744 vex_state->guest_REDIR_SP = -1; 745 for (i = 0; i < VEX_GUEST_PPC32_REDIR_STACK_SIZE; i++) 746 vex_state->guest_REDIR_STACK[i] = 0; 747 748 vex_state->guest_IP_AT_SYSCALL = 0; 749 vex_state->guest_SPRG3_RO = 0; 750 vex_state->guest_PPR = 0x4ULL << 50; // medium priority 751 vex_state->guest_PSPB = 0x100; // an arbitrary non-zero value to start with 752 753 vex_state->padding1 = 0; 754 /* vex_state->padding2 = 0; currently not used */ 755 } 756 757 758 /* VISIBLE TO LIBVEX CLIENT */ 759 void LibVEX_GuestPPC64_initialise ( /*OUT*/VexGuestPPC64State* vex_state ) 760 { 761 Int i; 762 vex_state->host_EvC_FAILADDR = 0; 763 vex_state->host_EvC_COUNTER = 0; 764 vex_state->pad0 = 0; 765 vex_state->guest_GPR0 = 0; 766 vex_state->guest_GPR1 = 0; 767 vex_state->guest_GPR2 = 0; 768 vex_state->guest_GPR3 = 0; 769 vex_state->guest_GPR4 = 0; 770 vex_state->guest_GPR5 = 0; 771 vex_state->guest_GPR6 = 0; 772 vex_state->guest_GPR7 = 0; 773 vex_state->guest_GPR8 = 0; 774 vex_state->guest_GPR9 = 0; 775 vex_state->guest_GPR10 = 0; 776 vex_state->guest_GPR11 = 0; 777 vex_state->guest_GPR12 = 0; 778 vex_state->guest_GPR13 = 0; 779 vex_state->guest_GPR14 = 0; 780 vex_state->guest_GPR15 = 0; 781 vex_state->guest_GPR16 = 0; 782 vex_state->guest_GPR17 = 0; 783 vex_state->guest_GPR18 = 0; 784 vex_state->guest_GPR19 = 0; 785 vex_state->guest_GPR20 = 0; 786 vex_state->guest_GPR21 = 0; 787 vex_state->guest_GPR22 = 0; 788 vex_state->guest_GPR23 = 0; 789 vex_state->guest_GPR24 = 0; 790 vex_state->guest_GPR25 = 0; 791 vex_state->guest_GPR26 = 0; 792 vex_state->guest_GPR27 = 0; 793 vex_state->guest_GPR28 = 0; 794 vex_state->guest_GPR29 = 0; 795 vex_state->guest_GPR30 = 0; 796 vex_state->guest_GPR31 = 0; 797 798 /* Initialise the vector state. */ 799 # define VECZERO(_vr) _vr[0]=_vr[1]=_vr[2]=_vr[3] = 0; 800 801 VECZERO(vex_state->guest_VSR0 ); 802 VECZERO(vex_state->guest_VSR1 ); 803 VECZERO(vex_state->guest_VSR2 ); 804 VECZERO(vex_state->guest_VSR3 ); 805 VECZERO(vex_state->guest_VSR4 ); 806 VECZERO(vex_state->guest_VSR5 ); 807 VECZERO(vex_state->guest_VSR6 ); 808 VECZERO(vex_state->guest_VSR7 ); 809 VECZERO(vex_state->guest_VSR8 ); 810 VECZERO(vex_state->guest_VSR9 ); 811 VECZERO(vex_state->guest_VSR10); 812 VECZERO(vex_state->guest_VSR11); 813 VECZERO(vex_state->guest_VSR12); 814 VECZERO(vex_state->guest_VSR13); 815 VECZERO(vex_state->guest_VSR14); 816 VECZERO(vex_state->guest_VSR15); 817 VECZERO(vex_state->guest_VSR16); 818 VECZERO(vex_state->guest_VSR17); 819 VECZERO(vex_state->guest_VSR18); 820 VECZERO(vex_state->guest_VSR19); 821 VECZERO(vex_state->guest_VSR20); 822 VECZERO(vex_state->guest_VSR21); 823 VECZERO(vex_state->guest_VSR22); 824 VECZERO(vex_state->guest_VSR23); 825 VECZERO(vex_state->guest_VSR24); 826 VECZERO(vex_state->guest_VSR25); 827 VECZERO(vex_state->guest_VSR26); 828 VECZERO(vex_state->guest_VSR27); 829 VECZERO(vex_state->guest_VSR28); 830 VECZERO(vex_state->guest_VSR29); 831 VECZERO(vex_state->guest_VSR30); 832 VECZERO(vex_state->guest_VSR31); 833 VECZERO(vex_state->guest_VSR32); 834 VECZERO(vex_state->guest_VSR33); 835 VECZERO(vex_state->guest_VSR34); 836 VECZERO(vex_state->guest_VSR35); 837 VECZERO(vex_state->guest_VSR36); 838 VECZERO(vex_state->guest_VSR37); 839 VECZERO(vex_state->guest_VSR38); 840 VECZERO(vex_state->guest_VSR39); 841 VECZERO(vex_state->guest_VSR40); 842 VECZERO(vex_state->guest_VSR41); 843 VECZERO(vex_state->guest_VSR42); 844 VECZERO(vex_state->guest_VSR43); 845 VECZERO(vex_state->guest_VSR44); 846 VECZERO(vex_state->guest_VSR45); 847 VECZERO(vex_state->guest_VSR46); 848 VECZERO(vex_state->guest_VSR47); 849 VECZERO(vex_state->guest_VSR48); 850 VECZERO(vex_state->guest_VSR49); 851 VECZERO(vex_state->guest_VSR50); 852 VECZERO(vex_state->guest_VSR51); 853 VECZERO(vex_state->guest_VSR52); 854 VECZERO(vex_state->guest_VSR53); 855 VECZERO(vex_state->guest_VSR54); 856 VECZERO(vex_state->guest_VSR55); 857 VECZERO(vex_state->guest_VSR56); 858 VECZERO(vex_state->guest_VSR57); 859 VECZERO(vex_state->guest_VSR58); 860 VECZERO(vex_state->guest_VSR59); 861 VECZERO(vex_state->guest_VSR60); 862 VECZERO(vex_state->guest_VSR61); 863 VECZERO(vex_state->guest_VSR62); 864 VECZERO(vex_state->guest_VSR63); 865 866 # undef VECZERO 867 868 vex_state->guest_CIA = 0; 869 vex_state->guest_LR = 0; 870 vex_state->guest_CTR = 0; 871 872 vex_state->guest_XER_SO = 0; 873 vex_state->guest_XER_OV = 0; 874 vex_state->guest_XER_CA = 0; 875 vex_state->guest_XER_BC = 0; 876 877 vex_state->guest_CR0_321 = 0; 878 vex_state->guest_CR0_0 = 0; 879 vex_state->guest_CR1_321 = 0; 880 vex_state->guest_CR1_0 = 0; 881 vex_state->guest_CR2_321 = 0; 882 vex_state->guest_CR2_0 = 0; 883 vex_state->guest_CR3_321 = 0; 884 vex_state->guest_CR3_0 = 0; 885 vex_state->guest_CR4_321 = 0; 886 vex_state->guest_CR4_0 = 0; 887 vex_state->guest_CR5_321 = 0; 888 vex_state->guest_CR5_0 = 0; 889 vex_state->guest_CR6_321 = 0; 890 vex_state->guest_CR6_0 = 0; 891 vex_state->guest_CR7_321 = 0; 892 vex_state->guest_CR7_0 = 0; 893 894 vex_state->guest_FPROUND = PPCrm_NEAREST; 895 vex_state->guest_DFPROUND = PPCrm_NEAREST; 896 vex_state->guest_C_FPCC = 0; 897 vex_state->pad2 = 0; 898 899 vex_state->guest_VRSAVE = 0; 900 901 vex_state->guest_VSCR = 0x0; // Non-Java mode = 0 902 903 vex_state->guest_EMNOTE = EmNote_NONE; 904 905 vex_state->padding = 0; 906 907 vex_state->guest_CMSTART = 0; 908 vex_state->guest_CMLEN = 0; 909 910 vex_state->guest_NRADDR = 0; 911 vex_state->guest_NRADDR_GPR2 = 0; 912 913 vex_state->guest_REDIR_SP = -1; 914 for (i = 0; i < VEX_GUEST_PPC64_REDIR_STACK_SIZE; i++) 915 vex_state->guest_REDIR_STACK[i] = 0; 916 917 vex_state->guest_IP_AT_SYSCALL = 0; 918 vex_state->guest_SPRG3_RO = 0; 919 vex_state->guest_TFHAR = 0; 920 vex_state->guest_TFIAR = 0; 921 vex_state->guest_TEXASR = 0; 922 vex_state->guest_PPR = 0x4ULL << 50; // medium priority 923 vex_state->guest_PSPB = 0x100; // an arbitrary non-zero value to start with 924 } 925 926 927 /*-----------------------------------------------------------*/ 928 /*--- Describing the ppc guest state, for the benefit ---*/ 929 /*--- of iropt and instrumenters. ---*/ 930 /*-----------------------------------------------------------*/ 931 932 /* Figure out if any part of the guest state contained in minoff 933 .. maxoff requires precise memory exceptions. If in doubt return 934 True (but this is generates significantly slower code). 935 936 By default we enforce precise exns for guest R1 (stack pointer), 937 CIA (current insn address) and LR (link register). These are the 938 minimum needed to extract correct stack backtraces from ppc 939 code. [[NB: not sure if keeping LR up to date is actually 940 necessary.]] 941 942 Only R1 is needed in mode VexRegUpdSpAtMemAccess. 943 */ 944 Bool guest_ppc32_state_requires_precise_mem_exns ( 945 Int minoff, Int maxoff, VexRegisterUpdates pxControl 946 ) 947 { 948 Int lr_min = offsetof(VexGuestPPC32State, guest_LR); 949 Int lr_max = lr_min + 4 - 1; 950 Int r1_min = offsetof(VexGuestPPC32State, guest_GPR1); 951 Int r1_max = r1_min + 4 - 1; 952 Int cia_min = offsetof(VexGuestPPC32State, guest_CIA); 953 Int cia_max = cia_min + 4 - 1; 954 955 if (maxoff < r1_min || minoff > r1_max) { 956 /* no overlap with R1 */ 957 if (pxControl == VexRegUpdSpAtMemAccess) 958 return False; // We only need to check stack pointer. 959 } else { 960 return True; 961 } 962 963 if (maxoff < lr_min || minoff > lr_max) { 964 /* no overlap with LR */ 965 } else { 966 return True; 967 } 968 969 if (maxoff < cia_min || minoff > cia_max) { 970 /* no overlap with CIA */ 971 } else { 972 return True; 973 } 974 975 return False; 976 } 977 978 Bool guest_ppc64_state_requires_precise_mem_exns ( 979 Int minoff, Int maxoff, VexRegisterUpdates pxControl 980 ) 981 { 982 /* Given that R2 is a Big Deal in the ELF ppc64 ABI, it seems 983 prudent to be conservative with it, even though thus far there 984 is no evidence to suggest that it actually needs to be kept up 985 to date wrt possible exceptions. */ 986 Int lr_min = offsetof(VexGuestPPC64State, guest_LR); 987 Int lr_max = lr_min + 8 - 1; 988 Int r1_min = offsetof(VexGuestPPC64State, guest_GPR1); 989 Int r1_max = r1_min + 8 - 1; 990 Int r2_min = offsetof(VexGuestPPC64State, guest_GPR2); 991 Int r2_max = r2_min + 8 - 1; 992 Int cia_min = offsetof(VexGuestPPC64State, guest_CIA); 993 Int cia_max = cia_min + 8 - 1; 994 995 if (maxoff < r1_min || minoff > r1_max) { 996 /* no overlap with R1 */ 997 if (pxControl == VexRegUpdSpAtMemAccess) 998 return False; // We only need to check stack pointer. 999 } else { 1000 return True; 1001 } 1002 1003 if (maxoff < lr_min || minoff > lr_max) { 1004 /* no overlap with LR */ 1005 } else { 1006 return True; 1007 } 1008 1009 if (maxoff < r2_min || minoff > r2_max) { 1010 /* no overlap with R2 */ 1011 } else { 1012 return True; 1013 } 1014 1015 if (maxoff < cia_min || minoff > cia_max) { 1016 /* no overlap with CIA */ 1017 } else { 1018 return True; 1019 } 1020 1021 return False; 1022 } 1023 1024 1025 #define ALWAYSDEFD32(field) \ 1026 { offsetof(VexGuestPPC32State, field), \ 1027 (sizeof ((VexGuestPPC32State*)0)->field) } 1028 1029 VexGuestLayout 1030 ppc32Guest_layout 1031 = { 1032 /* Total size of the guest state, in bytes. */ 1033 .total_sizeB = sizeof(VexGuestPPC32State), 1034 1035 /* Describe the stack pointer. */ 1036 .offset_SP = offsetof(VexGuestPPC32State,guest_GPR1), 1037 .sizeof_SP = 4, 1038 1039 /* Describe the frame pointer. */ 1040 .offset_FP = offsetof(VexGuestPPC32State,guest_GPR1), 1041 .sizeof_FP = 4, 1042 1043 /* Describe the instruction pointer. */ 1044 .offset_IP = offsetof(VexGuestPPC32State,guest_CIA), 1045 .sizeof_IP = 4, 1046 1047 /* Describe any sections to be regarded by Memcheck as 1048 'always-defined'. */ 1049 .n_alwaysDefd = 12, 1050 1051 .alwaysDefd 1052 = { /* 0 */ ALWAYSDEFD32(guest_CIA), 1053 /* 1 */ ALWAYSDEFD32(guest_EMNOTE), 1054 /* 2 */ ALWAYSDEFD32(guest_CMSTART), 1055 /* 3 */ ALWAYSDEFD32(guest_CMLEN), 1056 /* 4 */ ALWAYSDEFD32(guest_VSCR), 1057 /* 5 */ ALWAYSDEFD32(guest_FPROUND), 1058 /* 6 */ ALWAYSDEFD32(guest_NRADDR), 1059 /* 7 */ ALWAYSDEFD32(guest_NRADDR_GPR2), 1060 /* 8 */ ALWAYSDEFD32(guest_REDIR_SP), 1061 /* 9 */ ALWAYSDEFD32(guest_REDIR_STACK), 1062 /* 10 */ ALWAYSDEFD32(guest_IP_AT_SYSCALL), 1063 /* 11 */ ALWAYSDEFD32(guest_C_FPCC) 1064 } 1065 }; 1066 1067 #define ALWAYSDEFD64(field) \ 1068 { offsetof(VexGuestPPC64State, field), \ 1069 (sizeof ((VexGuestPPC64State*)0)->field) } 1070 1071 VexGuestLayout 1072 ppc64Guest_layout 1073 = { 1074 /* Total size of the guest state, in bytes. */ 1075 .total_sizeB = sizeof(VexGuestPPC64State), 1076 1077 /* Describe the stack pointer. */ 1078 .offset_SP = offsetof(VexGuestPPC64State,guest_GPR1), 1079 .sizeof_SP = 8, 1080 1081 /* Describe the frame pointer. */ 1082 .offset_FP = offsetof(VexGuestPPC64State,guest_GPR1), 1083 .sizeof_FP = 8, 1084 1085 /* Describe the instruction pointer. */ 1086 .offset_IP = offsetof(VexGuestPPC64State,guest_CIA), 1087 .sizeof_IP = 8, 1088 1089 /* Describe any sections to be regarded by Memcheck as 1090 'always-defined'. */ 1091 .n_alwaysDefd = 12, 1092 1093 .alwaysDefd 1094 = { /* 0 */ ALWAYSDEFD64(guest_CIA), 1095 /* 1 */ ALWAYSDEFD64(guest_EMNOTE), 1096 /* 2 */ ALWAYSDEFD64(guest_CMSTART), 1097 /* 3 */ ALWAYSDEFD64(guest_CMLEN), 1098 /* 4 */ ALWAYSDEFD64(guest_VSCR), 1099 /* 5 */ ALWAYSDEFD64(guest_FPROUND), 1100 /* 6 */ ALWAYSDEFD64(guest_NRADDR), 1101 /* 7 */ ALWAYSDEFD64(guest_NRADDR_GPR2), 1102 /* 8 */ ALWAYSDEFD64(guest_REDIR_SP), 1103 /* 9 */ ALWAYSDEFD64(guest_REDIR_STACK), 1104 /* 10 */ ALWAYSDEFD64(guest_IP_AT_SYSCALL), 1105 /* 11 */ ALWAYSDEFD64(guest_C_FPCC) 1106 } 1107 }; 1108 1109 /*---------------------------------------------------------------*/ 1110 /*--- end guest_ppc_helpers.c ---*/ 1111 /*---------------------------------------------------------------*/ 1112