1 2 /*--------------------------------------------------------------------*/ 3 /*--- Interface to LibVEX_Translate, and the SP-update pass ---*/ 4 /*--- m_translate.c ---*/ 5 /*--------------------------------------------------------------------*/ 6 7 /* 8 This file is part of Valgrind, a dynamic binary instrumentation 9 framework. 10 11 Copyright (C) 2000-2015 Julian Seward 12 jseward (at) acm.org 13 14 This program is free software; you can redistribute it and/or 15 modify it under the terms of the GNU General Public License as 16 published by the Free Software Foundation; either version 2 of the 17 License, or (at your option) any later version. 18 19 This program is distributed in the hope that it will be useful, but 20 WITHOUT ANY WARRANTY; without even the implied warranty of 21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22 General Public License for more details. 23 24 You should have received a copy of the GNU General Public License 25 along with this program; if not, write to the Free Software 26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 27 02111-1307, USA. 28 29 The GNU General Public License is contained in the file COPYING. 30 */ 31 32 #include "pub_core_basics.h" 33 #include "pub_core_vki.h" 34 #include "pub_core_aspacemgr.h" 35 36 #include "pub_core_machine.h" // VG_(fnptr_to_fnentry) 37 // VG_(get_SP) 38 // VG_(machine_get_VexArchInfo) 39 #include "pub_core_libcbase.h" 40 #include "pub_core_libcassert.h" 41 #include "pub_core_libcprint.h" 42 #include "pub_core_options.h" 43 44 #include "pub_core_debuginfo.h" // VG_(get_fnname_w_offset) 45 #include "pub_core_redir.h" // VG_(redir_do_lookup) 46 47 #include "pub_core_signals.h" // VG_(synth_fault_{perms,mapping} 48 #include "pub_core_stacks.h" // VG_(unknown_SP_update*)() 49 #include "pub_core_tooliface.h" // VG_(tdict) 50 51 #include "pub_core_translate.h" 52 #include "pub_core_transtab.h" 53 #include "pub_core_dispatch.h" // VG_(run_innerloop__dispatch_{un}profiled) 54 // VG_(run_a_noredir_translation__return_point) 55 56 #include "pub_core_threadstate.h" // VexGuestArchState 57 #include "pub_core_trampoline.h" // VG_(ppctoc_magic_redirect_return_stub) 58 59 #include "pub_core_execontext.h" // VG_(make_depth_1_ExeContext_from_Addr) 60 61 #include "pub_core_gdbserver.h" // VG_(instrument_for_gdbserver_if_needed) 62 63 #include "libvex_emnote.h" // For PPC, EmWarn_PPC64_redir_underflow 64 65 /*------------------------------------------------------------*/ 66 /*--- Stats ---*/ 67 /*------------------------------------------------------------*/ 68 69 static ULong n_SP_updates_fast = 0; 70 static ULong n_SP_updates_generic_known = 0; 71 static ULong n_SP_updates_generic_unknown = 0; 72 73 static ULong n_PX_VexRegUpdSpAtMemAccess = 0; 74 static ULong n_PX_VexRegUpdUnwindregsAtMemAccess = 0; 75 static ULong n_PX_VexRegUpdAllregsAtMemAccess = 0; 76 static ULong n_PX_VexRegUpdAllregsAtEachInsn = 0; 77 78 void VG_(print_translation_stats) ( void ) 79 { 80 UInt n_SP_updates = n_SP_updates_fast + n_SP_updates_generic_known 81 + n_SP_updates_generic_unknown; 82 if (n_SP_updates == 0) { 83 VG_(message)(Vg_DebugMsg, "translate: no SP updates identified\n"); 84 } else { 85 VG_(message)(Vg_DebugMsg, 86 "translate: fast SP updates identified: %'llu (%3.1f%%)\n", 87 n_SP_updates_fast, n_SP_updates_fast * 100.0 / n_SP_updates ); 88 89 VG_(message)(Vg_DebugMsg, 90 "translate: generic_known SP updates identified: %'llu (%3.1f%%)\n", 91 n_SP_updates_generic_known, 92 n_SP_updates_generic_known * 100.0 / n_SP_updates ); 93 94 VG_(message)(Vg_DebugMsg, 95 "translate: generic_unknown SP updates identified: %'llu (%3.1f%%)\n", 96 n_SP_updates_generic_unknown, 97 n_SP_updates_generic_unknown * 100.0 / n_SP_updates ); 98 } 99 100 VG_(message)(Vg_DebugMsg, 101 "translate: PX: SPonly %'llu, UnwRegs %'llu, AllRegs %'llu, AllRegsAllInsns %'llu\n", n_PX_VexRegUpdSpAtMemAccess, n_PX_VexRegUpdUnwindregsAtMemAccess, n_PX_VexRegUpdAllregsAtMemAccess, n_PX_VexRegUpdAllregsAtEachInsn); 102 } 103 104 /*------------------------------------------------------------*/ 105 /*--- %SP-update pass ---*/ 106 /*------------------------------------------------------------*/ 107 108 static Bool need_to_handle_SP_assignment(void) 109 { 110 return ( VG_(tdict).track_new_mem_stack_4 || 111 VG_(tdict).track_die_mem_stack_4 || 112 VG_(tdict).track_new_mem_stack_8 || 113 VG_(tdict).track_die_mem_stack_8 || 114 VG_(tdict).track_new_mem_stack_12 || 115 VG_(tdict).track_die_mem_stack_12 || 116 VG_(tdict).track_new_mem_stack_16 || 117 VG_(tdict).track_die_mem_stack_16 || 118 VG_(tdict).track_new_mem_stack_32 || 119 VG_(tdict).track_die_mem_stack_32 || 120 VG_(tdict).track_new_mem_stack_112 || 121 VG_(tdict).track_die_mem_stack_112 || 122 VG_(tdict).track_new_mem_stack_128 || 123 VG_(tdict).track_die_mem_stack_128 || 124 VG_(tdict).track_new_mem_stack_144 || 125 VG_(tdict).track_die_mem_stack_144 || 126 VG_(tdict).track_new_mem_stack_160 || 127 VG_(tdict).track_die_mem_stack_160 || 128 VG_(tdict).track_new_mem_stack || 129 VG_(tdict).track_die_mem_stack ); 130 } 131 132 // - The SP aliases are held in an array which is used as a circular buffer. 133 // This misses very few constant updates of SP (ie. < 0.1%) while using a 134 // small, constant structure that will also never fill up and cause 135 // execution to abort. 136 // - Unused slots have a .temp value of 'IRTemp_INVALID'. 137 // - 'next_SP_alias_slot' is the index where the next alias will be stored. 138 // - If the buffer fills, we circle around and start over-writing 139 // non-IRTemp_INVALID values. This is rare, and the overwriting of a 140 // value that would have subsequently be used is even rarer. 141 // - Every slot below next_SP_alias_slot holds a non-IRTemp_INVALID value. 142 // The rest either all won't (if we haven't yet circled around) or all 143 // will (if we have circled around). 144 145 typedef 146 struct { 147 IRTemp temp; 148 Long delta; 149 } 150 SP_Alias; 151 152 // With 32 slots the buffer fills very rarely -- eg. once in a run of GCC. 153 // And I've tested with smaller values and the wrap-around case works ok. 154 #define N_ALIASES 32 155 static SP_Alias SP_aliases[N_ALIASES]; 156 static Int next_SP_alias_slot = 0; 157 158 static void clear_SP_aliases(void) 159 { 160 Int i; 161 for (i = 0; i < N_ALIASES; i++) { 162 SP_aliases[i].temp = IRTemp_INVALID; 163 SP_aliases[i].delta = 0; 164 } 165 next_SP_alias_slot = 0; 166 } 167 168 static void add_SP_alias(IRTemp temp, Long delta) 169 { 170 vg_assert(temp != IRTemp_INVALID); 171 SP_aliases[ next_SP_alias_slot ].temp = temp; 172 SP_aliases[ next_SP_alias_slot ].delta = delta; 173 next_SP_alias_slot++; 174 if (N_ALIASES == next_SP_alias_slot) next_SP_alias_slot = 0; 175 } 176 177 static Bool get_SP_delta(IRTemp temp, Long* delta) 178 { 179 Int i; // i must be signed! 180 vg_assert(IRTemp_INVALID != temp); 181 // Search backwards between current buffer position and the start. 182 for (i = next_SP_alias_slot-1; i >= 0; i--) { 183 if (temp == SP_aliases[i].temp) { 184 *delta = SP_aliases[i].delta; 185 return True; 186 } 187 } 188 // Search backwards between the end and the current buffer position. 189 for (i = N_ALIASES-1; i >= next_SP_alias_slot; i--) { 190 if (temp == SP_aliases[i].temp) { 191 *delta = SP_aliases[i].delta; 192 return True; 193 } 194 } 195 return False; 196 } 197 198 static void update_SP_aliases(Long delta) 199 { 200 Int i; 201 for (i = 0; i < N_ALIASES; i++) { 202 if (SP_aliases[i].temp == IRTemp_INVALID) { 203 return; 204 } 205 SP_aliases[i].delta += delta; 206 } 207 } 208 209 /* Given a guest IP, get an origin tag for a 1-element stack trace, 210 and wrap it up in an IR atom that can be passed as the origin-tag 211 value for a stack-adjustment helper function. */ 212 static IRExpr* mk_ecu_Expr ( Addr guest_IP ) 213 { 214 UInt ecu; 215 ExeContext* ec 216 = VG_(make_depth_1_ExeContext_from_Addr)( guest_IP ); 217 vg_assert(ec); 218 ecu = VG_(get_ECU_from_ExeContext)( ec ); 219 vg_assert(VG_(is_plausible_ECU)(ecu)); 220 /* This is always safe to do, since ecu is only 32 bits, and 221 HWord is 32 or 64. */ 222 return mkIRExpr_HWord( (HWord)ecu ); 223 } 224 225 /* When gdbserver is activated, the translation of a block must 226 first be done by the tool function, then followed by a pass 227 which (if needed) instruments the code for gdbserver. 228 */ 229 static 230 IRSB* tool_instrument_then_gdbserver_if_needed ( VgCallbackClosure* closureV, 231 IRSB* sb_in, 232 const VexGuestLayout* layout, 233 const VexGuestExtents* vge, 234 const VexArchInfo* vai, 235 IRType gWordTy, 236 IRType hWordTy ) 237 { 238 return VG_(instrument_for_gdbserver_if_needed) 239 (VG_(tdict).tool_instrument (closureV, 240 sb_in, 241 layout, 242 vge, 243 vai, 244 gWordTy, 245 hWordTy), 246 layout, 247 vge, 248 gWordTy, 249 hWordTy); 250 } 251 252 /* For tools that want to know about SP changes, this pass adds 253 in the appropriate hooks. We have to do it after the tool's 254 instrumentation, so the tool doesn't have to worry about the C calls 255 it adds in, and we must do it before register allocation because 256 spilled temps make it much harder to work out the SP deltas. 257 This it is done with Vex's "second instrumentation" pass. 258 259 Basically, we look for GET(SP)/PUT(SP) pairs and track constant 260 increments/decrements of SP between them. (This requires tracking one or 261 more "aliases", which are not exact aliases but instead are tempregs 262 whose value is equal to the SP's plus or minus a known constant.) 263 If all the changes to SP leading up to a PUT(SP) are by known, small 264 constants, we can do a specific call to eg. new_mem_stack_4, otherwise 265 we fall back to the case that handles an unknown SP change. 266 267 There is some extra complexity to deal correctly with updates to 268 only parts of SP. Bizarre, but it has been known to happen. 269 */ 270 static 271 IRSB* vg_SP_update_pass ( void* closureV, 272 IRSB* sb_in, 273 const VexGuestLayout* layout, 274 const VexGuestExtents* vge, 275 const VexArchInfo* vai, 276 IRType gWordTy, 277 IRType hWordTy ) 278 { 279 Int i, j, k, minoff_ST, maxoff_ST, sizeof_SP, offset_SP; 280 Int first_SP, last_SP, first_Put, last_Put; 281 IRDirty *dcall, *d; 282 IRStmt* st; 283 IRExpr* e; 284 IRRegArray* descr; 285 IRType typeof_SP; 286 Long delta, con; 287 288 /* Set up stuff for tracking the guest IP */ 289 Bool curr_IP_known = False; 290 Addr curr_IP = 0; 291 292 /* Set up BB */ 293 IRSB* bb = emptyIRSB(); 294 bb->tyenv = deepCopyIRTypeEnv(sb_in->tyenv); 295 bb->next = deepCopyIRExpr(sb_in->next); 296 bb->jumpkind = sb_in->jumpkind; 297 bb->offsIP = sb_in->offsIP; 298 299 delta = 0; 300 301 sizeof_SP = layout->sizeof_SP; 302 offset_SP = layout->offset_SP; 303 typeof_SP = sizeof_SP==4 ? Ity_I32 : Ity_I64; 304 vg_assert(sizeof_SP == 4 || sizeof_SP == 8); 305 306 /* --- Start of #defines --- */ 307 308 # define IS_ADD(op) (sizeof_SP==4 ? ((op)==Iop_Add32) : ((op)==Iop_Add64)) 309 # define IS_SUB(op) (sizeof_SP==4 ? ((op)==Iop_Sub32) : ((op)==Iop_Sub64)) 310 311 # define IS_ADD_OR_SUB(op) (IS_ADD(op) || IS_SUB(op)) 312 313 # define GET_CONST(con) \ 314 (sizeof_SP==4 ? (Long)(Int)(con->Ico.U32) \ 315 : (Long)(con->Ico.U64)) 316 317 # define DO_NEW(syze, tmpp) \ 318 do { \ 319 Bool vanilla, w_ecu; \ 320 vg_assert(curr_IP_known); \ 321 vanilla = NULL != VG_(tdict).track_new_mem_stack_##syze; \ 322 w_ecu = NULL != VG_(tdict).track_new_mem_stack_##syze##_w_ECU; \ 323 vg_assert(!(vanilla && w_ecu)); /* can't have both */ \ 324 if (!(vanilla || w_ecu)) \ 325 goto generic; \ 326 \ 327 /* I don't know if it's really necessary to say that the */ \ 328 /* call reads the stack pointer. But anyway, we do. */ \ 329 if (w_ecu) { \ 330 dcall = unsafeIRDirty_0_N( \ 331 2/*regparms*/, \ 332 "track_new_mem_stack_" #syze "_w_ECU", \ 333 VG_(fnptr_to_fnentry)( \ 334 VG_(tdict).track_new_mem_stack_##syze##_w_ECU ), \ 335 mkIRExprVec_2(IRExpr_RdTmp(tmpp), \ 336 mk_ecu_Expr(curr_IP)) \ 337 ); \ 338 } else { \ 339 dcall = unsafeIRDirty_0_N( \ 340 1/*regparms*/, \ 341 "track_new_mem_stack_" #syze , \ 342 VG_(fnptr_to_fnentry)( \ 343 VG_(tdict).track_new_mem_stack_##syze ), \ 344 mkIRExprVec_1(IRExpr_RdTmp(tmpp)) \ 345 ); \ 346 } \ 347 dcall->nFxState = 1; \ 348 dcall->fxState[0].fx = Ifx_Read; \ 349 dcall->fxState[0].offset = layout->offset_SP; \ 350 dcall->fxState[0].size = layout->sizeof_SP; \ 351 dcall->fxState[0].nRepeats = 0; \ 352 dcall->fxState[0].repeatLen = 0; \ 353 \ 354 addStmtToIRSB( bb, IRStmt_Dirty(dcall) ); \ 355 \ 356 vg_assert(syze > 0); \ 357 update_SP_aliases(syze); \ 358 \ 359 n_SP_updates_fast++; \ 360 \ 361 } while (0) 362 363 # define DO_DIE(syze, tmpp) \ 364 do { \ 365 if (!VG_(tdict).track_die_mem_stack_##syze) \ 366 goto generic; \ 367 \ 368 /* I don't know if it's really necessary to say that the */ \ 369 /* call reads the stack pointer. But anyway, we do. */ \ 370 dcall = unsafeIRDirty_0_N( \ 371 1/*regparms*/, \ 372 "track_die_mem_stack_" #syze, \ 373 VG_(fnptr_to_fnentry)( \ 374 VG_(tdict).track_die_mem_stack_##syze ), \ 375 mkIRExprVec_1(IRExpr_RdTmp(tmpp)) \ 376 ); \ 377 dcall->nFxState = 1; \ 378 dcall->fxState[0].fx = Ifx_Read; \ 379 dcall->fxState[0].offset = layout->offset_SP; \ 380 dcall->fxState[0].size = layout->sizeof_SP; \ 381 dcall->fxState[0].nRepeats = 0; \ 382 dcall->fxState[0].repeatLen = 0; \ 383 \ 384 addStmtToIRSB( bb, IRStmt_Dirty(dcall) ); \ 385 \ 386 vg_assert(syze > 0); \ 387 update_SP_aliases(-(syze)); \ 388 \ 389 n_SP_updates_fast++; \ 390 \ 391 } while (0) 392 393 /* --- End of #defines --- */ 394 395 clear_SP_aliases(); 396 397 for (i = 0; i < sb_in->stmts_used; i++) { 398 399 st = sb_in->stmts[i]; 400 401 if (st->tag == Ist_IMark) { 402 curr_IP_known = True; 403 curr_IP = st->Ist.IMark.addr; 404 } 405 406 /* t = Get(sp): curr = t, delta = 0 */ 407 if (st->tag != Ist_WrTmp) goto case2; 408 e = st->Ist.WrTmp.data; 409 if (e->tag != Iex_Get) goto case2; 410 if (e->Iex.Get.offset != offset_SP) goto case2; 411 if (e->Iex.Get.ty != typeof_SP) goto case2; 412 vg_assert( typeOfIRTemp(bb->tyenv, st->Ist.WrTmp.tmp) == typeof_SP ); 413 add_SP_alias(st->Ist.WrTmp.tmp, 0); 414 addStmtToIRSB( bb, st ); 415 continue; 416 417 case2: 418 /* t' = curr +/- const: curr = t', delta +=/-= const */ 419 if (st->tag != Ist_WrTmp) goto case3; 420 e = st->Ist.WrTmp.data; 421 if (e->tag != Iex_Binop) goto case3; 422 if (e->Iex.Binop.arg1->tag != Iex_RdTmp) goto case3; 423 if (!get_SP_delta(e->Iex.Binop.arg1->Iex.RdTmp.tmp, &delta)) goto case3; 424 if (e->Iex.Binop.arg2->tag != Iex_Const) goto case3; 425 if (!IS_ADD_OR_SUB(e->Iex.Binop.op)) goto case3; 426 con = GET_CONST(e->Iex.Binop.arg2->Iex.Const.con); 427 vg_assert( typeOfIRTemp(bb->tyenv, st->Ist.WrTmp.tmp) == typeof_SP ); 428 if (IS_ADD(e->Iex.Binop.op)) { 429 add_SP_alias(st->Ist.WrTmp.tmp, delta + con); 430 } else { 431 add_SP_alias(st->Ist.WrTmp.tmp, delta - con); 432 } 433 addStmtToIRSB( bb, st ); 434 continue; 435 436 case3: 437 /* t' = curr: curr = t' */ 438 if (st->tag != Ist_WrTmp) goto case4; 439 e = st->Ist.WrTmp.data; 440 if (e->tag != Iex_RdTmp) goto case4; 441 if (!get_SP_delta(e->Iex.RdTmp.tmp, &delta)) goto case4; 442 vg_assert( typeOfIRTemp(bb->tyenv, st->Ist.WrTmp.tmp) == typeof_SP ); 443 add_SP_alias(st->Ist.WrTmp.tmp, delta); 444 addStmtToIRSB( bb, st ); 445 continue; 446 447 case4: 448 /* Put(sp) = curr */ 449 /* More generally, we must correctly handle a Put which writes 450 any part of SP, not just the case where all of SP is 451 written. */ 452 if (st->tag != Ist_Put) goto case5; 453 first_SP = offset_SP; 454 last_SP = first_SP + sizeof_SP - 1; 455 first_Put = st->Ist.Put.offset; 456 last_Put = first_Put 457 + sizeofIRType( typeOfIRExpr( bb->tyenv, st->Ist.Put.data )) 458 - 1; 459 vg_assert(first_SP <= last_SP); 460 vg_assert(first_Put <= last_Put); 461 462 if (last_Put < first_SP || last_SP < first_Put) 463 goto case5; /* no overlap */ 464 465 if (st->Ist.Put.data->tag == Iex_RdTmp 466 && get_SP_delta(st->Ist.Put.data->Iex.RdTmp.tmp, &delta)) { 467 IRTemp tttmp = st->Ist.Put.data->Iex.RdTmp.tmp; 468 /* Why should the following assertion hold? Because any 469 alias added by put_SP_alias must be of a temporary which 470 has the same type as typeof_SP, and whose value is a Get 471 at exactly offset_SP of size typeof_SP. Each call to 472 put_SP_alias is immediately preceded by an assertion that 473 we are putting in a binding for a correctly-typed 474 temporary. */ 475 vg_assert( typeOfIRTemp(bb->tyenv, tttmp) == typeof_SP ); 476 /* From the same type-and-offset-correctness argument, if 477 we found a useable alias, it must for an "exact" write of SP. */ 478 vg_assert(first_SP == first_Put); 479 vg_assert(last_SP == last_Put); 480 switch (delta) { 481 case 0: addStmtToIRSB(bb,st); continue; 482 case 4: DO_DIE( 4, tttmp); addStmtToIRSB(bb,st); continue; 483 case -4: DO_NEW( 4, tttmp); addStmtToIRSB(bb,st); continue; 484 case 8: DO_DIE( 8, tttmp); addStmtToIRSB(bb,st); continue; 485 case -8: DO_NEW( 8, tttmp); addStmtToIRSB(bb,st); continue; 486 case 12: DO_DIE( 12, tttmp); addStmtToIRSB(bb,st); continue; 487 case -12: DO_NEW( 12, tttmp); addStmtToIRSB(bb,st); continue; 488 case 16: DO_DIE( 16, tttmp); addStmtToIRSB(bb,st); continue; 489 case -16: DO_NEW( 16, tttmp); addStmtToIRSB(bb,st); continue; 490 case 32: DO_DIE( 32, tttmp); addStmtToIRSB(bb,st); continue; 491 case -32: DO_NEW( 32, tttmp); addStmtToIRSB(bb,st); continue; 492 case 112: DO_DIE( 112, tttmp); addStmtToIRSB(bb,st); continue; 493 case -112: DO_NEW( 112, tttmp); addStmtToIRSB(bb,st); continue; 494 case 128: DO_DIE( 128, tttmp); addStmtToIRSB(bb,st); continue; 495 case -128: DO_NEW( 128, tttmp); addStmtToIRSB(bb,st); continue; 496 case 144: DO_DIE( 144, tttmp); addStmtToIRSB(bb,st); continue; 497 case -144: DO_NEW( 144, tttmp); addStmtToIRSB(bb,st); continue; 498 case 160: DO_DIE( 160, tttmp); addStmtToIRSB(bb,st); continue; 499 case -160: DO_NEW( 160, tttmp); addStmtToIRSB(bb,st); continue; 500 default: 501 /* common values for ppc64: 144 128 160 112 176 */ 502 n_SP_updates_generic_known++; 503 goto generic; 504 } 505 } else { 506 /* Deal with an unknown update to SP. We're here because 507 either: 508 (1) the Put does not exactly cover SP; it is a partial update. 509 Highly unlikely, but has been known to happen for 16-bit 510 Windows apps running on Wine, doing 16-bit adjustments to 511 %sp. 512 (2) the Put does exactly cover SP, but we are unable to 513 determine how the value relates to the old SP. In any 514 case, we cannot assume that the Put.data value is a tmp; 515 we must assume it can be anything allowed in flat IR (tmp 516 or const). 517 */ 518 IRTemp old_SP; 519 n_SP_updates_generic_unknown++; 520 521 // Nb: if all is well, this generic case will typically be 522 // called something like every 1000th SP update. If it's more than 523 // that, the above code may be missing some cases. 524 generic: 525 /* Pass both the old and new SP values to this helper. Also, 526 pass an origin tag, even if it isn't needed. */ 527 old_SP = newIRTemp(bb->tyenv, typeof_SP); 528 addStmtToIRSB( 529 bb, 530 IRStmt_WrTmp( old_SP, IRExpr_Get(offset_SP, typeof_SP) ) 531 ); 532 533 /* Now we know what the old value of SP is. But knowing the new 534 value is a bit tricky if there is a partial write. */ 535 if (first_Put == first_SP && last_Put == last_SP) { 536 /* The common case, an exact write to SP. So st->Ist.Put.data 537 does hold the new value; simple. */ 538 vg_assert(curr_IP_known); 539 if (NULL != VG_(tdict).track_new_mem_stack_w_ECU) 540 dcall = unsafeIRDirty_0_N( 541 3/*regparms*/, 542 "VG_(unknown_SP_update_w_ECU)", 543 VG_(fnptr_to_fnentry)( &VG_(unknown_SP_update_w_ECU) ), 544 mkIRExprVec_3( IRExpr_RdTmp(old_SP), st->Ist.Put.data, 545 mk_ecu_Expr(curr_IP) ) 546 ); 547 else 548 dcall = unsafeIRDirty_0_N( 549 2/*regparms*/, 550 "VG_(unknown_SP_update)", 551 VG_(fnptr_to_fnentry)( &VG_(unknown_SP_update) ), 552 mkIRExprVec_2( IRExpr_RdTmp(old_SP), st->Ist.Put.data ) 553 ); 554 555 addStmtToIRSB( bb, IRStmt_Dirty(dcall) ); 556 /* don't forget the original assignment */ 557 addStmtToIRSB( bb, st ); 558 } else { 559 /* We have a partial update to SP. We need to know what 560 the new SP will be, and hand that to the helper call, 561 but when the helper call happens, SP must hold the 562 value it had before the update. Tricky. 563 Therefore use the following kludge: 564 1. do the partial SP update (Put) 565 2. Get the new SP value into a tmp, new_SP 566 3. Put old_SP 567 4. Call the helper 568 5. Put new_SP 569 */ 570 IRTemp new_SP; 571 /* 1 */ 572 addStmtToIRSB( bb, st ); 573 /* 2 */ 574 new_SP = newIRTemp(bb->tyenv, typeof_SP); 575 addStmtToIRSB( 576 bb, 577 IRStmt_WrTmp( new_SP, IRExpr_Get(offset_SP, typeof_SP) ) 578 ); 579 /* 3 */ 580 addStmtToIRSB( bb, IRStmt_Put(offset_SP, IRExpr_RdTmp(old_SP) )); 581 /* 4 */ 582 vg_assert(curr_IP_known); 583 if (NULL != VG_(tdict).track_new_mem_stack_w_ECU) 584 dcall = unsafeIRDirty_0_N( 585 3/*regparms*/, 586 "VG_(unknown_SP_update_w_ECU)", 587 VG_(fnptr_to_fnentry)( &VG_(unknown_SP_update_w_ECU) ), 588 mkIRExprVec_3( IRExpr_RdTmp(old_SP), 589 IRExpr_RdTmp(new_SP), 590 mk_ecu_Expr(curr_IP) ) 591 ); 592 else 593 dcall = unsafeIRDirty_0_N( 594 2/*regparms*/, 595 "VG_(unknown_SP_update)", 596 VG_(fnptr_to_fnentry)( &VG_(unknown_SP_update) ), 597 mkIRExprVec_2( IRExpr_RdTmp(old_SP), 598 IRExpr_RdTmp(new_SP) ) 599 ); 600 addStmtToIRSB( bb, IRStmt_Dirty(dcall) ); 601 /* 5 */ 602 addStmtToIRSB( bb, IRStmt_Put(offset_SP, IRExpr_RdTmp(new_SP) )); 603 } 604 605 /* Forget what we already know. */ 606 clear_SP_aliases(); 607 608 /* If this is a Put of a tmp that exactly updates SP, 609 start tracking aliases against this tmp. */ 610 611 if (first_Put == first_SP && last_Put == last_SP 612 && st->Ist.Put.data->tag == Iex_RdTmp) { 613 vg_assert( typeOfIRTemp(bb->tyenv, st->Ist.Put.data->Iex.RdTmp.tmp) 614 == typeof_SP ); 615 add_SP_alias(st->Ist.Put.data->Iex.RdTmp.tmp, 0); 616 } 617 continue; 618 } 619 620 case5: 621 /* PutI or Dirty call which overlaps SP: complain. We can't 622 deal with SP changing in weird ways (well, we can, but not at 623 this time of night). */ 624 if (st->tag == Ist_PutI) { 625 descr = st->Ist.PutI.details->descr; 626 minoff_ST = descr->base; 627 maxoff_ST = descr->base 628 + descr->nElems * sizeofIRType(descr->elemTy) - 1; 629 if (!(offset_SP > maxoff_ST 630 || (offset_SP + sizeof_SP - 1) < minoff_ST)) 631 goto complain; 632 } 633 if (st->tag == Ist_Dirty) { 634 d = st->Ist.Dirty.details; 635 for (j = 0; j < d->nFxState; j++) { 636 if (d->fxState[j].fx == Ifx_Read || d->fxState[j].fx == Ifx_None) 637 continue; 638 /* Enumerate the described state segments */ 639 for (k = 0; k < 1 + d->fxState[j].nRepeats; k++) { 640 minoff_ST = d->fxState[j].offset + k * d->fxState[j].repeatLen; 641 maxoff_ST = minoff_ST + d->fxState[j].size - 1; 642 if (!(offset_SP > maxoff_ST 643 || (offset_SP + sizeof_SP - 1) < minoff_ST)) 644 goto complain; 645 } 646 } 647 } 648 649 /* well, not interesting. Just copy and keep going. */ 650 addStmtToIRSB( bb, st ); 651 652 } /* for (i = 0; i < sb_in->stmts_used; i++) */ 653 654 return bb; 655 656 complain: 657 VG_(core_panic)("vg_SP_update_pass: PutI or Dirty which overlaps SP"); 658 659 #undef IS_ADD 660 #undef IS_SUB 661 #undef IS_ADD_OR_SUB 662 #undef GET_CONST 663 #undef DO_NEW 664 #undef DO_DIE 665 } 666 667 /*------------------------------------------------------------*/ 668 /*--- Main entry point for the JITter. ---*/ 669 /*------------------------------------------------------------*/ 670 671 /* Extra comments re self-checking translations and self-modifying 672 code. (JRS 14 Oct 05). 673 674 There are 3 modes: 675 (1) no checking: all code assumed to be not self-modifying 676 (2) partial: known-problematic situations get a self-check 677 (3) full checking: all translations get a self-check 678 679 As currently implemented, the default is (2). (3) is always safe, 680 but very slow. (1) works mostly, but fails for gcc nested-function 681 code which uses trampolines on the stack; this situation is 682 detected and handled by (2). 683 684 ---------- 685 686 A more robust and transparent solution, which is not currently 687 implemented, is a variant of (2): if a translation is made from an 688 area which aspacem says does not have 'w' permission, then it can 689 be non-self-checking. Otherwise, it needs a self-check. 690 691 This is complicated by Vex's basic-block chasing. If a self-check 692 is requested, then Vex will not chase over basic block boundaries 693 (it's too complex). However there is still a problem if it chases 694 from a non-'w' area into a 'w' area. 695 696 I think the right thing to do is: 697 698 - if a translation request starts in a 'w' area, ask for a 699 self-checking translation, and do not allow any chasing (make 700 chase_into_ok return False). Note that the latter is redundant 701 in the sense that Vex won't chase anyway in this situation. 702 703 - if a translation request starts in a non-'w' area, do not ask for 704 a self-checking translation. However, do not allow chasing (as 705 determined by chase_into_ok) to go into a 'w' area. 706 707 The result of this is that all code inside 'w' areas is self 708 checking. 709 710 To complete the trick, there is a caveat: we must watch the 711 client's mprotect calls. If pages are changed from non-'w' to 'w' 712 then we should throw away all translations which intersect the 713 affected area, so as to force them to be redone with self-checks. 714 715 ---------- 716 717 The above outlines the conditions under which bb chasing is allowed 718 from a self-modifying-code point of view. There are other 719 situations pertaining to function redirection in which it is 720 necessary to disallow chasing, but those fall outside the scope of 721 this comment. 722 */ 723 724 725 /* Vex dumps the final code in here. Then we can copy it off 726 wherever we like. */ 727 /* 60000: should agree with assertion in VG_(add_to_transtab) in 728 m_transtab.c. */ 729 #define N_TMPBUF 60000 730 static UChar tmpbuf[N_TMPBUF]; 731 732 733 /* Function pointers we must supply to LibVEX in order that it 734 can bomb out and emit messages under Valgrind's control. */ 735 __attribute__ ((noreturn)) 736 static 737 void failure_exit ( void ) 738 { 739 LibVEX_ShowAllocStats(); 740 VG_(core_panic)("LibVEX called failure_exit()."); 741 } 742 743 static 744 void log_bytes ( const HChar* bytes, SizeT nbytes ) 745 { 746 SizeT i = 0; 747 if (nbytes >= 4) 748 for (; i < nbytes-3; i += 4) 749 VG_(printf)("%c%c%c%c", bytes[i], bytes[i+1], bytes[i+2], bytes[i+3]); 750 for (; i < nbytes; i++) 751 VG_(printf)("%c", bytes[i]); 752 } 753 754 755 /* --------- Various helper functions for translation --------- */ 756 757 /* Look for reasons to disallow making translations from the given 758 segment/addr. */ 759 760 static Bool translations_allowable_from_seg ( NSegment const* seg, Addr addr ) 761 { 762 # if defined(VGA_x86) || defined(VGA_s390x) || defined(VGA_mips32) \ 763 || defined(VGA_mips64) || defined(VGA_tilegx) 764 Bool allowR = True; 765 # else 766 Bool allowR = False; 767 # endif 768 return seg != NULL 769 && (seg->kind == SkAnonC || seg->kind == SkFileC || seg->kind == SkShmC) 770 && (seg->hasX 771 || (seg->hasR && (allowR 772 || VG_(has_gdbserver_breakpoint) (addr)))); 773 /* If GDB/gdbsrv has inserted a breakpoint at addr, assume this is a valid 774 location to translate if seg is not executable but is readable. 775 This is needed for inferior function calls from GDB: GDB inserts a 776 breakpoint on the stack, and expects to regain control before the 777 breakpoint instruction at the breakpoint address is really 778 executed. For this, the breakpoint instruction must be translated 779 so as to have the call to gdbserver executed. */ 780 } 781 782 783 /* Produce a bitmask stating which of the supplied extents needs a 784 self-check. See documentation of 785 VexTranslateArgs::needs_self_check for more details about the 786 return convention. */ 787 788 static UInt needs_self_check ( void* closureV, 789 /*MAYBE_MOD*/VexRegisterUpdates* pxControl, 790 const VexGuestExtents* vge ) 791 { 792 VgCallbackClosure* closure = (VgCallbackClosure*)closureV; 793 UInt i, bitset; 794 795 vg_assert(vge->n_used >= 1 && vge->n_used <= 3); 796 bitset = 0; 797 798 /* Will we need to do a second pass in order to compute a 799 revised *pxControl value? */ 800 Bool pxStatusMightChange 801 = /* "the user actually set it" */ 802 VG_(clo_px_file_backed) != VexRegUpd_INVALID 803 /* "and they set it to something other than the default. */ 804 && *pxControl != VG_(clo_px_file_backed); 805 806 /* First, compute |bitset|, which specifies which extent(s) need a 807 self check. Whilst we're at it, note any NSegments that we get, 808 so as to reduce the number of calls required to 809 VG_(am_find_nsegment) in a possible second pass. */ 810 const NSegment *segs[3] = { NULL, NULL, NULL }; 811 812 for (i = 0; i < vge->n_used; i++) { 813 Bool check = False; 814 Addr addr = vge->base[i]; 815 SizeT len = vge->len[i]; 816 NSegment const* segA = NULL; 817 818 # if defined(VGO_darwin) 819 // GrP fixme hack - dyld i386 IMPORT gets rewritten. 820 // To really do this correctly, we'd need to flush the 821 // translation cache whenever a segment became +WX. 822 segA = VG_(am_find_nsegment)(addr); 823 if (segA && segA->hasX && segA->hasW) 824 check = True; 825 # endif 826 827 if (!check) { 828 switch (VG_(clo_smc_check)) { 829 case Vg_SmcNone: 830 /* never check (except as per Darwin hack above) */ 831 break; 832 case Vg_SmcAll: 833 /* always check */ 834 check = True; 835 break; 836 case Vg_SmcStack: { 837 /* check if the address is in the same segment as this 838 thread's stack pointer */ 839 Addr sp = VG_(get_SP)(closure->tid); 840 if (!segA) { 841 segA = VG_(am_find_nsegment)(addr); 842 } 843 NSegment const* segSP = VG_(am_find_nsegment)(sp); 844 if (segA && segSP && segA == segSP) 845 check = True; 846 break; 847 } 848 case Vg_SmcAllNonFile: { 849 /* check if any part of the extent is not in a 850 file-mapped segment */ 851 if (!segA) { 852 segA = VG_(am_find_nsegment)(addr); 853 } 854 if (segA && segA->kind == SkFileC && segA->start <= addr 855 && (len == 0 || addr + len <= segA->end + 1)) { 856 /* in a file-mapped segment; skip the check */ 857 } else { 858 check = True; 859 } 860 break; 861 } 862 default: 863 vg_assert(0); 864 } 865 } 866 867 if (check) 868 bitset |= (1 << i); 869 870 if (pxStatusMightChange && segA) { 871 vg_assert(i < sizeof(segs)/sizeof(segs[0])); 872 segs[i] = segA; 873 } 874 } 875 876 /* Now, possibly do a second pass, to see if the PX status might 877 change. This can happen if the user specified value via 878 --px-file-backed= which is different from the default PX value 879 specified via --vex-iropt-register-updates (also known by the 880 shorter alias --px-default). */ 881 if (pxStatusMightChange) { 882 883 Bool allFileBacked = True; 884 for (i = 0; i < vge->n_used; i++) { 885 Addr addr = vge->base[i]; 886 SizeT len = vge->len[i]; 887 NSegment const* segA = segs[i]; 888 if (!segA) { 889 /* If we don't have a cached value for |segA|, compute it now. */ 890 segA = VG_(am_find_nsegment)(addr); 891 } 892 vg_assert(segA); /* Can this ever fail? */ 893 if (segA && segA->kind == SkFileC && segA->start <= addr 894 && (len == 0 || addr + len <= segA->end + 1)) { 895 /* in a file-mapped segment */ 896 } else { 897 /* not in a file-mapped segment, or we can't figure out 898 where it is */ 899 allFileBacked = False; 900 break; 901 } 902 } 903 904 /* So, finally, if all the extents are in file backed segments, perform 905 the user-specified PX change. */ 906 if (allFileBacked) { 907 *pxControl = VG_(clo_px_file_backed); 908 } 909 910 } 911 912 /* Update running PX stats, as it is difficult without these to 913 check that the system is behaving as expected. */ 914 switch (*pxControl) { 915 case VexRegUpdSpAtMemAccess: 916 n_PX_VexRegUpdSpAtMemAccess++; break; 917 case VexRegUpdUnwindregsAtMemAccess: 918 n_PX_VexRegUpdUnwindregsAtMemAccess++; break; 919 case VexRegUpdAllregsAtMemAccess: 920 n_PX_VexRegUpdAllregsAtMemAccess++; break; 921 case VexRegUpdAllregsAtEachInsn: 922 n_PX_VexRegUpdAllregsAtEachInsn++; break; 923 default: 924 vg_assert(0); 925 } 926 927 return bitset; 928 } 929 930 931 /* This is a callback passed to LibVEX_Translate. It stops Vex from 932 chasing into function entry points that we wish to redirect. 933 Chasing across them obviously defeats the redirect mechanism, with 934 bad effects for Memcheck, Helgrind, DRD, Massif, and possibly others. 935 */ 936 static Bool chase_into_ok ( void* closureV, Addr addr ) 937 { 938 NSegment const* seg = VG_(am_find_nsegment)(addr); 939 940 /* Work through a list of possibilities why we might not want to 941 allow a chase. */ 942 943 /* Destination not in a plausible segment? */ 944 if (!translations_allowable_from_seg(seg, addr)) 945 goto dontchase; 946 947 /* Destination is redirected? */ 948 if (addr != VG_(redir_do_lookup)(addr, NULL)) 949 goto dontchase; 950 951 # if defined(VG_PLAT_USES_PPCTOC) || defined(VGP_ppc64le_linux) 952 /* This needs to be at the start of its own block. Don't chase. */ 953 if (addr == (Addr)&VG_(ppctoc_magic_redirect_return_stub)) 954 goto dontchase; 955 # endif 956 957 /* overly conservative, but .. don't chase into the distinguished 958 address that m_transtab uses as an empty-slot marker for 959 VG_(tt_fast). */ 960 if (addr == TRANSTAB_BOGUS_GUEST_ADDR) 961 goto dontchase; 962 963 # if defined(VGA_s390x) 964 /* Never chase into an EX instruction. Generating IR for EX causes 965 a round-trip through the scheduler including VG_(discard_translations). 966 And that's expensive as shown by perf/tinycc.c: 967 Chasing into EX increases the number of EX translations from 21 to 968 102666 causing a 7x runtime increase for "none" and a 3.2x runtime 969 increase for memcheck. */ 970 if (((UChar *)addr)[0] == 0x44 || /* EX */ 971 ((UChar *)addr)[0] == 0xC6) /* EXRL */ 972 goto dontchase; 973 # endif 974 975 /* well, ok then. go on and chase. */ 976 return True; 977 978 vg_assert(0); 979 /*NOTREACHED*/ 980 981 dontchase: 982 if (0) VG_(printf)("not chasing into 0x%lx\n", addr); 983 return False; 984 } 985 986 987 /* --------------- helpers for with-TOC platforms --------------- */ 988 989 /* NOTE: with-TOC platforms are: ppc64-linux. */ 990 991 static IRExpr* mkU64 ( ULong n ) { 992 return IRExpr_Const(IRConst_U64(n)); 993 } 994 static IRExpr* mkU32 ( UInt n ) { 995 return IRExpr_Const(IRConst_U32(n)); 996 } 997 998 #if defined(VG_PLAT_USES_PPCTOC) || defined(VGP_ppc64le_linux) 999 static IRExpr* mkU8 ( UChar n ) { 1000 return IRExpr_Const(IRConst_U8(n)); 1001 } 1002 static IRExpr* narrowTo32 ( IRTypeEnv* tyenv, IRExpr* e ) { 1003 if (typeOfIRExpr(tyenv, e) == Ity_I32) { 1004 return e; 1005 } else { 1006 vg_assert(typeOfIRExpr(tyenv, e) == Ity_I64); 1007 return IRExpr_Unop(Iop_64to32, e); 1008 } 1009 } 1010 1011 /* Generate code to push word-typed expression 'e' onto this thread's 1012 redir stack, checking for stack overflow and generating code to 1013 bomb out if so. */ 1014 1015 static void gen_PUSH ( IRSB* bb, IRExpr* e ) 1016 { 1017 IRRegArray* descr; 1018 IRTemp t1; 1019 IRExpr* one; 1020 1021 # if defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) 1022 Int stack_size = VEX_GUEST_PPC64_REDIR_STACK_SIZE; 1023 Int offB_REDIR_SP = offsetof(VexGuestPPC64State,guest_REDIR_SP); 1024 Int offB_REDIR_STACK = offsetof(VexGuestPPC64State,guest_REDIR_STACK); 1025 Int offB_EMNOTE = offsetof(VexGuestPPC64State,guest_EMNOTE); 1026 Int offB_CIA = offsetof(VexGuestPPC64State,guest_CIA); 1027 Bool is64 = True; 1028 IRType ty_Word = Ity_I64; 1029 IROp op_CmpNE = Iop_CmpNE64; 1030 IROp op_Sar = Iop_Sar64; 1031 IROp op_Sub = Iop_Sub64; 1032 IROp op_Add = Iop_Add64; 1033 IRExpr*(*mkU)(ULong) = mkU64; 1034 vg_assert(VG_WORDSIZE == 8); 1035 # else 1036 Int stack_size = VEX_GUEST_PPC32_REDIR_STACK_SIZE; 1037 Int offB_REDIR_SP = offsetof(VexGuestPPC32State,guest_REDIR_SP); 1038 Int offB_REDIR_STACK = offsetof(VexGuestPPC32State,guest_REDIR_STACK); 1039 Int offB_EMNOTE = offsetof(VexGuestPPC32State,guest_EMNOTE); 1040 Int offB_CIA = offsetof(VexGuestPPC32State,guest_CIA); 1041 Bool is64 = False; 1042 IRType ty_Word = Ity_I32; 1043 IROp op_CmpNE = Iop_CmpNE32; 1044 IROp op_Sar = Iop_Sar32; 1045 IROp op_Sub = Iop_Sub32; 1046 IROp op_Add = Iop_Add32; 1047 IRExpr*(*mkU)(UInt) = mkU32; 1048 vg_assert(VG_WORDSIZE == 4); 1049 # endif 1050 1051 vg_assert(sizeof(void*) == VG_WORDSIZE); 1052 vg_assert(sizeof(Word) == VG_WORDSIZE); 1053 vg_assert(sizeof(Addr) == VG_WORDSIZE); 1054 1055 descr = mkIRRegArray( offB_REDIR_STACK, ty_Word, stack_size ); 1056 t1 = newIRTemp( bb->tyenv, ty_Word ); 1057 one = mkU(1); 1058 1059 vg_assert(typeOfIRExpr(bb->tyenv, e) == ty_Word); 1060 1061 /* t1 = guest_REDIR_SP + 1 */ 1062 addStmtToIRSB( 1063 bb, 1064 IRStmt_WrTmp( 1065 t1, 1066 IRExpr_Binop(op_Add, IRExpr_Get( offB_REDIR_SP, ty_Word ), one) 1067 ) 1068 ); 1069 1070 /* Bomb out if t1 >=s stack_size, that is, (stack_size-1)-t1 <s 0. 1071 The destination (0) is a bit bogus but it doesn't matter since 1072 this is an unrecoverable error and will lead to Valgrind 1073 shutting down. _EMNOTE is set regardless - that's harmless 1074 since is only has a meaning if the exit is taken. */ 1075 addStmtToIRSB( 1076 bb, 1077 IRStmt_Put(offB_EMNOTE, mkU32(EmWarn_PPC64_redir_overflow)) 1078 ); 1079 addStmtToIRSB( 1080 bb, 1081 IRStmt_Exit( 1082 IRExpr_Binop( 1083 op_CmpNE, 1084 IRExpr_Binop( 1085 op_Sar, 1086 IRExpr_Binop(op_Sub,mkU(stack_size-1),IRExpr_RdTmp(t1)), 1087 mkU8(8 * VG_WORDSIZE - 1) 1088 ), 1089 mkU(0) 1090 ), 1091 Ijk_EmFail, 1092 is64 ? IRConst_U64(0) : IRConst_U32(0), 1093 offB_CIA 1094 ) 1095 ); 1096 1097 /* guest_REDIR_SP = t1 */ 1098 addStmtToIRSB(bb, IRStmt_Put(offB_REDIR_SP, IRExpr_RdTmp(t1))); 1099 1100 /* guest_REDIR_STACK[t1+0] = e */ 1101 /* PutI/GetI have I32-typed indexes regardless of guest word size */ 1102 addStmtToIRSB( 1103 bb, 1104 IRStmt_PutI(mkIRPutI(descr, 1105 narrowTo32(bb->tyenv,IRExpr_RdTmp(t1)), 0, e))); 1106 } 1107 1108 1109 /* Generate code to pop a word-sized value from this thread's redir 1110 stack, binding it to a new temporary, which is returned. As with 1111 gen_PUSH, an overflow check is also performed. */ 1112 1113 static IRTemp gen_POP ( IRSB* bb ) 1114 { 1115 # if defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) 1116 Int stack_size = VEX_GUEST_PPC64_REDIR_STACK_SIZE; 1117 Int offB_REDIR_SP = offsetof(VexGuestPPC64State,guest_REDIR_SP); 1118 Int offB_REDIR_STACK = offsetof(VexGuestPPC64State,guest_REDIR_STACK); 1119 Int offB_EMNOTE = offsetof(VexGuestPPC64State,guest_EMNOTE); 1120 Int offB_CIA = offsetof(VexGuestPPC64State,guest_CIA); 1121 Bool is64 = True; 1122 IRType ty_Word = Ity_I64; 1123 IROp op_CmpNE = Iop_CmpNE64; 1124 IROp op_Sar = Iop_Sar64; 1125 IROp op_Sub = Iop_Sub64; 1126 IRExpr*(*mkU)(ULong) = mkU64; 1127 # else 1128 Int stack_size = VEX_GUEST_PPC32_REDIR_STACK_SIZE; 1129 Int offB_REDIR_SP = offsetof(VexGuestPPC32State,guest_REDIR_SP); 1130 Int offB_REDIR_STACK = offsetof(VexGuestPPC32State,guest_REDIR_STACK); 1131 Int offB_EMNOTE = offsetof(VexGuestPPC32State,guest_EMNOTE); 1132 Int offB_CIA = offsetof(VexGuestPPC32State,guest_CIA); 1133 Bool is64 = False; 1134 IRType ty_Word = Ity_I32; 1135 IROp op_CmpNE = Iop_CmpNE32; 1136 IROp op_Sar = Iop_Sar32; 1137 IROp op_Sub = Iop_Sub32; 1138 IRExpr*(*mkU)(UInt) = mkU32; 1139 # endif 1140 1141 IRRegArray* descr = mkIRRegArray( offB_REDIR_STACK, ty_Word, stack_size ); 1142 IRTemp t1 = newIRTemp( bb->tyenv, ty_Word ); 1143 IRTemp res = newIRTemp( bb->tyenv, ty_Word ); 1144 IRExpr* one = mkU(1); 1145 1146 vg_assert(sizeof(void*) == VG_WORDSIZE); 1147 vg_assert(sizeof(Word) == VG_WORDSIZE); 1148 vg_assert(sizeof(Addr) == VG_WORDSIZE); 1149 1150 /* t1 = guest_REDIR_SP */ 1151 addStmtToIRSB( 1152 bb, 1153 IRStmt_WrTmp( t1, IRExpr_Get( offB_REDIR_SP, ty_Word ) ) 1154 ); 1155 1156 /* Bomb out if t1 < 0. Same comments as gen_PUSH apply. */ 1157 addStmtToIRSB( 1158 bb, 1159 IRStmt_Put(offB_EMNOTE, mkU32(EmWarn_PPC64_redir_underflow)) 1160 ); 1161 addStmtToIRSB( 1162 bb, 1163 IRStmt_Exit( 1164 IRExpr_Binop( 1165 op_CmpNE, 1166 IRExpr_Binop( 1167 op_Sar, 1168 IRExpr_RdTmp(t1), 1169 mkU8(8 * VG_WORDSIZE - 1) 1170 ), 1171 mkU(0) 1172 ), 1173 Ijk_EmFail, 1174 is64 ? IRConst_U64(0) : IRConst_U32(0), 1175 offB_CIA 1176 ) 1177 ); 1178 1179 /* res = guest_REDIR_STACK[t1+0] */ 1180 /* PutI/GetI have I32-typed indexes regardless of guest word size */ 1181 addStmtToIRSB( 1182 bb, 1183 IRStmt_WrTmp( 1184 res, 1185 IRExpr_GetI(descr, narrowTo32(bb->tyenv,IRExpr_RdTmp(t1)), 0) 1186 ) 1187 ); 1188 1189 /* guest_REDIR_SP = t1-1 */ 1190 addStmtToIRSB( 1191 bb, 1192 IRStmt_Put(offB_REDIR_SP, IRExpr_Binop(op_Sub, IRExpr_RdTmp(t1), one)) 1193 ); 1194 1195 return res; 1196 } 1197 1198 #endif 1199 1200 #if defined(VG_PLAT_USES_PPCTOC) 1201 1202 /* Generate code to push LR and R2 onto this thread's redir stack, 1203 then set R2 to the new value (which is the TOC pointer to be used 1204 for the duration of the replacement function, as determined by 1205 m_debuginfo), and set LR to the magic return stub, so we get to 1206 intercept the return and restore R2 and L2 to the values saved 1207 here. */ 1208 1209 static void gen_push_and_set_LR_R2 ( IRSB* bb, Addr new_R2_value ) 1210 { 1211 # if defined(VGP_ppc64be_linux) 1212 Addr bogus_RA = (Addr)&VG_(ppctoc_magic_redirect_return_stub); 1213 Int offB_GPR2 = offsetof(VexGuestPPC64State,guest_GPR2); 1214 Int offB_LR = offsetof(VexGuestPPC64State,guest_LR); 1215 gen_PUSH( bb, IRExpr_Get(offB_LR, Ity_I64) ); 1216 gen_PUSH( bb, IRExpr_Get(offB_GPR2, Ity_I64) ); 1217 addStmtToIRSB( bb, IRStmt_Put( offB_LR, mkU64( bogus_RA )) ); 1218 addStmtToIRSB( bb, IRStmt_Put( offB_GPR2, mkU64( new_R2_value )) ); 1219 1220 # else 1221 # error Platform is not TOC-afflicted, fortunately 1222 # endif 1223 } 1224 #endif 1225 1226 #if defined(VG_PLAT_USES_PPCTOC) || defined(VGP_ppc64le_linux) 1227 1228 static void gen_pop_R2_LR_then_bLR ( IRSB* bb ) 1229 { 1230 # if defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) 1231 Int offB_GPR2 = offsetof(VexGuestPPC64State,guest_GPR2); 1232 Int offB_LR = offsetof(VexGuestPPC64State,guest_LR); 1233 Int offB_CIA = offsetof(VexGuestPPC64State,guest_CIA); 1234 IRTemp old_R2 = newIRTemp( bb->tyenv, Ity_I64 ); 1235 IRTemp old_LR = newIRTemp( bb->tyenv, Ity_I64 ); 1236 /* Restore R2 */ 1237 old_R2 = gen_POP( bb ); 1238 addStmtToIRSB( bb, IRStmt_Put( offB_GPR2, IRExpr_RdTmp(old_R2)) ); 1239 /* Restore LR */ 1240 old_LR = gen_POP( bb ); 1241 addStmtToIRSB( bb, IRStmt_Put( offB_LR, IRExpr_RdTmp(old_LR)) ); 1242 /* Branch to LR */ 1243 /* re boring, we arrived here precisely because a wrapped fn did a 1244 blr (hence Ijk_Ret); so we should just mark this jump as Boring, 1245 else one _Call will have resulted in two _Rets. */ 1246 bb->jumpkind = Ijk_Boring; 1247 bb->next = IRExpr_Binop(Iop_And64, IRExpr_RdTmp(old_LR), mkU64(~(3ULL))); 1248 bb->offsIP = offB_CIA; 1249 # else 1250 # error Platform is not TOC-afflicted, fortunately 1251 # endif 1252 } 1253 #endif 1254 1255 #if defined(VG_PLAT_USES_PPCTOC) || defined(VGP_ppc64le_linux) 1256 1257 static 1258 Bool mk_preamble__ppctoc_magic_return_stub ( void* closureV, IRSB* bb ) 1259 { 1260 VgCallbackClosure* closure = (VgCallbackClosure*)closureV; 1261 /* Since we're creating the entire IRSB right here, give it a 1262 proper IMark, as it won't get one any other way, and cachegrind 1263 will barf if it doesn't have one (fair enough really). */ 1264 addStmtToIRSB( bb, IRStmt_IMark( closure->readdr, 4, 0 ) ); 1265 /* Generate the magic sequence: 1266 pop R2 from hidden stack 1267 pop LR from hidden stack 1268 goto LR 1269 */ 1270 gen_pop_R2_LR_then_bLR(bb); 1271 return True; /* True == this is the entire BB; don't disassemble any 1272 real insns into it - just hand it directly to 1273 optimiser/instrumenter/backend. */ 1274 } 1275 #endif 1276 1277 #if defined(VGP_ppc64le_linux) 1278 /* Generate code to push LR and R2 onto this thread's redir stack. 1279 Need to save R2 in case we redirect to a global entry point. The 1280 value of R2 is not preserved when entering the global entry point. 1281 Need to make sure R2 gets restored on return. Set LR to the magic 1282 return stub, so we get to intercept the return and restore R2 and 1283 L2 to the values saved here. 1284 1285 The existing infrastruture for the TOC enabled architectures is 1286 being exploited here. So, we need to enable a number of the 1287 code sections used by VG_PLAT_USES_PPCTOC. 1288 */ 1289 1290 static void gen_push_R2_and_set_LR ( IRSB* bb ) 1291 { 1292 Addr bogus_RA = (Addr)&VG_(ppctoc_magic_redirect_return_stub); 1293 Int offB_GPR2 = offsetof(VexGuestPPC64State,guest_GPR2); 1294 Int offB_LR = offsetof(VexGuestPPC64State,guest_LR); 1295 gen_PUSH( bb, IRExpr_Get(offB_LR, Ity_I64) ); 1296 gen_PUSH( bb, IRExpr_Get(offB_GPR2, Ity_I64) ); 1297 addStmtToIRSB( bb, IRStmt_Put( offB_LR, mkU64( bogus_RA )) ); 1298 } 1299 # endif 1300 1301 /* --------------- END helpers for with-TOC platforms --------------- */ 1302 1303 1304 /* This is the IR preamble generator used for replacement 1305 functions. It adds code to set the guest_NRADDR{_GPR2} to zero 1306 (technically not necessary, but facilitates detecting mixups in 1307 which a replacement function has been erroneously declared using 1308 VG_REPLACE_FUNCTION_Z{U,Z} when instead it should have been written 1309 using VG_WRAP_FUNCTION_Z{U,Z}). 1310 1311 On with-TOC platforms the follow hacks are also done: LR and R2 are 1312 pushed onto a hidden stack, R2 is set to the correct value for the 1313 replacement function, and LR is set to point at the magic 1314 return-stub address. Setting LR causes the return of the 1315 wrapped/redirected function to lead to our magic return stub, which 1316 restores LR and R2 from said stack and returns for real. 1317 1318 VG_(get_StackTrace_wrk) understands that the LR value may point to 1319 the return stub address, and that in that case it can get the real 1320 LR value from the hidden stack instead. */ 1321 static 1322 Bool mk_preamble__set_NRADDR_to_zero ( void* closureV, IRSB* bb ) 1323 { 1324 Int nraddr_szB 1325 = sizeof(((VexGuestArchState*)0)->guest_NRADDR); 1326 vg_assert(nraddr_szB == 4 || nraddr_szB == 8); 1327 vg_assert(nraddr_szB == VG_WORDSIZE); 1328 addStmtToIRSB( 1329 bb, 1330 IRStmt_Put( 1331 offsetof(VexGuestArchState,guest_NRADDR), 1332 nraddr_szB == 8 ? mkU64(0) : mkU32(0) 1333 ) 1334 ); 1335 // t9 needs to be set to point to the start of the redirected function. 1336 # if defined(VGP_mips32_linux) 1337 VgCallbackClosure* closure = (VgCallbackClosure*)closureV; 1338 Int offB_GPR25 = offsetof(VexGuestMIPS32State, guest_r25); 1339 addStmtToIRSB(bb, IRStmt_Put(offB_GPR25, mkU32(closure->readdr))); 1340 # endif 1341 # if defined(VGP_mips64_linux) 1342 VgCallbackClosure* closure = (VgCallbackClosure*)closureV; 1343 Int offB_GPR25 = offsetof(VexGuestMIPS64State, guest_r25); 1344 addStmtToIRSB(bb, IRStmt_Put(offB_GPR25, mkU64(closure->readdr))); 1345 # endif 1346 # if defined(VG_PLAT_USES_PPCTOC) 1347 { VgCallbackClosure* closure = (VgCallbackClosure*)closureV; 1348 addStmtToIRSB( 1349 bb, 1350 IRStmt_Put( 1351 offsetof(VexGuestArchState,guest_NRADDR_GPR2), 1352 VG_WORDSIZE==8 ? mkU64(0) : mkU32(0) 1353 ) 1354 ); 1355 gen_push_and_set_LR_R2 ( bb, VG_(get_tocptr)( closure->readdr ) ); 1356 } 1357 # endif 1358 1359 #if defined(VGP_ppc64le_linux) 1360 VgCallbackClosure* closure = (VgCallbackClosure*)closureV; 1361 Int offB_GPR12 = offsetof(VexGuestArchState, guest_GPR12); 1362 addStmtToIRSB(bb, IRStmt_Put(offB_GPR12, mkU64(closure->readdr))); 1363 addStmtToIRSB(bb, 1364 IRStmt_Put( 1365 offsetof(VexGuestArchState,guest_NRADDR_GPR2), 1366 VG_WORDSIZE==8 ? mkU64(0) : mkU32(0) 1367 ) 1368 ); 1369 gen_push_R2_and_set_LR ( bb ); 1370 #endif 1371 return False; 1372 } 1373 1374 /* Ditto, except set guest_NRADDR to nraddr (the un-redirected guest 1375 address). This is needed for function wrapping - so the wrapper 1376 can read _NRADDR and find the address of the function being 1377 wrapped. On toc-afflicted platforms we must also snarf r2. */ 1378 static 1379 Bool mk_preamble__set_NRADDR_to_nraddr ( void* closureV, IRSB* bb ) 1380 { 1381 VgCallbackClosure* closure = (VgCallbackClosure*)closureV; 1382 Int nraddr_szB 1383 = sizeof(((VexGuestArchState*)0)->guest_NRADDR); 1384 vg_assert(nraddr_szB == 4 || nraddr_szB == 8); 1385 vg_assert(nraddr_szB == VG_WORDSIZE); 1386 addStmtToIRSB( 1387 bb, 1388 IRStmt_Put( 1389 offsetof(VexGuestArchState,guest_NRADDR), 1390 nraddr_szB == 8 1391 ? IRExpr_Const(IRConst_U64( closure->nraddr )) 1392 : IRExpr_Const(IRConst_U32( (UInt)closure->nraddr )) 1393 ) 1394 ); 1395 // t9 needs to be set to point to the start of the redirected function. 1396 # if defined(VGP_mips32_linux) 1397 Int offB_GPR25 = offsetof(VexGuestMIPS32State, guest_r25); 1398 addStmtToIRSB(bb, IRStmt_Put(offB_GPR25, mkU32(closure->readdr))); 1399 # endif 1400 # if defined(VGP_mips64_linux) 1401 Int offB_GPR25 = offsetof(VexGuestMIPS64State, guest_r25); 1402 addStmtToIRSB(bb, IRStmt_Put(offB_GPR25, mkU64(closure->readdr))); 1403 # endif 1404 # if defined(VG_PLAT_USES_PPCTOC) 1405 addStmtToIRSB( 1406 bb, 1407 IRStmt_Put( 1408 offsetof(VexGuestArchState,guest_NRADDR_GPR2), 1409 IRExpr_Get(offsetof(VexGuestArchState,guest_GPR2), 1410 VG_WORDSIZE==8 ? Ity_I64 : Ity_I32) 1411 ) 1412 ); 1413 gen_push_and_set_LR_R2 ( bb, VG_(get_tocptr)( closure->readdr ) ); 1414 # endif 1415 #if defined(VGP_ppc64le_linux) 1416 /* This saves the r2 before leaving the function. We need to move 1417 * guest_NRADDR_GPR2 back to R2 on return. 1418 */ 1419 Int offB_GPR12 = offsetof(VexGuestArchState, guest_GPR12); 1420 addStmtToIRSB( 1421 bb, 1422 IRStmt_Put( 1423 offsetof(VexGuestArchState,guest_NRADDR_GPR2), 1424 IRExpr_Get(offsetof(VexGuestArchState,guest_GPR2), 1425 VG_WORDSIZE==8 ? Ity_I64 : Ity_I32) 1426 ) 1427 ); 1428 addStmtToIRSB(bb, IRStmt_Put(offB_GPR12, mkU64(closure->readdr))); 1429 gen_push_R2_and_set_LR ( bb ); 1430 #endif 1431 return False; 1432 } 1433 1434 /* --- Helpers to do with PPC related stack redzones. --- */ 1435 1436 __attribute__((unused)) 1437 static Bool const_True ( Addr guest_addr ) 1438 { 1439 return True; 1440 } 1441 1442 /* --------------- main translation function --------------- */ 1443 1444 /* Note: see comments at top of m_redir.c for the Big Picture on how 1445 redirections are managed. */ 1446 1447 typedef 1448 enum { 1449 /* normal translation, redir neither requested nor inhibited */ 1450 T_Normal, 1451 /* redir translation, function-wrap (set _NRADDR) style */ 1452 T_Redir_Wrap, 1453 /* redir translation, replacement (don't set _NRADDR) style */ 1454 T_Redir_Replace, 1455 /* a translation in which redir is specifically disallowed */ 1456 T_NoRedir 1457 } 1458 T_Kind; 1459 1460 /* Translate the basic block beginning at NRADDR, and add it to the 1461 translation cache & translation table. Unless 1462 DEBUGGING_TRANSLATION is true, in which case the call is being done 1463 for debugging purposes, so (a) throw away the translation once it 1464 is made, and (b) produce a load of debugging output. If 1465 ALLOW_REDIRECTION is False, do not attempt redirection of NRADDR, 1466 and also, put the resulting translation into the no-redirect tt/tc 1467 instead of the normal one. 1468 1469 TID is the identity of the thread requesting this translation. 1470 */ 1471 1472 Bool VG_(translate) ( ThreadId tid, 1473 Addr nraddr, 1474 Bool debugging_translation, 1475 Int debugging_verbosity, 1476 ULong bbs_done, 1477 Bool allow_redirection ) 1478 { 1479 Addr addr; 1480 T_Kind kind; 1481 Int tmpbuf_used, verbosity, i; 1482 Bool (*preamble_fn)(void*,IRSB*); 1483 VexArch vex_arch; 1484 VexArchInfo vex_archinfo; 1485 VexAbiInfo vex_abiinfo; 1486 VexGuestExtents vge; 1487 VexTranslateArgs vta; 1488 VexTranslateResult tres; 1489 VgCallbackClosure closure; 1490 1491 /* Make sure Vex is initialised right. */ 1492 1493 static Bool vex_init_done = False; 1494 1495 if (!vex_init_done) { 1496 LibVEX_Init ( &failure_exit, &log_bytes, 1497 1, /* debug_paranoia */ 1498 &VG_(clo_vex_control) ); 1499 vex_init_done = True; 1500 } 1501 1502 /* Establish the translation kind and actual guest address to 1503 start from. Sets (addr,kind). */ 1504 if (allow_redirection) { 1505 Bool isWrap; 1506 Addr tmp = VG_(redir_do_lookup)( nraddr, &isWrap ); 1507 if (tmp == nraddr) { 1508 /* no redirection found */ 1509 addr = nraddr; 1510 kind = T_Normal; 1511 } else { 1512 /* found a redirect */ 1513 addr = tmp; 1514 kind = isWrap ? T_Redir_Wrap : T_Redir_Replace; 1515 } 1516 } else { 1517 addr = nraddr; 1518 kind = T_NoRedir; 1519 } 1520 1521 /* Established: (nraddr, addr, kind) */ 1522 1523 /* Printing redirection info. */ 1524 1525 if ((kind == T_Redir_Wrap || kind == T_Redir_Replace) 1526 && (VG_(clo_verbosity) >= 2 || VG_(clo_trace_redir))) { 1527 Bool ok; 1528 const HChar *buf; 1529 const HChar *name2; 1530 1531 /* Try also to get the soname (not the filename) of the "from" 1532 object. This makes it much easier to debug redirection 1533 problems. */ 1534 const HChar* nraddr_soname = "???"; 1535 DebugInfo* nraddr_di = VG_(find_DebugInfo)(nraddr); 1536 if (nraddr_di) { 1537 const HChar* t = VG_(DebugInfo_get_soname)(nraddr_di); 1538 if (t) 1539 nraddr_soname = t; 1540 } 1541 1542 ok = VG_(get_fnname_w_offset)(nraddr, &buf); 1543 if (!ok) buf = "???"; 1544 // Stash away name1 1545 HChar name1[VG_(strlen)(buf) + 1]; 1546 VG_(strcpy)(name1, buf); 1547 ok = VG_(get_fnname_w_offset)(addr, &name2); 1548 if (!ok) name2 = "???"; 1549 1550 VG_(message)(Vg_DebugMsg, 1551 "REDIR: 0x%lx (%s:%s) redirected to 0x%lx (%s)\n", 1552 nraddr, nraddr_soname, name1, 1553 addr, name2 ); 1554 } 1555 1556 if (!debugging_translation) 1557 VG_TRACK( pre_mem_read, Vg_CoreTranslate, 1558 tid, "(translator)", addr, 1 ); 1559 1560 /* If doing any code printing, print a basic block start marker */ 1561 if (VG_(clo_trace_flags) || debugging_translation) { 1562 const HChar* objname = "UNKNOWN_OBJECT"; 1563 OffT objoff = 0; 1564 DebugInfo* di = VG_(find_DebugInfo)( addr ); 1565 if (di) { 1566 objname = VG_(DebugInfo_get_filename)(di); 1567 objoff = addr - VG_(DebugInfo_get_text_bias)(di); 1568 } 1569 vg_assert(objname); 1570 1571 const HChar *fnname; 1572 Bool ok = VG_(get_fnname_w_offset)(addr, &fnname); 1573 if (!ok) fnname = "UNKNOWN_FUNCTION"; 1574 VG_(printf)( 1575 "==== SB %u (evchecks %llu) [tid %u] 0x%lx %s %s%c0x%lx\n", 1576 VG_(get_bbs_translated)(), bbs_done, tid, addr, 1577 fnname, objname, objoff >= 0 ? '+' : '-', 1578 (UWord)(objoff >= 0 ? objoff : -objoff) 1579 ); 1580 } 1581 1582 /* Are we allowed to translate here? */ 1583 1584 { /* BEGIN new scope specially for 'seg' */ 1585 NSegment const* seg = VG_(am_find_nsegment)(addr); 1586 1587 if ( (!translations_allowable_from_seg(seg, addr)) 1588 || addr == TRANSTAB_BOGUS_GUEST_ADDR ) { 1589 if (VG_(clo_trace_signals)) 1590 VG_(message)(Vg_DebugMsg, "translations not allowed here (0x%lx)" 1591 " - throwing SEGV\n", addr); 1592 /* U R busted, sonny. Place your hands on your head and step 1593 away from the orig_addr. */ 1594 /* Code address is bad - deliver a signal instead */ 1595 if (seg != NULL) { 1596 /* There's some kind of segment at the requested place, but we 1597 aren't allowed to execute code here. */ 1598 if (debugging_translation) 1599 VG_(printf)("translations not allowed here (segment not executable)" 1600 "(0x%lx)\n", addr); 1601 else 1602 VG_(synth_fault_perms)(tid, addr); 1603 } else { 1604 /* There is no segment at all; we are attempting to execute in 1605 the middle of nowhere. */ 1606 if (debugging_translation) 1607 VG_(printf)("translations not allowed here (no segment)" 1608 "(0x%lx)\n", addr); 1609 else 1610 VG_(synth_fault_mapping)(tid, addr); 1611 } 1612 return False; 1613 } 1614 1615 /* True if a debug trans., or if bit N set in VG_(clo_trace_codegen). */ 1616 verbosity = 0; 1617 if (debugging_translation) { 1618 verbosity = debugging_verbosity; 1619 } 1620 else 1621 if ( (VG_(clo_trace_flags) > 0 1622 && VG_(get_bbs_translated)() <= VG_(clo_trace_notabove) 1623 && VG_(get_bbs_translated)() >= VG_(clo_trace_notbelow) )) { 1624 verbosity = VG_(clo_trace_flags); 1625 } 1626 1627 /* Figure out which preamble-mangling callback to send. */ 1628 preamble_fn = NULL; 1629 if (kind == T_Redir_Replace) 1630 preamble_fn = mk_preamble__set_NRADDR_to_zero; 1631 else 1632 if (kind == T_Redir_Wrap) 1633 preamble_fn = mk_preamble__set_NRADDR_to_nraddr; 1634 1635 /* LE we setup the LR */ 1636 # if defined(VG_PLAT_USES_PPCTOC) || defined(VGP_ppc64le_linux) 1637 if (nraddr == (Addr)&VG_(ppctoc_magic_redirect_return_stub)) { 1638 /* If entering the special return stub, this means a wrapped or 1639 redirected function is returning. Make this translation one 1640 which restores R2 and LR from the thread's hidden redir 1641 stack, and branch to the (restored) link register, thereby 1642 really causing the function to return. */ 1643 vg_assert(kind == T_Normal); 1644 vg_assert(nraddr == addr); 1645 preamble_fn = mk_preamble__ppctoc_magic_return_stub; 1646 } 1647 # endif 1648 1649 /* ------ Actually do the translation. ------ */ 1650 vg_assert2(VG_(tdict).tool_instrument, 1651 "you forgot to set VgToolInterface function 'tool_instrument'"); 1652 1653 /* Get the CPU info established at startup. */ 1654 VG_(machine_get_VexArchInfo)( &vex_arch, &vex_archinfo ); 1655 1656 /* Set up 'abiinfo' structure with stuff Vex needs to know about 1657 the guest and host ABIs. */ 1658 1659 LibVEX_default_VexAbiInfo( &vex_abiinfo ); 1660 vex_abiinfo.guest_stack_redzone_size = VG_STACK_REDZONE_SZB; 1661 1662 # if defined(VGP_amd64_linux) 1663 vex_abiinfo.guest_amd64_assume_fs_is_const = True; 1664 vex_abiinfo.guest_amd64_assume_gs_is_const = True; 1665 # endif 1666 # if defined(VGP_amd64_darwin) 1667 vex_abiinfo.guest_amd64_assume_gs_is_const = True; 1668 # endif 1669 # if defined(VGP_ppc32_linux) 1670 vex_abiinfo.guest_ppc_zap_RZ_at_blr = False; 1671 vex_abiinfo.guest_ppc_zap_RZ_at_bl = NULL; 1672 # endif 1673 # if defined(VGP_ppc64be_linux) 1674 vex_abiinfo.guest_ppc_zap_RZ_at_blr = True; 1675 vex_abiinfo.guest_ppc_zap_RZ_at_bl = const_True; 1676 vex_abiinfo.host_ppc_calls_use_fndescrs = True; 1677 # endif 1678 # if defined(VGP_ppc64le_linux) 1679 vex_abiinfo.guest_ppc_zap_RZ_at_blr = True; 1680 vex_abiinfo.guest_ppc_zap_RZ_at_bl = const_True; 1681 vex_abiinfo.host_ppc_calls_use_fndescrs = False; 1682 # endif 1683 # if defined(VGP_amd64_solaris) 1684 vex_abiinfo.guest_amd64_assume_fs_is_const = True; 1685 # endif 1686 1687 /* Set up closure args. */ 1688 closure.tid = tid; 1689 closure.nraddr = nraddr; 1690 closure.readdr = addr; 1691 1692 /* Set up args for LibVEX_Translate. */ 1693 vta.arch_guest = vex_arch; 1694 vta.archinfo_guest = vex_archinfo; 1695 vta.arch_host = vex_arch; 1696 vta.archinfo_host = vex_archinfo; 1697 vta.abiinfo_both = vex_abiinfo; 1698 vta.callback_opaque = (void*)&closure; 1699 vta.guest_bytes = (UChar*)addr; 1700 vta.guest_bytes_addr = addr; 1701 vta.chase_into_ok = chase_into_ok; 1702 vta.guest_extents = &vge; 1703 vta.host_bytes = tmpbuf; 1704 vta.host_bytes_size = N_TMPBUF; 1705 vta.host_bytes_used = &tmpbuf_used; 1706 { /* At this point we have to reconcile Vex's view of the 1707 instrumentation callback - which takes a void* first argument 1708 - with Valgrind's view, in which the first arg is a 1709 VgCallbackClosure*. Hence the following longwinded casts. 1710 They are entirely legal but longwinded so as to maximise the 1711 chance of the C typechecker picking up any type snafus. */ 1712 IRSB*(*f)(VgCallbackClosure*, 1713 IRSB*,const VexGuestLayout*,const VexGuestExtents*, 1714 const VexArchInfo*,IRType,IRType) 1715 = VG_(clo_vgdb) != Vg_VgdbNo 1716 ? tool_instrument_then_gdbserver_if_needed 1717 : VG_(tdict).tool_instrument; 1718 IRSB*(*g)(void*, 1719 IRSB*,const VexGuestLayout*,const VexGuestExtents*, 1720 const VexArchInfo*,IRType,IRType) = (__typeof__(g)) f; 1721 vta.instrument1 = g; 1722 } 1723 /* No need for type kludgery here. */ 1724 vta.instrument2 = need_to_handle_SP_assignment() 1725 ? vg_SP_update_pass 1726 : NULL; 1727 vta.finaltidy = VG_(needs).final_IR_tidy_pass 1728 ? VG_(tdict).tool_final_IR_tidy_pass 1729 : NULL; 1730 vta.needs_self_check = needs_self_check; 1731 vta.preamble_function = preamble_fn; 1732 vta.traceflags = verbosity; 1733 vta.sigill_diag = VG_(clo_sigill_diag); 1734 vta.addProfInc = VG_(clo_profyle_sbs) && kind != T_NoRedir; 1735 1736 /* Set up the dispatch continuation-point info. If this is a 1737 no-redir translation then it cannot be chained, and the chain-me 1738 points are set to NULL to indicate that. The indir point must 1739 also be NULL, since we can't allow this translation to do an 1740 indir transfer -- that would take it back into the main 1741 translation cache too. 1742 1743 All this is because no-redir translations live outside the main 1744 translation cache (in a secondary one) and chaining them would 1745 involve more adminstrative complexity that isn't worth the 1746 hassle, because we don't expect them to get used often. So 1747 don't bother. */ 1748 if (allow_redirection) { 1749 vta.disp_cp_chain_me_to_slowEP 1750 = VG_(fnptr_to_fnentry)( &VG_(disp_cp_chain_me_to_slowEP) ); 1751 vta.disp_cp_chain_me_to_fastEP 1752 = VG_(fnptr_to_fnentry)( &VG_(disp_cp_chain_me_to_fastEP) ); 1753 vta.disp_cp_xindir 1754 = VG_(fnptr_to_fnentry)( &VG_(disp_cp_xindir) ); 1755 } else { 1756 vta.disp_cp_chain_me_to_slowEP = NULL; 1757 vta.disp_cp_chain_me_to_fastEP = NULL; 1758 vta.disp_cp_xindir = NULL; 1759 } 1760 /* This doesn't involve chaining and so is always allowable. */ 1761 vta.disp_cp_xassisted 1762 = VG_(fnptr_to_fnentry)( &VG_(disp_cp_xassisted) ); 1763 1764 /* Sheesh. Finally, actually _do_ the translation! */ 1765 tres = LibVEX_Translate ( &vta ); 1766 1767 vg_assert(tres.status == VexTransOK); 1768 vg_assert(tres.n_sc_extents >= 0 && tres.n_sc_extents <= 3); 1769 vg_assert(tmpbuf_used <= N_TMPBUF); 1770 vg_assert(tmpbuf_used > 0); 1771 } /* END new scope specially for 'seg' */ 1772 1773 /* Tell aspacem of all segments that have had translations taken 1774 from them. */ 1775 for (i = 0; i < vge.n_used; i++) { 1776 VG_(am_set_segment_hasT)( vge.base[i] ); 1777 } 1778 1779 /* Copy data at trans_addr into the translation cache. */ 1780 vg_assert(tmpbuf_used > 0 && tmpbuf_used < 65536); 1781 1782 // If debugging, don't do anything with the translated block; we 1783 // only did this for the debugging output produced along the way. 1784 if (!debugging_translation) { 1785 1786 if (kind != T_NoRedir) { 1787 // Put it into the normal TT/TC structures. This is the 1788 // normal case. 1789 1790 // Note that we use nraddr (the non-redirected address), not 1791 // addr, which might have been changed by the redirection 1792 VG_(add_to_transtab)( &vge, 1793 nraddr, 1794 (Addr)(&tmpbuf[0]), 1795 tmpbuf_used, 1796 tres.n_sc_extents > 0, 1797 tres.offs_profInc, 1798 tres.n_guest_instrs ); 1799 } else { 1800 vg_assert(tres.offs_profInc == -1); /* -1 == unset */ 1801 VG_(add_to_unredir_transtab)( &vge, 1802 nraddr, 1803 (Addr)(&tmpbuf[0]), 1804 tmpbuf_used ); 1805 } 1806 } 1807 1808 return True; 1809 } 1810 1811 /*--------------------------------------------------------------------*/ 1812 /*--- end ---*/ 1813 /*--------------------------------------------------------------------*/ 1814