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

📄 toir.c

📁 The Valgrind distribution has multiple tools. The most popular is the memory checking tool (called M
💻 C
📖 第 1 页 / 共 5 页
字号:
/*--------------------------------------------------------------------*//*---                                                              ---*//*--- This file (guest-ppc/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-2006 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.*//* TODO 18/Nov/05:   Spot rld... cases which are simply left/right shifts and emit   Shl64/Shr64 accordingly.   Altivec   - datastream insns   - lvxl,stvxl: load/store with 'least recently used' hint   - vexptefp, vlogefp   LIMITATIONS:   Various, including:   - Some invalid forms of lswi and lswx are accepted when they should     not be.   - Floating Point:     - All exceptions disabled in FPSCR     - condition codes not set in FPSCR   - Altivec floating point:     - vmaddfp, vnmsubfp       Because we're using Java/IEEE mode (FPSCR[NJ]), rather than the       system default of Non-Java mode, we get some small errors       (lowest bit only).       This is because Non-Java mode brutally hacks denormalised results       to zero, whereas we keep maximum accuracy.  However, using       Non-Java mode would give us more inaccuracy, as our intermediate       results would then be zeroed, too.   - 64-bit mode: AbiHints for the stack red zone are only emitted for       unconditional calls and returns (bl, blr).  They should also be       emitted for conditional calls and returns, but we don't have a        way to express that right now.  Ah well.*//* "Special" instructions.   This instruction decoder can decode four special instructions   which mean nothing natively (are no-ops as far as regs/mem are   concerned) but have meaning for supporting Valgrind.  A special   instruction is flagged by a 16-byte preamble:      32-bit mode: 54001800 54006800 5400E800 54009800                   (rlwinm 0,0,3,0,0; rlwinm 0,0,13,0,0;                     rlwinm 0,0,29,0,0; rlwinm 0,0,19,0,0)      64-bit mode: 78001800 78006800 7800E802 78009802                   (rotldi 0,0,3; rotldi 0,0,13;                    rotldi 0,0,61; rotldi 0,0,51)   Following that, one of the following 3 are allowed   (standard interpretation in parentheses):      7C210B78 (or 1,1,1)   %R3 = client_request ( %R4 )      7C421378 (or 2,2,2)   %R3 = guest_NRADDR      7C631B78 (or 3,3,3)   branch-and-link-to-noredir %R11      7C842378 (or 4,4,4)   %R3 = guest_NRADDR_GPR2 (64-bit mode only)   Any other bytes following the 16-byte preamble are illegal and   constitute a failure in instruction decoding.  This all assumes   that the preamble will never occur except in specific code   fragments designed for Valgrind to catch.*//* Translates PPC32/64 code to IR. *//* References#define PPC32   "PowerPC Microprocessor Family:    The Programming Environments Manual for 32-Bit Microprocessors"    02/21/2000    http://www-3.ibm.com/chips/techlib/techlib.nsf/techdocs/852569B20050FF778525699600719DF2#define PPC64   "PowerPC Microprocessor Family:    Programming Environments Manual for 64-Bit Microprocessors"    06/10/2003   http://www-3.ibm.com/chips/techlib/techlib.nsf/techdocs/F7E732FF811F783187256FDD004D3797#define AV   "PowerPC Microprocessor Family:    AltiVec(TM) Technology Programming Environments Manual"    07/10/2003   http://www-3.ibm.com/chips/techlib/techlib.nsf/techdocs/FBFA164F824370F987256D6A006F424D*/#include "libvex_basictypes.h"#include "libvex_ir.h"#include "libvex.h"#include "libvex_guest_ppc32.h"#include "libvex_guest_ppc64.h"#include "main/vex_util.h"#include "main/vex_globals.h"#include "guest-generic/bb_to_IR.h"#include "guest-ppc/gdefs.h"/*------------------------------------------------------------*//*--- Globals                                              ---*//*------------------------------------------------------------*//* These are set at the start of the translation of an insn, right   down in disInstr_PPC, so that we don't have to pass them around   endlessly.  They are all constant during the translation of any   given insn. *//* We need to know this to do sub-register accesses correctly. */static Bool host_is_bigendian;/* Pointer to the guest code area. */static UChar* guest_code;/* The guest address corresponding to guest_code[0]. */static Addr64 guest_CIA_bbstart;/* The guest address for the instruction currently being   translated. */static Addr64 guest_CIA_curr_instr;/* The IRBB* into which we're generating code. */static IRBB* irbb;/* Is our guest binary 32 or 64bit?  Set at each call to   disInstr_PPC below. */static Bool mode64 = False;// Given a pointer to a function as obtained by "& functionname" in C,// produce a pointer to the actual entry point for the function.  For// most platforms it's the identity function.  Unfortunately, on// ppc64-linux it isn't (sigh).static void* fnptr_to_fnentry( void* f ){#if defined(__powerpc64__)   /* f is a pointer to a 3-word function descriptor, of which      the first word is the entry address. */   ULong* fdescr = (ULong*)f;   return (void*)(fdescr[0]);#else   return f;#endif}/*------------------------------------------------------------*//*--- 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 ppc32/64 guest state ---*//*------------------------------------------------------------*/#define offsetofPPCGuestState(_x) \   (mode64 ? offsetof(VexGuestPPC64State, _x) : \             offsetof(VexGuestPPC32State, _x))#define OFFB_CIA        offsetofPPCGuestState(guest_CIA)#define OFFB_LR         offsetofPPCGuestState(guest_LR)#define OFFB_CTR        offsetofPPCGuestState(guest_CTR)#define OFFB_XER_SO     offsetofPPCGuestState(guest_XER_SO)#define OFFB_XER_OV     offsetofPPCGuestState(guest_XER_OV)#define OFFB_XER_CA     offsetofPPCGuestState(guest_XER_CA)#define OFFB_XER_BC     offsetofPPCGuestState(guest_XER_BC)#define OFFB_FPROUND    offsetofPPCGuestState(guest_FPROUND)#define OFFB_VRSAVE     offsetofPPCGuestState(guest_VRSAVE)#define OFFB_VSCR       offsetofPPCGuestState(guest_VSCR)#define OFFB_EMWARN     offsetofPPCGuestState(guest_EMWARN)#define OFFB_TISTART    offsetofPPCGuestState(guest_TISTART)#define OFFB_TILEN      offsetofPPCGuestState(guest_TILEN)#define OFFB_RESVN      offsetofPPCGuestState(guest_RESVN)#define OFFB_NRADDR     offsetofPPCGuestState(guest_NRADDR)/* This only exists in the 64-bit guest state */#define OFFB64_NRADDR_GPR2 \                        offsetof(VexGuestPPC64State,guest_NRADDR_GPR2)/*------------------------------------------------------------*//*--- Extract instruction fields                          --- *//*------------------------------------------------------------*//* Extract field from insn, given idx (zero = lsb) and field length */#define IFIELD( insn, idx, len ) ((insn >> idx) & ((1<<len)-1))/* Extract primary opcode, instr[31:26] */static UChar ifieldOPC( UInt instr ) {   return toUChar( IFIELD( instr, 26, 6 ) );}/* Extract 10-bit secondary opcode, instr[10:1] */static UInt ifieldOPClo10 ( UInt instr) {   return IFIELD( instr, 1, 10 );}/* Extract 9-bit secondary opcode, instr[9:1] */static UInt ifieldOPClo9 ( UInt instr) {   return IFIELD( instr, 1, 9 );}/* Extract 5-bit secondary opcode, instr[5:1] */static UInt ifieldOPClo5 ( UInt instr) {   return IFIELD( instr, 1, 5 );}/* Extract RD (destination register) field, instr[25:21] */static UChar ifieldRegDS( UInt instr ) {   return toUChar( IFIELD( instr, 21, 5 ) );}/* Extract RA (1st source register) field, instr[20:16] */static UChar ifieldRegA ( UInt instr ) {   return toUChar( IFIELD( instr, 16, 5 ) );}/* Extract RB (2nd source register) field, instr[15:11] */static UChar ifieldRegB ( UInt instr ) {   return toUChar( IFIELD( instr, 11, 5 ) );}/* Extract RC (3rd source register) field, instr[10:6] */static UChar ifieldRegC ( UInt instr ) {   return toUChar( IFIELD( instr, 6, 5 ) );}/* Extract 2nd lowest bit, instr[1] */static UChar ifieldBIT10 ( UInt instr ) {   return toUChar( IFIELD( instr, 10, 1 ) );}/* Extract 2nd lowest bit, instr[1] */static UChar ifieldBIT1 ( UInt instr ) {   return toUChar( IFIELD( instr, 1, 1 ) );}/* Extract lowest bit, instr[0] */static UChar ifieldBIT0 ( UInt instr ) {   return toUChar( instr & 0x1 );}/* Extract unsigned bottom half, instr[15:0] */static UInt ifieldUIMM16 ( UInt instr ) {   return instr & 0xFFFF;}/* Extract unsigned bottom 26 bits, instr[25:0] */static UInt ifieldUIMM26 ( UInt instr ) {   return instr & 0x3FFFFFF;}/*------------------------------------------------------------*//*--- Guest-state identifiers                              ---*//*------------------------------------------------------------*/typedef enum {    PPC_GST_CIA,    // Current Instruction Address    PPC_GST_LR,     // Link Register    PPC_GST_CTR,    // Count Register    PPC_GST_XER,    // Overflow, carry flags, byte count    PPC_GST_CR,     // Condition Register    PPC_GST_FPSCR,  // Floating Point Status/Control Register    PPC_GST_VRSAVE, // Vector Save/Restore Register    PPC_GST_VSCR,   // Vector Status and Control Register    PPC_GST_EMWARN, // Emulation warnings    PPC_GST_TISTART,// For icbi: start of area to invalidate    PPC_GST_TILEN,  // For icbi: length of area to invalidate    PPC_GST_RESVN,  // For lwarx/stwcx.    PPC_GST_MAX} PPC_GST;#define MASK_FPSCR_RN   0x3#define MASK_VSCR_VALID 0x00010001/*------------------------------------------------------------*//*---  FP Helpers                                          ---*//*------------------------------------------------------------*//* Produce the 32-bit pattern corresponding to the supplied   float. */static UInt float_to_bits ( Float f ){   union { UInt i; Float f; } u;   vassert(4 == sizeof(UInt));   vassert(4 == sizeof(Float));   vassert(4 == sizeof(u));   u.f = f;   return u.i;}/*------------------------------------------------------------*//*--- Misc Helpers                                         ---*//*------------------------------------------------------------*//* Generate mask with 1's from 'begin' through 'end',   wrapping if begin > end.   begin->end works from right to left, 0=lsb*/static UInt MASK32( UInt begin, UInt end ){   UInt m1, m2, mask;   vassert(begin < 32);   vassert(end < 32);   m1   = ((UInt)(-1)) << begin;   m2   = ((UInt)(-1)) << end << 1;   mask = m1 ^ m2;   if (begin > end) mask = ~mask;  // wrap mask   return mask;}/* ditto for 64bit mask */static ULong MASK64( UInt begin, UInt end ){   ULong m1, m2, mask;   vassert(begin < 64);   vassert(end < 64);   m1   = ((ULong)(-1)) << begin;   m2   = ((ULong)(-1)) << end << 1;   mask = m1 ^ m2;   if (begin > end) mask = ~mask;  // wrap mask   return mask;}static Addr64 nextInsnAddr( void ){   return guest_CIA_curr_instr + 4;}/*------------------------------------------------------------*//*--- Helper bits and pieces for deconstructing the        ---*//*--- ppc32/64 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 )

⌨️ 快捷键说明

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