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

📄 toir.c

📁 unix下调试内存泄露的工具源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
  ARM ARM A5-18*/staticBool dis_loadstore_w_ub ( UInt theInstr ){   UInt   flags   =         (theInstr >> 20) & 0x3F;  // theInstr[25:20]   UChar  Rn_addr = toUChar((theInstr >> 16) & 0xF);   UChar  Rd_addr = toUChar((theInstr >> 12) & 0xF);   IRTemp address = newTemp(Ity_I32);     UChar L  = toUChar((flags >> 0) & 1); // Load(1) | Store(0)   UChar W  = toUChar((flags >> 1) & 1); // base register writeback   UChar B  = toUChar((flags >> 2) & 1); // access = unsigned byte(1) | word(0)      IRTemp value      = newTemp(Ity_I32);   IRTemp data       = newTemp(Ity_I32);   IRTemp data_ror8  = newTemp(Ity_I32);   IRTemp data_ror16 = newTemp(Ity_I32);   IRTemp data_ror24 = newTemp(Ity_I32);   IRExpr* expr_addr_10;   HChar* cond_name = name_ARMCondcode( (theInstr >> 28) & 0xF );   HChar dis_buf[50];         vassert(((theInstr >> 26) & 0x3) == 0x1);      // Get the address to load/store   if (!dis_loadstore_w_ub_address(theInstr, &address, dis_buf)) { return False; }      DIP("%s%s%s R%d, %s\n", (L==1) ? "ldr" : "str", cond_name,       (B==1) ? "b" : "", Rd_addr, dis_buf);      if (Rd_addr == Rn_addr && W==1) {  // Unpredictable - ARM ARM A4-39,41,89,91      vex_printf("dis_loadstore_w_ub(arm): Unpredictable - Rd_addr==Rn_addr\n");      return False;   }      /*     LOAD/STORE Rd, address   */   if (L==1) { // LOAD      if (B==1) {  // unsigned byte (LDRB): ARM ARM A4-40         if (Rd_addr == 15) {  // Unpredictable - ARM ARM A4-40            vex_printf("dis_loadstore_w_ub(arm): Unpredictable - Rd_addr==15\n");            return False;         }         putIReg( Rd_addr, loadLE( Ity_I8, mkexpr( address ) ) );      }      else {       // word (LDR): ARM ARM A4-38         expr_addr_10 = binop(Iop_And32, mkexpr(address), mkU32(0x3));                  /*           CAB TODO           if (Rd_addr == 15 && address[1:0] == 0) => Unpredictable           How to bomb out using IR?         */                  /* LOAD memory data (4 bytes) */         assign( data, loadLE( Ity_I32, mkexpr( address ) ) );                  // data ROR 8         assign( data_ror8, binop(Iop_Sub8, mkU8(32), mkU32(8)) );          assign( data_ror8,                 binop( Iop_Or32,                        binop( Iop_Shr32, mkexpr(data), mkU8(8) ),                        binop( Iop_Shl32, mkexpr(data), mkexpr(data_ror8) )));         // data ROR 16         assign( data_ror16, binop(Iop_Sub8, mkU8(32), mkU32(16)) );         assign( data_ror16,                 binop( Iop_Or32,                        binop( Iop_Shr32, mkexpr(data), mkU8(16) ),                        binop( Iop_Shl32, mkexpr(data), mkexpr(data_ror16) )));                  // data ROR 24         assign( data_ror24, binop(Iop_Sub8, mkU8(32), mkU32(24)) );         assign( data_ror24,                 binop( Iop_Or32,                        binop( Iop_Shr32, mkexpr(data), mkU8(24) ),                        binop( Iop_Shl32, mkexpr(data), mkexpr(data_ror24) )));                  /* switch (address[1:0]) {            0x0: value = data;            0x1: value = data ROR 8;            0x2: value = data ROR 16;            0x3: value = data ROR 24; } */         assign( value, IRExpr_Mux0X(                    binop(Iop_CmpEQ32, expr_addr_10, mkU32(0x0)),                    IRExpr_Mux0X(                       binop(Iop_CmpEQ32, expr_addr_10, mkU32(0x1)),                       IRExpr_Mux0X(                          binop(Iop_CmpEQ32, expr_addr_10, mkU32(0x2)),                          mkexpr(data_ror24),                          mkexpr(data_ror16) ),                       mkexpr(data_ror8) ),                    mkexpr(data) ) );                  if (Rd_addr == 15) {            // assuming architecture < 5: See ARM ARM A4-28            putIReg( Rd_addr, binop(Iop_And32, mkexpr(value), mkU32(0xFFFFFFFC)) );                        // CAB: Need to tell vex we're doing a jump here?            // irbb->jumpkind = Ijk_Boring;            // irbb->next     = mkexpr(value);         } else {            putIReg( Rd_addr, mkexpr(value) );         }               }   } else { // STORE: ARM ARM A4-88      if (B==1) {  // unsigned byte         if (Rd_addr == 15) {  // Unpredictable - ARM ARM A4-90            vex_printf("dis_loadstore_w_ub(arm): Unpredictable - Rd_addr==15\n");            return False;         }         storeLE( mkexpr(address), unop(Iop_32to8, getIReg(Rd_addr)) );   // Rd[7:0]      } else {     // word                  if (Rd_addr == 15) {  // Implementation Defined - ARM ARM A4-88            vex_printf("dis_loadstore_w_ub(arm): Implementation Defined - Rd_addr==15\n");            return False;            // CAB TODO: What to do here?         }         storeLE( mkexpr(address), getIReg(Rd_addr) );      }   }   return True;}/*  ARMG_CC_OP_LSL, ARMG_CC_OP_LSR, ARMG_CC_OP_ASR  ARM ARM A5-9...  carry = carry_out[0]*/staticIRExpr* dis_shift( Bool* decode_ok, UInt theInstr, IRTemp* carry_out, HChar* buf ){   UChar   Rn_addr     = toUChar((theInstr >> 16) & 0xF);   UChar   Rd_addr     = toUChar((theInstr >> 12) & 0xF);   UChar   Rs_addr     = toUChar((theInstr >>  8) & 0xF);   UChar   Rm_addr     = toUChar((theInstr >>  0) & 0xF);   UChar   by_reg      = toUChar((theInstr >>  4) & 0x1);  // instr[4]   UChar   shift_imm   = toUChar((theInstr >>  7) & 0x1F); // instr[11:7]   UChar   shift_op    = toUChar((theInstr >>  4) & 0xF);  // instr[7:4]   IRTemp  Rm          = newTemp(Ity_I32);   IRTemp  Rs          = newTemp(Ity_I32);   IRTemp  shift_amt   = newTemp(Ity_I8);   IRTemp  carry_shift = newTemp(Ity_I8);   IRTemp  oldFlagC    = newTemp(Ity_I32);   IRTemp  mux_false   = newTemp(Ity_I32);   IRExpr* expr;   IROp    op;      assign( oldFlagC, binop(Iop_Shr32,                           mk_armg_calculate_flags_c(),                           mkU8(ARMG_CC_SHIFT_C)) );      switch (shift_op) {   case 0x0: case 0x8: case 0x1: op = Iop_Shl32; break;   case 0x2: case 0xA: case 0x3: op = Iop_Shr32; break;   case 0x4: case 0xC: case 0x5: op = Iop_Sar32; break;   default:      vex_printf("dis_shift(arm): No such case: 0x%x\n", shift_op);      *decode_ok = False;      return mkU32(0);   }         if (by_reg) {  // Register Shift      assign( Rm, getIReg(Rm_addr) );            if (Rd_addr == 15 || Rm_addr == 15 ||          Rn_addr == 15 || Rs_addr == 15) {   // Unpredictable (ARM ARM A5-10)         vex_printf("dis_shift(arm): Unpredictable - Rd|Rm|Rn|Rs == R15\n");         *decode_ok = False;         return mkU32(0);      }            assign( Rs, getIReg((theInstr >> 8) & 0xF) );  // instr[11:8]            // shift_amt = shift_expr & 31   => Rs[5:0]      assign( shift_amt,              narrowTo(Ity_I8, binop( Iop_And32, mkexpr(Rs), mkU32(0x1F)) ) );            // CAB TODO: support for >31 shift ?  (Rs[7:0])            switch (shift_op) {      case 0x1: // LSL(reg)         assign( mux_false, mkU32(0) );         assign( carry_shift, binop(Iop_Add8, mkU8(32), mkexpr(shift_amt)) );         break;               case 0x3: // LSR(reg)         assign( mux_false, mkU32(0) );         assign( carry_shift, binop(Iop_Sub8, mkexpr(shift_amt), mkU8(1)) );         break;               case 0x5: // ASR(reg)         // Rs[31] == 0 ? 0x0 : 0xFFFFFFFF         assign( mux_false,                 IRExpr_Mux0X(                    binop(Iop_CmpLT32U, mkexpr(Rs), mkU32(0x80000000)),                    mkU32(0xFFFFFFFF), mkU32(0) ) );         assign( carry_shift,                 binop(Iop_Sub8, mkexpr(shift_amt), mkU8(1)) );         break;               default:         vex_printf("dis_shift(arm): Reg shift: No such case: 0x%x\n", shift_op);         *decode_ok = False;         return mkU32(0);      }            expr = IRExpr_Mux0X(          binop(Iop_CmpLT32U, widenUto32(mkexpr(shift_amt)), mkU32(32)),         mkexpr(mux_false),         binop(op, mkexpr(Rm), mkexpr(shift_amt)) );            // shift_amt == 0 ? old_flag_c : Rm >> x      assign( *carry_out,              IRExpr_Mux0X(                 binop(Iop_CmpEQ8, mkexpr(shift_amt), mkU8(0)),                 binop(Iop_Shr32, mkexpr(Rm), mkexpr(carry_shift)),                 mkexpr(oldFlagC) ) );            DIS(buf, "R%d, %s R%d", Rm_addr, name_ARMShiftOp(shift_op, 0), Rs_addr);   }   else {  // Immediate shift            // CAB: This right?      // "the value used is the address of the current intruction plus 8"      if (Rm_addr == 15 || Rn_addr == 15) {        // ARM ARM A5-9         assign( Rm, binop(Iop_Add32, getIReg(15), mkU32(8)) );      } else {         assign( Rm, getIReg(Rm_addr) );      }            if (shift_imm == 0) {         switch (shift_op) {         case 0x0: case 0x8: // LSL(imm)            expr = mkexpr(Rm);            assign( *carry_out, mkexpr(oldFlagC) );            break;                     case 0x2: case 0xA: // LSR(imm)            expr = mkexpr(0);            // Rm >> 31: carry = R[0]            assign( *carry_out, binop(Iop_Shr32, mkexpr(Rm), mkU8(31)) );            break;                     case 0x4: case 0xC: // ASR(imm)            // Rs[31] == 0 ? 0x0 : 0xFFFFFFFF            expr = IRExpr_Mux0X(               binop(Iop_CmpLT32U, mkexpr(Rs), mkU32(0x80000000)),               mkU32(0xFFFFFFFF), mkU32(0) );            // Rm >> 31: carry = R[0]            assign( *carry_out, binop(Iop_Shr32, mkexpr(Rm), mkU8(31)) );            break;                     default:            vex_printf("dis_shift(arm): Imm shift: No such case: 0x%x\n", shift_op);            *decode_ok = False;            return mkU32(0);         }         DIS(buf, "R%d", Rm_addr);      } else {         expr = binop(op, mkexpr(Rm), mkU8(shift_imm));         assign( *carry_out, binop(op, mkexpr(Rm),                                   binop(Iop_Sub32, mkU32(shift_imm), mkU32(1)) ) );         DIS(buf, "R%d, %s #%d", Rm_addr, name_ARMShiftOp(shift_op, 0), shift_imm);      }   }   return expr;}/*  ARMG_CC_OP_ROR  ARM ARM A5-15,16,17*/staticIRExpr* dis_rotate ( Bool* decode_ok, UInt theInstr, IRTemp* carry_out, HChar* buf ){   UChar  Rn_addr  = toUChar((theInstr >> 16) & 0xF);   UChar  Rd_addr  = toUChar((theInstr >> 12) & 0xF);   UChar  Rs_addr  = toUChar((theInstr >> 8) & 0xF);   UChar  Rm_addr  = toUChar((theInstr >> 0) & 0xF);   UChar  by_reg   = toUChar((theInstr >> 4) & 0x1);  // instr[4]   UChar  rot_imm  = toUChar((theInstr >> 7) & 0x1F); // instr[11:7]   IRTemp Rm       = newTemp(Ity_I32);   IRTemp Rs       = newTemp(Ity_I32);   IRTemp rot_amt  = newTemp(Ity_I8);      // Rs[7:0]   IRTemp oldFlagC = newTemp(Ity_I32);   IRExpr* expr=0;      assign( oldFlagC, binop(Iop_Shr32,                           mk_armg_calculate_flags_c(),                           mkU8(ARMG_CC_SHIFT_C)) );      if (by_reg) {  // Register rotate      assign( Rm, getIReg(Rm_addr) );            if (Rd_addr == 15 || Rm_addr == 15 ||          Rn_addr == 15 || Rs_addr == 15) {    // Unpredictable (ARM ARM A5-10)         vex_printf("dis_rotate(arm): Unpredictable - Rd|Rm|Rn|Rs == R15\n");         *decode_ok = False;         return mkU32(0);      }            assign( Rs, getIReg((theInstr >> 8) & 0xF) );  // instr[11:8]      // Rs[4:0]      assign( rot_amt, narrowTo(Ity_I8,                                binop(Iop_And32, mkexpr(Rs), mkU32(0x1F))) );            // CAB: This right?      // Rs[7:0] == 0 ? oldFlagC : (Rs[4:0] == 0 ? Rm >> 31 : Rm >> rot-1 )      assign( *carry_out,              IRExpr_Mux0X(                 binop(Iop_CmpNE32, mkU32(0),                       binop(Iop_And32, mkexpr(Rs), mkU32(0xFF))),                 mkexpr(oldFlagC),                 IRExpr_Mux0X(                    binop(Iop_CmpEQ8, mkexpr(rot_amt), mkU8(0)),                    binop(Iop_Shr32, mkexpr(Rm),                          binop(Iop_Sub8, mkexpr(rot_amt), mkU8(1))),                    binop(Iop_Shr32, mkexpr(Rm),                          binop(Iop_Shr32, mkexpr(Rm), mkU8(31))) ) ) );                  /* expr = (dst0 >> rot_amt) | (dst0 << (wordsize-rot_amt)) */      expr = binop(Iop_Or32,                   binop(Iop_Shr32, mkexpr(Rm), mkexpr(rot_amt)),                   binop(Iop_Shl32, mkexpr(Rm),                         binop(Iop_Sub8, mkU8(32), mkexpr(rot_amt))));      DIS(buf, "R%d, ror R%d", Rm_addr, Rs_addr);   }   else {  // Immediate rotate      // CAB: This right?      // "the value used is the address of the current intruction plus 8"      if (Rm_addr == 15 || Rn_addr == 15) {        // ARM ARM A5-9         assign( Rm, binop(Iop_Add32, getIReg(15), mkU32(8)) );      } else {         assign( Rm, getIReg(Rm_addr) );      }            // Rm >> rot-1: carry = R[0]      assign( *carry_out, binop(Iop_Shr32, mkexpr(Rm),                                binop(Iop_Sub8, mkU8(rot_imm), mkU8(1)) ) );            if (rot_imm == 0) {   // RRX (ARM ARM A5-17)         // 33 bit ROR using carry flag as the 33rd bit         // op = Rm >> 1, carry flag replacing vacated bit position.                    // CAB: This right?         expr = binop(Iop_Or32,                      binop(Iop_Shl32, mkexpr(oldFlagC), mkU8(31)),                      binop(Iop_Shr32, mkexpr(Rm), mkU8(1)));         DIS(buf, "R%d, rrx", Rm_addr);      } else {         expr = binop(Iop_Or32,                      binop(Iop_Shr32, mkexpr(Rm), mkU8(rot_imm)),                      binop(Iop_Shl32, mkexpr(Rm),                            binop(Iop_Sub8, mkU8(32), mkU8(rot_imm))));                  DIS(buf, "R%d, ror #%u", Rm_addr, (UInt)rot_imm);      }   }   return expr;}/*  CAB TODO:   - Not all shifts by 0 leave c_flag unchanged, so guard_expr is more difficult...  assign( flags_guard, binop( Iop_CmpEQ32, mkexpr(shift_amt), mkU32(0) ) );  setFlags_DEP1_DEP2_shift( ARMG_CC_OP_LSL, Rm, shift_op, flags_guard );*//* Addressing mode 1 - Data Processing ops   General syntax: <opcode>{<cond>}{S} <Rd>, <Rn>, <shifter_operand>   Returns <shifter_operand> expression*/staticIRExpr* dis_shifter_op ( Bool *decode_ok, UInt theInstr, IRTemp* carry_out, HChar* buf ){   UChar is_immed  = toUChar((theInstr >> 25) & 1);  // immediate / register shift   UChar shift_op  = toUChar((theInstr >> 4) & 0xF); // second byte   UInt immed_8, rot_imm;   UInt imm;   IRTemp oldFlagC = newTemp(Ity_I32);      if (is_immed) {  // ARM ARM A5-2      // dst = src ROR rot << 1      //     = (src >> rot) | (src << (32-rot));      immed_8 = theInstr & 0xFF;      rot_imm = ((theInstr >> 8) & 0xF) << 1;        imm = (immed_8 >> rot_imm) | (immed_8 << (32-rot_imm));            if (rot_imm == 0) {         assign( oldFlagC, binop(Iop_Shr32,

⌨️ 快捷键说明

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