📄 toir.c
字号:
/*--------------------------------------------------------------------*//*--- ---*//*--- 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 + -