⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bb_to_ir.c

📁 The Valgrind distribution has multiple tools. The most popular is the memory checking tool (called M
💻 C
📖 第 1 页 / 共 2 页
字号:
      /* Finally, actually disassemble an instruction. */      dres = dis_instr_fn ( irbb,                            need_to_put_IP,                            resteerOKfn,                            callback_opaque,                            guest_code,                            delta,                            guest_IP_curr_instr,                            arch_guest,                            archinfo_guest,                            host_bigendian );      /* stay sane ... */      vassert(dres.whatNext == Dis_StopHere              || dres.whatNext == Dis_Continue              || dres.whatNext == Dis_Resteer);      vassert(dres.len >= 0 && dres.len <= 20);      if (dres.whatNext != Dis_Resteer)         vassert(dres.continueAt == 0);      /* Fill in the insn-mark length field. */      vassert(first_stmt_idx >= 0 && first_stmt_idx < irbb->stmts_used);      imark = irbb->stmts[first_stmt_idx];      vassert(imark);      vassert(imark->tag == Ist_IMark);      vassert(imark->Ist.IMark.len == 0);      imark->Ist.IMark.len = toUInt(dres.len);      /* Print the resulting IR, if needed. */      if (vex_traceflags & VEX_TRACE_FE) {         for (i = first_stmt_idx; i < irbb->stmts_used; i++) {            vex_printf("              ");            ppIRStmt(irbb->stmts[i]);            vex_printf("\n");         }      }      /* If dis_instr_fn terminated the BB at this point, check it	 also filled in the irbb->next field. */      if (dres.whatNext == Dis_StopHere) {         vassert(irbb->next != NULL);         if (debug_print) {            vex_printf("              ");            vex_printf( "goto {");            ppIRJumpKind(irbb->jumpkind);            vex_printf( "} ");            ppIRExpr( irbb->next );            vex_printf( "\n");         }      }      /* Update the VexGuestExtents we are constructing. */      /* If vex_control.guest_max_insns is required to be < 100 and	 each insn is at max 20 bytes long, this limit of 5000 then	 seems reasonable since the max possible extent length will be	 100 * 20 == 2000. */      vassert(vge->len[vge->n_used-1] < 5000);      vge->len[vge->n_used-1]          = toUShort(toUInt( vge->len[vge->n_used-1] + dres.len ));      n_instrs++;      if (debug_print)          vex_printf("\n");      /* Advance delta (inconspicuous but very important :-) */      delta += (Long)dres.len;      switch (dres.whatNext) {         case Dis_Continue:            vassert(irbb->next == NULL);            if (n_instrs < vex_control.guest_max_insns) {               /* keep going */            } else {               /* We have to stop. */               irbb->next                   = IRExpr_Const(                       guest_word_type == Ity_I32                          ? IRConst_U32(toUInt(guest_IP_bbstart+delta))                          : IRConst_U64(guest_IP_bbstart+delta)                    );               goto done;            }            break;         case Dis_StopHere:            vassert(irbb->next != NULL);            goto done;         case Dis_Resteer:            /* Check that we actually allowed a resteer .. */            vassert(resteerOK);            vassert(irbb->next == NULL);            /* figure out a new delta to continue at. */            vassert(resteerOKfn(callback_opaque,dres.continueAt));            delta = dres.continueAt - guest_IP_bbstart;            /* we now have to start a new extent slot. */            vge->n_used++;            vassert(vge->n_used <= 3);            vge->base[vge->n_used-1] = dres.continueAt;            vge->len[vge->n_used-1] = 0;            n_resteers++;            d_resteers++;            if (0 && (n_resteers & 0xFF) == 0)            vex_printf("resteer[%d,%d] to 0x%llx (delta = %lld)\n",                       n_resteers, d_resteers,                       dres.continueAt, delta);            break;         default:            vpanic("bb_to_IR");      }   }   /*NOTREACHED*/   vassert(0);  done:   /* We're done.  The only thing that might need attending to is that      a self-checking preamble may need to be created. */   if (do_self_check) {      UInt     len2check, adler32;      IRTemp   tistart_tmp, tilen_tmp;      vassert(vge->n_used == 1);      len2check = vge->len[0];      if (len2check == 0)          len2check = 1;     adler32 = genericg_compute_adler32( (HWord)guest_code, len2check );     /* Set TISTART and TILEN.  These will describe to the despatcher        the area of guest code to invalidate should we exit with a        self-check failure. */     tistart_tmp = newIRTemp(irbb->tyenv, guest_word_type);     tilen_tmp   = newIRTemp(irbb->tyenv, guest_word_type);     irbb->stmts[selfcheck_idx+0]        = IRStmt_Tmp(tistart_tmp, IRExpr_Const(guest_IP_bbstart_IRConst) );     irbb->stmts[selfcheck_idx+1]        = IRStmt_Tmp(tilen_tmp,                     guest_word_type==Ity_I32                         ? IRExpr_Const(IRConst_U32(len2check))                         : IRExpr_Const(IRConst_U64(len2check))          );     irbb->stmts[selfcheck_idx+2]        = IRStmt_Put( offB_TISTART, IRExpr_Tmp(tistart_tmp) );     irbb->stmts[selfcheck_idx+3]        = IRStmt_Put( offB_TILEN, IRExpr_Tmp(tilen_tmp) );     irbb->stmts[selfcheck_idx+4]        = IRStmt_Exit(              IRExpr_Binop(                 Iop_CmpNE32,                 mkIRExprCCall(                    Ity_I32,                    2/*regparms*/,                    "genericg_compute_adler32",#if defined(__powerpc__) && defined(__powerpc64__)                   (void*)((ULong*)(&genericg_compute_adler32))[0],#else                   &genericg_compute_adler32,#endif                   mkIRExprVec_2(                       mkIRExpr_HWord( (HWord)guest_code ),                       mkIRExpr_HWord( (HWord)len2check )                   )                ),                IRExpr_Const(IRConst_U32(adler32))             ),             Ijk_TInval,             guest_IP_bbstart_IRConst          );   }   return irbb;}/*-------------------------------------------------------------  A support routine for doing self-checking translations.   -------------------------------------------------------------*//* CLEAN HELPER *//* CALLED FROM GENERATED CODE *//* Compute the Adler32 checksum of host memory at [addr   .. addr+len-1].  This presumably holds guest code.  Note this is   not a proper implementation of Adler32 in that it fails to mod the   counts with 65521 every 5552 bytes, but we really never expect to   get anywhere near that many bytes to deal with.  This fn is called   once for every use of a self-checking translation, so it needs to   be as fast as possible. */__attribute((regparm(2)))static UInt genericg_compute_adler32 ( HWord addr, HWord len ){   UInt   s1 = 1;   UInt   s2 = 0;   UChar* buf = (UChar*)addr;   while (len >= 4) {      s1 += buf[0];      s2 += s1;      s1 += buf[1];      s2 += s1;      s1 += buf[2];      s2 += s1;      s1 += buf[3];      s2 += s1;      buf += 4;      len -= 4;   }   while (len > 0) {      s1 += buf[0];      s2 += s1;      len--;      buf++;   }   return (s2 << 16) + s1;}/*--------------------------------------------------------------------*//*--- end                                 guest-generic/bb_to_IR.c ---*//*--------------------------------------------------------------------*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -