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

📄 toir.c

📁 unix下调试内存泄露的工具源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*--------------------------------------------------------------------*//*---                                                              ---*//*--- This file (guest-arm/toIR.c) is                              ---*//*--- Copyright (C) OpenWorks LLP.  All rights reserved.           ---*//*---                                                              ---*//*--------------------------------------------------------------------*//*   This file is part of LibVEX, a library for dynamic binary   instrumentation and translation.   Copyright (C) 2004-2005 OpenWorks LLP.  All rights reserved.   This library is made available under a dual licensing scheme.   If you link LibVEX against other code all of which is itself   licensed under the GNU General Public License, version 2 dated June   1991 ("GPL v2"), then you may use LibVEX under the terms of the GPL   v2, as appearing in the file LICENSE.GPL.  If the file LICENSE.GPL   is missing, you can obtain a copy of the GPL v2 from the Free   Software Foundation Inc., 51 Franklin St, Fifth Floor, Boston, MA   02110-1301, USA.   For any other uses of LibVEX, you must first obtain a commercial   license from OpenWorks LLP.  Please contact info@open-works.co.uk   for information about commercial licensing.   This software is provided by OpenWorks LLP "as is" and any express   or implied warranties, including, but not limited to, the implied   warranties of merchantability and fitness for a particular purpose   are disclaimed.  In no event shall OpenWorks LLP be liable for any   direct, indirect, incidental, special, exemplary, or consequential   damages (including, but not limited to, procurement of substitute   goods or services; loss of use, data, or profits; or business   interruption) however caused and on any theory of liability,   whether in contract, strict liability, or tort (including   negligence or otherwise) arising in any way out of the use of this   software, even if advised of the possibility of such damage.   Neither the names of the U.S. Department of Energy nor the   University of California nor the names of its contributors may be   used to endorse or promote products derived from this software   without prior written permission.*//* Translates ARM(v4) code to IR. */#include "libvex_basictypes.h"#include "libvex_ir.h"#include "libvex.h"#include "libvex_guest_arm.h"#include "main/vex_util.h"#include "main/vex_globals.h"#include "guest-arm/gdefs.h"/*------------------------------------------------------------*//*--- Globals                                              ---*//*------------------------------------------------------------*//* These are set at the start of the translation of a BB, so that we   don't have to pass them around endlessly.  CONST means does not   change during translation of a bb. *//* We need to know this to do sub-register accesses correctly. *//* CONST */static Bool host_is_bigendian;/* Pointer to the guest code area. *//* CONST */static UChar* guest_code;/* The guest address corresponding to guest_code[0]. *//* CONST */static Addr32 guest_pc_bbstart;/* The IRBB* into which we're generating code. */static IRBB* irbb;/*------------------------------------------------------------*//*--- Debugging output                                     ---*//*------------------------------------------------------------*/#define DIP(format, args...)           \   if (vex_traceflags & VEX_TRACE_FE)  \      vex_printf(format, ## args)#define DIS(buf, format, args...)      \   if (vex_traceflags & VEX_TRACE_FE)  \      vex_sprintf(buf, format, ## args)/*------------------------------------------------------------*//*--- Offsets of various parts of the arm guest state.     ---*//*------------------------------------------------------------*/#define OFFB_R0       offsetof(VexGuestARMState,guest_R0)#define OFFB_R1       offsetof(VexGuestARMState,guest_R1)#define OFFB_R2       offsetof(VexGuestARMState,guest_R2)#define OFFB_R3       offsetof(VexGuestARMState,guest_R3)#define OFFB_R4       offsetof(VexGuestARMState,guest_R4)#define OFFB_R5       offsetof(VexGuestARMState,guest_R5)#define OFFB_R6       offsetof(VexGuestARMState,guest_R6)#define OFFB_R7       offsetof(VexGuestARMState,guest_R7)#define OFFB_R8       offsetof(VexGuestARMState,guest_R8)#define OFFB_R9       offsetof(VexGuestARMState,guest_R9)#define OFFB_R10      offsetof(VexGuestARMState,guest_R10)#define OFFB_R11      offsetof(VexGuestARMState,guest_R11)#define OFFB_R12      offsetof(VexGuestARMState,guest_R12)#define OFFB_R13      offsetof(VexGuestARMState,guest_R13)#define OFFB_R14      offsetof(VexGuestARMState,guest_R14)#define OFFB_R15      offsetof(VexGuestARMState,guest_R15)// CAB: ? guest_SYSCALLNO;#define OFFB_CC_OP    offsetof(VexGuestARMState,guest_CC_OP)#define OFFB_CC_DEP1  offsetof(VexGuestARMState,guest_CC_DEP1)#define OFFB_CC_DEP2  offsetof(VexGuestARMState,guest_CC_DEP2)// CAB: ? guest_EMWARN;/*------------------------------------------------------------*//*--- Disassemble an entire basic block                    ---*//*------------------------------------------------------------*//* The results of disassembling an instruction.  There are three   possible outcomes.  For Dis_Resteer, the disassembler _must_   continue at the specified address.  For Dis_StopHere, the   disassembler _must_ terminate the BB.  For Dis_Continue, we may at   our option either disassemble the next insn, or terminate the BB;   but in the latter case we must set the bb's ->next field to point   to the next instruction.  */typedef   enum {       Dis_StopHere, /* this insn terminates the BB; we must stop. */      Dis_Continue, /* we can optionally continue into the next insn */      Dis_Resteer   /* followed a branch; continue at the spec'd addr */   }   DisResult;/* forward decls .. */static IRExpr* mkU32 ( UInt i );static void stmt ( IRStmt* st );/* disInstr disassembles an instruction located at &guest_code[delta],   and sets *size to its size.  If the returned value is Dis_Resteer,   the next guest address is assigned to *whereNext.  disInstr is not   permitted to return Dis_Resteer if either (1) resteerOK is False,   or (2) resteerOkFn, when applied to the address which it wishes to   resteer into, returns False.  */   static DisResult disInstr ( /*IN*/  Bool    resteerOK,                            /*IN*/  Bool    (*resteerOkFn) ( Addr64 ),                            /*IN*/  Long    delta,                             /*OUT*/ Int*    size,                            /*OUT*/ Addr64* whereNext );/* This is the main (only, in fact) entry point for this module. *//* Disassemble a complete basic block, starting at guest_pc_start, and   dumping the IR into global irbb.  Returns the size, in bytes, of   the basic block.  */IRBB* bbToIR_ARM ( UChar*           armCode,                    Addr64           guest_pc_start,                    VexGuestExtents* vge,                   Bool             (*byte_accessible)(Addr64),                   Bool             (*chase_into_ok)(Addr64),                   Bool             host_bigendian,                   VexArchInfo*     archinfo_guest ){   Long       delta;   Int        i, n_instrs, size, first_stmt_idx;   Addr64     guest_next;   Bool       resteerOK;   DisResult  dres;   static Int n_resteers = 0;   Int        d_resteers = 0;   /* check sanity .. */   vassert(vex_control.guest_max_insns >= 1);   vassert(vex_control.guest_max_insns < 500);   vassert(vex_control.guest_chase_thresh >= 0);   vassert(vex_control.guest_chase_thresh < vex_control.guest_max_insns);   vassert(archinfo_guest->subarch == VexSubArchARM_v4);   /* Start a new, empty extent. */   vge->n_used  = 1;   vge->base[0] = guest_pc_start;   vge->len[0]  = 0;   /* Set up globals. */   host_is_bigendian = host_bigendian;   guest_code        = armCode;   guest_pc_bbstart  = (Addr32)guest_pc_start;   irbb              = emptyIRBB();   vassert((guest_pc_start >> 32) == 0);   /* Delta keeps track of how far along the armCode array we      have so far gone. */   delta             = 0;   n_instrs          = 0;   while (True) {      vassert(n_instrs < vex_control.guest_max_insns);      guest_next = 0;      resteerOK = toBool(n_instrs < vex_control.guest_chase_thresh);      first_stmt_idx = irbb->stmts_used;      if (n_instrs > 0) {         /* for the first insn, the dispatch loop will have set            R15, but for all the others we have to do it ourselves. */         stmt( IRStmt_Put( OFFB_R15, mkU32(toUInt(guest_pc_bbstart + delta))) );      }      dres = disInstr( resteerOK, chase_into_ok,                        delta, &size, &guest_next );      /* 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 (dres == Dis_StopHere) {         vassert(irbb->next != NULL);         if (vex_traceflags & VEX_TRACE_FE) {            vex_printf("              ");            vex_printf( "goto {");            ppIRJumpKind(irbb->jumpkind);            vex_printf( "} ");            ppIRExpr( irbb->next );            vex_printf( "\n");         }      }      delta += size;      vge->len[vge->n_used-1] = toUShort(vge->len[vge->n_used-1] + size);      n_instrs++;      DIP("\n");      vassert(size > 0 && size <= 18);      if (!resteerOK)          vassert(dres != Dis_Resteer);      if (dres != Dis_Resteer)          vassert(guest_next == 0);      switch (dres) {      case Dis_Continue:         vassert(irbb->next == NULL);         if (n_instrs < vex_control.guest_max_insns) {            /* keep going */         } else {            irbb->next = mkU32(toUInt(guest_pc_start+delta));            return irbb;         }         break;      case Dis_StopHere:         vassert(irbb->next != NULL);         return irbb;      case Dis_Resteer:         vpanic("bbToIR_ARM: Dis_Resteer: fixme");         /* need to add code here to start a new extent ... */         vassert(irbb->next == NULL);         /* figure out a new delta to continue at. */         vassert(chase_into_ok(guest_next));         delta = guest_next - guest_pc_start;         n_resteers++;         d_resteers++;         if (0 && (n_resteers & 0xFF) == 0)            vex_printf("resteer[%d,%d] to %p (delta = %lld)\n",                       n_resteers, d_resteers,                       ULong_to_Ptr(guest_next), delta);         break;      }   }}/*------------------------------------------------------------*//*--- Helper bits and pieces for deconstructing the        ---*//*--- ARM insn stream.                                     ---*//*------------------------------------------------------------*//* Add a statement to the list held by "irbb". */static void stmt ( IRStmt* st ){   addStmtToIRBB( irbb, st );}/* Generate a new temporary of the given type. */static IRTemp newTemp ( IRType ty ){   vassert(isPlausibleIRType(ty));   return newIRTemp( irbb->tyenv, ty );}#if 0/* Bomb out if we can't handle something. */__attribute__ ((noreturn))static void unimplemented ( Char* str ){   vex_printf("armToIR: unimplemented feature\n");   vpanic(str);}#endif/* Various simple conversions */#if 0static UInt extend_s_8to32( UInt x ){   return (UInt)((((Int)x) << 24) >> 24);}static UInt extend_s_16to32 ( UInt x ){   return (UInt)((((Int)x) << 16) >> 16);}#endifstatic UInt extend_s_24to32 ( UInt x ){   return (UInt)((((Int)x) << 8) >> 8);}#if 0/* Fetch a byte from the guest insn stream. */static UChar getIByte ( UInt delta ){   return guest_code[delta];}#endif/* Get a 8/16/32-bit unsigned value out of the insn stream. */#if 0static UInt getUChar ( UInt delta ){   UInt v = guest_code[delta+0];   return v & 0xFF;}#endif#if 0static UInt getUDisp16 ( UInt delta ){   UInt v = guest_code[delta+1]; v <<= 8;   v |= guest_code[delta+0];   return v & 0xFFFF;}#endif#if 0static UInt getUDisp32 ( UInt delta ){   UInt v = guest_code[delta+3]; v <<= 8;   v |= guest_code[delta+2]; v <<= 8;   v |= guest_code[delta+1]; v <<= 8;   v |= guest_code[delta+0];   return v;}#endif#if 0static UInt getUDisp ( Int size, UInt delta ){   switch (size) {   case 4: return getUDisp32(delta);   case 2: return getUDisp16(delta);   case 1: return getUChar(delta);   default: vpanic("getUDisp(ARM)");   }   return 0; /*notreached*/}#endif#if 0/* Get a byte value out of the insn stream and sign-extend to 32   bits. */static UInt getSDisp8 ( UInt delta ){   return extend_s_8to32( (UInt) (guest_code[delta]) );}#endif#if 0static UInt getSDisp16 ( UInt delta0 ){   UChar* eip = (UChar*)(&guest_code[delta0]);   UInt d = *eip++;   d |= ((*eip++) << 8);   return extend_s_16to32(d);}#endif#if 0static UInt getSDisp ( Int size, UInt delta )

⌨️ 快捷键说明

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