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

📄 toir.c

📁 unix下调试内存泄露的工具源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
   case ARMCondHS:  return "{hs}";  // or 'cs'   case ARMCondLO:  return "{lo}";  // or 'cc'   case ARMCondMI:  return "{mi}";   case ARMCondPL:  return "{pl}";   case ARMCondVS:  return "{vs}";   case ARMCondVC:  return "{vc}";   case ARMCondHI:  return "{hi}";   case ARMCondLS:  return "{ls}";   case ARMCondGE:  return "{ge}";   case ARMCondLT:  return "{lt}";   case ARMCondGT:  return "{gt}";   case ARMCondLE:  return "{le}";   case ARMCondAL:  return "";      // {al}: default, doesn't need specifying   case ARMCondNV:  return "{nv}";   default: vpanic("name_ARMCondcode");   }}#if 0static ARMCondcode positiveIse_ARMCondcode ( ARMCondcode  cond,                                      Bool*     needInvert ){   vassert(cond >= ARMCondEQ && cond <= ARMCondNV);   if (cond & 1) {      *needInvert = True;      return cond-1;   } else {      *needInvert = False;      return cond;   }}#endif/* Addressing Mode 1 - DP ops   Addressing Mode 2 - Load/Store word/ubyte (scaled) */static HChar* name_ARMShiftOp ( UChar shift_op, UChar imm_val ){   switch (shift_op) {   case 0x0: case 0x1: case 0x8: return "lsl";   case 0x2: case 0x3: case 0xA: return "lsr";   case 0x4: case 0x5: case 0xC: return "asr";   case 0x6:                     return (imm_val==0) ? "rrx" : "ror";   case 0x7: case 0xE:           return "ror";   default: vpanic("name_ARMShiftcode");   }}/* Addressing Mode 4 - Load/Store Multiple */static HChar* name_ARMAddrMode4 ( UChar mode ){   /* See ARM ARM A5-55 for alternative names for stack operations      ldmfa (full ascending), etc. */   switch (mode) {   case 0x0: return "da"; // Decrement after   case 0x1: return "ia"; // Increment after   case 0x2: return "db"; // Decrement before   case 0x3: return "ib"; // Increment before   default: vpanic("name_ARMAddrMode4");   }}/* Data Processing ops */static HChar* name_ARMDataProcOp ( UChar opc ){   switch (opc) {   case 0x0: return "and";   case 0x1: return "eor";   case 0x2: return "sub";   case 0x3: return "rsb";   case 0x4: return "add";   case 0x5: return "adc";   case 0x6: return "sbc";   case 0x7: return "rsc";   case 0x8: return "tst";   case 0x9: return "teq";   case 0xA: return "cmp";   case 0xB: return "cmn";   case 0xC: return "orr";   case 0xD: return "mov";   case 0xE: return "bic";   case 0xF: return "mvn";   default: vpanic("name_ARMDataProcOp");   }}/*  Addressing mode 4 - LOAD/STORE multiple, LDM|STM  ARM ARM A5-48*/staticBool dis_loadstore_mult ( UInt theInstr ){   UChar flags   = toUChar((theInstr >> 20) & 0x1F); // theInstr[24:20]   UChar Rn_addr = toUChar((theInstr >> 16) & 0xF);   IRTemp Rn = newTemp(Ity_I32);   IRTemp Rn_orig = newTemp(Ity_I32);   UInt reg_list = theInstr & 0xFFFF;  // each bit addresses a register: R15 to R0                 // Load(1) | Store(0)   UChar L  = toUChar((flags >> 0) & 1);              // (W)riteback Rn (incr(U=1) | decr(U=0) by n_bytes)   UChar W  = toUChar((flags >> 1) & 1);              // Priviledged mode flag - *** CAB TODO ***   UChar S  = toUChar((flags >> 2) & 1);                // Txfr ctl: Direction = upwards(1) | downwards(0)   UChar U  = toUChar((flags >> 3) & 1);              // Txfr ctl: Rn within(P=1) | outside(P=0) accessed mem   UChar PU = toUChar((flags >> 3) & 3);        IRTemp start_addr = newTemp(Ity_I32);   IRTemp end_addr   = newTemp(Ity_I32);   IRTemp data=0;   UInt n_bytes=0;   UInt tmp_reg = reg_list;   UInt reg_idx, offset;   Bool decode_ok = True;      HChar* cond_name = name_ARMCondcode( (theInstr >> 28) & 0xF );   HChar reg_names[70];   UInt buf_offset;      while (tmp_reg > 0) {     // Count num bits in reg_list => num_bytes      if (tmp_reg & 1) { n_bytes += 4; }      tmp_reg = tmp_reg >> 1;   }      assign( Rn, getIReg(Rn_addr) );   assign( Rn_orig, mkexpr(Rn) );      switch (PU) {  // <addressing_mode>   case 0x0:  // Decrement after  (DA)      assign( start_addr, binop( Iop_Add32, mkexpr(Rn), mkU32(n_bytes + 4) ) );      assign( end_addr,   mkexpr(Rn) );      break;         case 0x1:  // Increment after  (IA)      assign( start_addr, mkexpr(Rn) );      assign( end_addr,   binop( Iop_Add32, mkexpr(Rn), mkU32(n_bytes - 4) ) );      break;         case 0x2:  // Decrement before (DB)      assign( start_addr, binop( Iop_Sub32, mkexpr(Rn), mkU32(n_bytes) ) );      assign( end_addr,   binop( Iop_Sub32, mkexpr(Rn), mkU32(4) ) );      break;         case 0x3:  // Increment before (IB)      assign( start_addr, binop( Iop_Add32, mkexpr(Rn), mkU32(4) ) );      assign( end_addr,   binop( Iop_Add32, mkexpr(Rn), mkU32(n_bytes) ) );      break;         default:      vex_printf("dis_loadstore_mult(ARM): No such case: 0x%x", PU);      return False;    }   if (W==1) {      if (U==1) { // upwards         putIReg( Rn_addr, binop( Iop_Add32, mkexpr(Rn), mkU32(n_bytes) ) );      } else { // downwards         putIReg( Rn_addr, binop( Iop_Sub32, mkexpr(Rn), mkU32(n_bytes) ) );      }   }         /*     Loop through register list, LOAD/STORE indicated registers     Lowest numbered reg -> lowest address, so start with lowest register     reg_idx: guest register address     offset : current mem offset from start_addr   */   reg_names[0] = '\0';   buf_offset=0;   offset=0;   for (reg_idx=0; reg_idx < 16; reg_idx++) {      if (( reg_list >> reg_idx ) & 1) {  // reg_list[i] == 1?                  if (L==1) { // LOAD Ri, (start_addr + offset)                        if (Rn_addr == reg_idx && W==1) { // Undefined - ARM ARM A4-31               decode_ok=False;               break;            }                        assign( data, loadLE(Ity_I32, binop(Iop_Add32,                                                mkexpr(start_addr),                                                mkU32(offset))) );            if (reg_idx == 15) {               // assuming architecture < 5: See ARM ARM A4-31               putIReg( reg_idx, binop(Iop_And32, mkexpr(data), mkU32(0xFFFFFFFC)) );            } else {               putIReg( reg_idx, mkexpr(data) );            }         } else {    // STORE Ri, (start_addr + offset)                        // ARM ARM A4-85 (Operand restrictions)            if (reg_idx == Rn_addr && W==1) {  // Rn in reg_list && writeback               if (offset != 0) {  // Undefined - See ARM ARM A4-85                  decode_ok=False;                  break;               }               // is lowest reg in reg_list: store Rn_orig               storeLE( mkexpr(start_addr), mkexpr(Rn_orig) );            } else {               storeLE( binop(Iop_Add32, mkexpr(start_addr), mkU32(offset) ),                        getIReg(reg_idx) );            }         }         offset += 4;                  reg_names[buf_offset++] = 'R';         if (reg_idx > 9) {            reg_names[buf_offset++] = '1';            reg_names[buf_offset++] = (HChar)toUChar(38 + reg_idx);         } else {            reg_names[buf_offset++] = (HChar)toUChar(48 + reg_idx);         }         reg_names[buf_offset++] = ',';         // CAB: Eugh!  Where's strcpy?!      }   }   if (buf_offset > 0) {      reg_names[buf_offset-1] = '\0';   }   DIP("%s%s%s R%d%s, {%s}%s\n", (L==1) ? "ldm":"stm", cond_name,       name_ARMAddrMode4( PU ), Rn_addr, (W==1) ? "!" : "",       reg_names, (S==1) ? "^" : "");      // CAB TODO:   // IR assert( end_addr == (start_addr + offset) - 8 )      if (offset == 0) {   // Unpredictable - ARM ARM A5-21      vex_printf("dis_loadstore_mult(arm): Unpredictable - offset==0\n");      decode_ok = False;   }      return decode_ok;}staticBool dis_loadstore_w_ub_address ( UInt theInstr, IRTemp* address, HChar* buf ){   UChar is_reg    = toUChar((theInstr >> 25) & 0x1);                      // immediate | register offset/index   UInt  flags     =         (theInstr >> 20) & 0x3F; // theInstr[25:20]   UChar Rn_addr   = toUChar((theInstr >> 16) & 0xF);   UChar Rm_addr   = toUChar((theInstr >> 00) & 0xF);   UChar shift_op  = toUChar((theInstr >> 04) & 0xFF);   UInt  offset_12 =         (theInstr >> 00) & 0xFFF;   IRTemp Rn = newTemp(Ity_I32);   IRTemp Rm = newTemp(Ity_I32);   UChar shift_imm, shift;      UChar W = toUChar((flags >> 1) & 1); // base register writeback flag - See *Note   UChar U = toUChar((flags >> 3) & 1); // offset is added(1)|subtracted(0) from the base   UChar P = toUChar((flags >> 4) & 1); // addressing mode flag - See *Note   /* *Note      P==0: post-indexed addressing: addr -> Rn      W==0: normal mem access      W==1: unprivileged mem access      P==1: W==0: offset addressing: Rn not updated  - ARM ARM A5-20      W==1: pre-indexed addressing: addr -> Rn   */      IRTemp scaled_index = newTemp(Ity_I32);   IRTemp reg_offset = newTemp(Ity_I32);      IRTemp oldFlagC = newTemp(Ity_I32);      HChar buf2[30];   HChar buf3[20];   buf3[0] = '\0';      if (Rn_addr == 15) {      if (P==1 && W==0) { // offset addressing         // CAB: This right?         assign( Rn, binop(Iop_And32, getIReg(15), mkU32(8)) );      } else {                        // Unpredictable - ARM ARM A5-25,29...         vex_printf("dis_loadstore_w_ub_address(arm): Unpredictable - Rn_addr==15\n");         return False;      }   } else {      assign( Rn, getIReg(Rn_addr) );   }      /*     Retrieve / Calculate reg_offset   */   if (is_reg) {      if (Rm_addr == 15) {               // Unpredictable - ARM ARM A5-21         vex_printf("dis_loadstore_w_ub_address(arm): Unpredictable - Rm_addr==15\n");         return False;      }      if (P==0 || W==1) {  // pre|post-indexed addressing         if (Rm_addr == Rn_addr) {      // Unpredictable - ARM ARM A5-25            vex_printf("dis_loadstore_w_ub_address(arm): Unpredictable - Rm_addr==Rn_addr\n");            return False;         }      }      assign( Rm, getIReg(Rm_addr) );            if (shift_op == 0) {  // Register addressing         assign( reg_offset, mkexpr(Rm) );      } else {              // Scaled Register addressing         shift_imm = toUChar((shift_op >> 3) & 0x1F);         shift     = toUChar((shift_op >> 1) & 0x3);                  switch (shift) {         case 0x0: // LSL            assign( scaled_index, binop(Iop_Shl32, mkexpr(Rm), mkU8(shift_imm)) );            break;                     case 0x1: // LSR            if (shift_imm) {               assign( scaled_index, binop(Iop_Shr32, mkexpr(Rm), mkU8(shift_imm)) );            } else {               assign( scaled_index, mkU32(0) );            }            break;                     case 0x2: // ASR            if (shift_imm) {               assign( scaled_index, binop(Iop_Sar32, mkexpr(Rm), mkU32(shift_imm)) );            } else {               assign( scaled_index,     // Rm[31] ? 0xFFFFFFFF : 0x0                       IRExpr_Mux0X(binop(Iop_And32, mkexpr(Rm), mkU32(0x8FFFFFFF)),                                    mkexpr(0x0), mkexpr(0xFFFFFFFF)) );            }            break;                     case 0x3: // ROR|RRX            assign( oldFlagC, binop(Iop_Shr32,                                    mk_armg_calculate_flags_c(),                                    mkU8(ARMG_CC_SHIFT_C)) );                        if (shift_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.                 // scaled_index = (c_flag << 31) | (Rm >> 1)               assign( scaled_index, binop(Iop_Or32,                                           binop(Iop_Shl32, mkexpr(oldFlagC), mkU32(31)),                                           binop(Iop_Shr32, mkexpr(Rm),  mkU8(1))) );                           } else { // ROR               // scaled_index = Rm ROR shift_imm               //              = (Rm >> shift_imm) | (Rm << (32-shift_imm))               assign( scaled_index,                       binop(Iop_Or32,                             binop(Iop_Shr32, mkexpr(Rm), mkU8(shift_imm)),                             binop(Iop_Shl32, mkexpr(Rm),                                   binop(Iop_Sub8, mkU8(32), mkU32(shift_imm)))) );            }            break;                     default:            vex_printf("dis_loadstore_w_ub(ARM): No such case: 0x%x", shift);            return False;          }         assign( reg_offset, mkexpr(scaled_index) );                  if (shift == 0x3 && shift_imm == 0) {            DIS(buf3, ", %s", name_ARMShiftOp(toUChar(shift_op * 2), shift_imm));         } else {            DIS(buf3, ", %s #%d",                       name_ARMShiftOp(toUChar(shift_op * 2), shift_imm),                       shift_imm);         }      }      DIS(buf2, "%cR%d%s", (U==1) ? '+' : '-', Rm_addr, buf3);   } else { // immediate      assign( reg_offset, mkU32(offset_12) );            DIS(buf2, "#%c%u", (U==1) ? '+' : '-', offset_12);   }   DIS(buf, "[R%d%s, %s%s", Rn_addr,       (P==0) ? "]" : "", buf2,       (P==1) ? ((W==1) ? "]!" : "]") : "");      /*     Depending on P,U,W, write to Rn and set address to load/store   */   if (P==1) {       // offset | pre-indexed addressing      if (U == 1) { // - increment         assign( *address, binop(Iop_Add32, mkexpr(Rn), mkexpr(reg_offset)) );      } else {      // - decrement         assign( *address, binop(Iop_Sub32, mkexpr(Rn), mkexpr(reg_offset)) );      }      if (W == 1) { // pre-indexed addressing, base register writeback         putIReg( Rn_addr, mkexpr(*address) );      }   } else {          // post-indexed addressing      assign( *address, mkexpr(Rn) );      if (U == 1) { // - increment         putIReg( Rn_addr, binop( Iop_Add32, mkexpr(Rn), mkexpr(reg_offset) ) );      } else {      // - decrement         putIReg( Rn_addr, binop( Iop_Sub32, mkexpr(Rn), mkexpr(reg_offset) ) );      }   }   return True;}/*  Addressing mode 2 - LOAD/STORE word or unsigned byte

⌨️ 快捷键说明

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