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