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

📄 toir.c

📁 unix下调试内存泄露的工具源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
                                 mk_armg_calculate_flags_c(),                                 mkU8(ARMG_CC_SHIFT_C)) );         assign( *carry_out, mkexpr(oldFlagC) );      } else {         assign( *carry_out, binop(Iop_Shr32, mkU32(imm), mkU8(31)) );      }      DIS(buf, "#%u", imm);      return mkU32(imm);   } else {            // We shouldn't have any 'op' with bits 4=1 and 7=1 : 1xx1      switch (shift_op) {      case 0x0: case 0x8: case 0x1:      case 0x2: case 0xA: case 0x3:       case 0x4: case 0xC: case 0x5:         return dis_shift( decode_ok, theInstr, carry_out, buf );               case 0x6: case 0xE: case 0x7:         return dis_rotate( decode_ok, theInstr, carry_out, buf );               default: // Error: Any other value shouldn't be here.         *decode_ok = False;         vex_printf("dis_shifter_op(arm): shift: No such case: 0x%x\n", shift_op);         return mkU32(0);      }   }}/* -------------- Helper for DPI's. --------------*/staticBool dis_dataproc ( UInt theInstr ){   UChar opc       = toUChar((theInstr >> 21) & 0xF);   UChar set_flags = toUChar((theInstr >> 20) & 1);   UChar Rn_addr   = toUChar((theInstr >> 16) & 0xF);   UChar Rd_addr   = toUChar((theInstr >> 12) & 0xF);   IRTemp Rn = newTemp(Ity_I32);   IRTemp Rd = newTemp(Ity_I32);   IRTemp alu_out = newTemp(Ity_I32);   IRTemp shifter_op = newTemp(Ity_I32);   IRTemp carry_out = newTemp(Ity_I32);   IROp op_set_flags = ARMG_CC_OP_LOGIC;   Bool testing_instr = False;   Bool decode_ok = True;   HChar* cond_name = name_ARMCondcode( (theInstr >> 28) & 0xF );   HChar* ch_set_flags = (set_flags == 1) ? "S" : "";   HChar dis_buf[50];      assign( shifter_op, dis_shifter_op( &decode_ok, theInstr, &carry_out, dis_buf ) );   if (!decode_ok) return False;      assign( Rd, getIReg(Rd_addr) );   assign( Rn, getIReg(Rn_addr) );         switch (opc) {   case 0x0: case 0x1: case 0x2: case 0x3: case 0x4:   case 0xC: case 0xE:      DIP("%s%s%s R%d, R%d, %s\n", name_ARMDataProcOp(opc),          cond_name, ch_set_flags, Rd_addr, Rn_addr, dis_buf);      break;   case 0x5: case 0x6: case 0x7:      // CAB: Unimplemented      break;   case 0x8: case 0x9: case 0xA: case 0xB:      DIP("%s%s R%d, %s\n", name_ARMDataProcOp(opc),          cond_name, Rn_addr, dis_buf);      break;   case 0xD: case 0xF:      DIP("%s%s%s R%d, %s\n", name_ARMDataProcOp(opc),          cond_name, ch_set_flags, Rd_addr, dis_buf);      break;   default:break;   }   switch (opc) {   case 0x0: // AND      assign( alu_out, binop(Iop_And32, getIReg(Rn_addr), mkexpr(shifter_op)) );      break;          case 0x1: // EOR      assign( alu_out, binop(Iop_Xor32, getIReg(Rn_addr), mkexpr(shifter_op)) );      break;   case 0x2: // SUB      assign( alu_out, binop( Iop_Sub32, getIReg(Rn_addr), mkexpr(shifter_op) ) );      op_set_flags = ARMG_CC_OP_SUB;      break;   case 0x3:  // RSB      assign( alu_out, binop( Iop_Sub32, mkexpr(shifter_op), getIReg(Rn_addr) ) );      op_set_flags = ARMG_CC_OP_SUB;      /* set_flags(), below, switches the args for this case */      break;   case 0x4: // ADD      assign( alu_out, binop( Iop_Add32, getIReg(Rn_addr), mkexpr(shifter_op) ) );      op_set_flags = ARMG_CC_OP_ADD;      break;   case 0x5:  // ADC  // CAB: Unimplemented   case 0x6:  // SBC  // CAB: Unimplemented   case 0x7:  // RSC  // CAB: Unimplemented      goto decode_failure;   case 0x8: // TST      vassert(set_flags==1);      assign( alu_out, binop(Iop_And32, getIReg(Rn_addr), mkexpr(shifter_op)) );      testing_instr = True;      break;         case 0x9: // TEQ      vassert(set_flags==1);      assign( alu_out, binop(Iop_Xor32, getIReg(Rn_addr), mkexpr(shifter_op)) );      testing_instr = True;      break;         case 0xA: // CMP      vassert(set_flags==1);      op_set_flags = ARMG_CC_OP_SUB;      testing_instr = True;      break;   case 0xB: // CMN      vassert(set_flags==1);      op_set_flags = ARMG_CC_OP_ADD;      testing_instr = True;      break;   case 0xC: // ORR      assign( alu_out, binop(Iop_Or32, getIReg(Rn_addr), mkexpr(shifter_op)) );      break;   case 0xD: // MOV      assign( alu_out, mkexpr(shifter_op) );      break;   case 0xE: // BIC      assign( alu_out, binop(Iop_And32, getIReg(Rn_addr),                             unop( Iop_Not32, mkexpr(shifter_op))) );      break;   case 0xF: // MVN      assign( alu_out, unop(Iop_Not32, mkexpr(shifter_op)) );      break;   default:   decode_failure:      vex_printf("dis_dataproc(arm): unhandled opcode: 0x%x\n", opc);      return False;   }   if (!testing_instr) {      if ( Rd_addr == 15) { // dest reg == PC         // CPSR = SPSR: Unpredictable in User | System mode (no SPSR!)         // Unpredictable - We're only supporting user mode...         vex_printf("dis_dataproc(arm): Unpredictable - Rd_addr==15\n");         return False;      }      putIReg( Rd_addr, mkexpr(alu_out) );   }      if (set_flags) {      if (op_set_flags == ARMG_CC_OP_LOGIC) {         setFlags_DEP1_DEP2( op_set_flags, alu_out, carry_out );      } else {         if (opc == 0x3) {            setFlags_DEP1_DEP2( op_set_flags, shifter_op, Rn );         } else {            setFlags_DEP1_DEP2( op_set_flags, Rn, shifter_op );         }      }   }   return decode_ok;}/* -------------- Helper for Branch. --------------*/staticvoid dis_branch ( UInt theInstr ){   UChar link = toUChar((theInstr >> 24) & 1);   UInt signed_immed_24 = theInstr & 0xFFFFFF;   UInt branch_offset;   IRTemp addr = newTemp(Ity_I32);   IRTemp dest = newTemp(Ity_I32);      if (link) { // LR (R14) = addr of instr after branch instr      assign( addr, binop(Iop_Add32, getIReg(15), mkU32(4)) );      putIReg( 14, mkexpr(addr) );   }      // PC = PC + (SignExtend(signed_immed_24) << 2)   branch_offset = extend_s_24to32( signed_immed_24 ) << 2;   assign( dest, binop(Iop_Add32, getIReg(15), mkU32(branch_offset)) );      irbb->jumpkind = link ? Ijk_Call : Ijk_Boring;   irbb->next     = mkexpr(dest);      // Note: Not actually writing to R15 - let the IR stuff do that.      DIP("b%s%s 0x%x\n",       link ? "l" : "",       name_ARMCondcode( (theInstr >> 28) & 0xF ),       branch_offset);}/*------------------------------------------------------------*//*--- Disassemble a single instruction                     ---*//*------------------------------------------------------------*//* Disassemble a single instruction into IR.  The instruction   is located in host memory at &guest_code[delta].   Set *size to be the size of the instruction.   If the returned value is Dis_Resteer,   the next guest address is assigned to *whereNext.  If resteerOK   is False, disInstr may not return Dis_Resteer. */   static DisResult disInstr ( /*IN*/  Bool    resteerOK,                            /*IN*/  Bool    (*resteerOkFn) ( Addr64 ),                            /*IN*/  Long    delta,                             /*OUT*/ Int*    size,                            /*OUT*/ Addr64* whereNext ){   //   IRType    ty;   //  IRTemp    addr, t1, t2;   //   Int       alen;   UChar opc1, opc2, opc_tmp; //, modrm, abyte;   ARMCondcode cond;   //  UInt      d32;   // UChar     dis_buf[50];   // Int       am_sz, d_sz;   DisResult whatNext = Dis_Continue;   UInt      theInstr;      /* At least this is simple on ARM: insns are all 4 bytes long, and      4-aligned.  So just fish the whole thing out of memory right now      and have done. */      /* We will set *size to 4 if the insn is successfully decoded.      Setting it to 0 by default makes bbToIR_ARM abort if we fail the      decode. */   *size = 0;   theInstr = *(UInt*)(&guest_code[delta]);//   vex_printf("START: 0x%x, %,b\n", theInstr, theInstr );   DIP("\t0x%x:  ", toUInt(guest_pc_bbstart+delta));   // TODO: fix the client-request stuff, else nothing will work   /* Spot the client-request magic sequence. */   // Essentially a v. unlikely sequence of noops that we can catch   {      UInt* code = (UInt*)(guest_code + delta);            /* Spot this:                                                E1A00EE0                   mov  r0, r0, ror #29         E1A001E0                   mov  r0, r0, ror #3         E1A00DE0                   mov  r0, r0, ror #27         E1A002E0                   mov  r0, r0, ror #5         E1A006E0                   mov  r0, r0, ror #13         E1A009E0                   mov  r0, r0, ror #19      */      /* I suspect these will have to be turned the other way round to         work on little-endian arm. */      if (code[0] == 0xE1A00EE0 &&          code[1] == 0xE1A001E0 &&          code[2] == 0xE1A00DE0 &&          code[3] == 0xE1A002E0 &&          code[4] == 0xE1A006E0 &&          code[5] == 0xE1A009E0) {         // uh ... I'll figure this out later.  possibly r0 = client_request(r0) */         DIP("?CAB? = client_request ( ?CAB? )\n");                  *size = 24;                  irbb->next     = mkU32(toUInt(guest_pc_bbstart+delta));         irbb->jumpkind = Ijk_ClientReq;                  whatNext = Dis_StopHere;         goto decode_success;      }   }   /*     Deal with condition first   */   cond = (theInstr >> 28) & 0xF;    /* opcode: bits 31:28 *///   vex_printf("\ndisInstr(arm): cond: 0x%x, %b\n", cond, cond );      switch (cond) {   case 0xF:   // => Illegal instruction prior to v5 (see ARM ARM A3-5)      vex_printf("disInstr(arm): illegal condition\n");      goto decode_failure;         case 0xE:   // => Unconditional: go translate the instruction      break;   default:      // => Valid condition: translate the condition test first      stmt( IRStmt_Exit( mk_armg_calculate_condition(cond),                         Ijk_Boring,                         IRConst_U32(toUInt(guest_pc_bbstart+delta+4)) ) );      //irbb->next     = mkU32(guest_pc_bbstart+delta+4);      //irbb->jumpkind = Ijk_Boring;   }      /* Primary opcode is roughly bits 27:20 (ARM ARM(v2) A3-2)      secondary opcode is bits 4:0 */   opc1 = toUChar((theInstr >> 20) & 0xFF);    /* opcode1: bits 27:20 */   opc2 = toUChar((theInstr >> 4 ) & 0xF);     /* opcode2: bits 7:4   *///   vex_printf("disInstr(arm): opcode1: 0x%2x, %,09b\n", opc1, opc1 );//   vex_printf("disInstr(arm): opcode2: 0x%02x, %,04b\n", opc2, opc2 );      switch (opc1 >> 4) { // instr[27:24]   case 0x0:   case 0x1:      /*        Multiplies, extra load/store instructions: ARM ARM A3-3      */      if ( (opc1 & 0xE0) == 0x0 && (opc2 & 0x9) == 0x9 ) {  // 000xxxxx && 1xx1         if (opc2 == 0x9) {            if ((opc1 & 0x1C) == 0x00) {  // multiply (accumulate)               goto decode_failure;            }            if ((opc1 & 0x18) == 0x08) {  // multiply (accumulate) long               goto decode_failure;            }            if ((opc1 & 0x1B) == 0x10) {  // swap/swap byte               goto decode_failure;            }         }         if ( opc2 == 0xB ) {            if ((opc1 & 0x04) == 0x00) {  // load/store 1/2word reg offset               goto decode_failure;            } else {                      // load/store 1/2word imm offset               goto decode_failure;            }         }         if ((opc2 & 0xD) == 0xD) {            if ((opc1 & 0x05) == 0x00) {  // load/store 2 words reg offset               goto decode_failure;            }            if ((opc1 & 0x05) == 0x04) {  // load/store 2 words imm offset               goto decode_failure;            }            if ((opc1 & 0x05) == 0x01) {  // load/store signed 1/2word/byte reg offset               goto decode_failure;            }            if ((opc1 & 0x05) == 0x05) {  // load/store signed 1/2word/byte imm offset               goto decode_failure;            }         }      } /* endif: Multiplies, extra load/store... */            /*          'Misc' Instructions: ARM ARM A3-4      */      if ((opc1 & 0xF9) == 0x10) {  // 0001 0xx0         opc_tmp = toUChar((opc1 >> 1) & 0x3);         switch (opc2) {         case 0x0:            if ((opc_tmp & 0x1) == 0x0) { // move stat reg -> reg               goto decode_failure;            } else {                      // move reg -> stat reg               goto decode_failure;            }                     case 0x1:            if (opc_tmp == 0x1) {       // branch/exchange instr set               goto decode_failure;            }            if (opc_tmp == 0x3) {       // count leading zeros               goto decode_failure;            }            break;                     case 0x3:     

⌨️ 快捷键说明

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