📄 hdefs.c
字号:
/*---------------------------------------------------------------*//*--- ---*//*--- This file (host-arm/hdefs.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.*/#include "libvex_basictypes.h"#include "libvex.h"#include "libvex_trc_values.h"#include "main/vex_util.h"#include "host-generic/h_generic_regs.h"#include "host-arm/hdefs.h"/* --------- Registers. --------- *//* The usual HReg abstraction. There are 16 general purpose regs.*//* --------- Registers. --------- */void ppHRegARM ( HReg reg ) { Int r; static HChar* ireg32_names[16] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" }; /* Be generic for all virtual regs. */ if (hregIsVirtual(reg)) { ppHReg(reg); return; } /* But specific for real regs. */ switch (hregClass(reg)) { case HRcInt32: r = hregNumber(reg); vassert(r >= 0 && r < 16); vex_printf("%s", ireg32_names[r]); return; default: vpanic("ppHRegARM"); }}HReg hregARM_R0 ( void ) { return mkHReg(0, HRcInt32, False); }HReg hregARM_R1 ( void ) { return mkHReg(1, HRcInt32, False); }HReg hregARM_R2 ( void ) { return mkHReg(2, HRcInt32, False); }HReg hregARM_R3 ( void ) { return mkHReg(3, HRcInt32, False); }HReg hregARM_R4 ( void ) { return mkHReg(4, HRcInt32, False); }HReg hregARM_R5 ( void ) { return mkHReg(5, HRcInt32, False); }HReg hregARM_R6 ( void ) { return mkHReg(6, HRcInt32, False); }HReg hregARM_R7 ( void ) { return mkHReg(7, HRcInt32, False); }HReg hregARM_R8 ( void ) { return mkHReg(8, HRcInt32, False); }HReg hregARM_R9 ( void ) { return mkHReg(9, HRcInt32, False); }HReg hregARM_R10 ( void ) { return mkHReg(10, HRcInt32, False); }HReg hregARM_R11 ( void ) { return mkHReg(11, HRcInt32, False); }HReg hregARM_R12 ( void ) { return mkHReg(12, HRcInt32, False); }HReg hregARM_R13 ( void ) { return mkHReg(13, HRcInt32, False); }HReg hregARM_R14 ( void ) { return mkHReg(14, HRcInt32, False); }HReg hregARM_R15 ( void ) { return mkHReg(15, HRcInt32, False); }void getAllocableRegs_ARM ( Int* nregs, HReg** arr ) { *nregs = 20; *arr = LibVEX_Alloc(*nregs * sizeof(HReg)); (*arr)[0] = hregARM_R0(); (*arr)[1] = hregARM_R1(); (*arr)[2] = hregARM_R2(); (*arr)[3] = hregARM_R3(); (*arr)[4] = hregARM_R4(); (*arr)[5] = hregARM_R5(); (*arr)[6] = hregARM_R6(); (*arr)[7] = hregARM_R7(); (*arr)[8] = hregARM_R8(); (*arr)[9] = hregARM_R9(); (*arr)[10] = hregARM_R10(); (*arr)[11] = hregARM_R11(); (*arr)[12] = hregARM_R12(); (*arr)[13] = hregARM_R13(); (*arr)[14] = hregARM_R14(); (*arr)[15] = hregARM_R15();}/* --------- Condition codes, ARM encoding. --------- */HChar* showARMCondCode ( ARMCondCode cond ) { switch (cond) { case ARMccEQ: return "eq"; case ARMccNE: return "ne"; case ARMccHS: return "hs"; case ARMccLO: return "lo"; case ARMccMI: return "mi"; case ARMccPL: return "pl"; case ARMccVS: return "vs"; case ARMccVC: return "vc"; case ARMccHI: return "hi"; case ARMccLS: return "ls"; case ARMccGE: return "ge"; case ARMccLT: return "lt"; case ARMccGT: return "gt"; case ARMccLE: return "le"; case ARMccAL: return "al"; // default case ARMccNV: return "nv"; default: vpanic("showARMCondCode"); }}/* --------- ARMAMode1: memory address expressions. --------- */ARMAMode1* ARMAMode1_I12A ( ARMImm12A imm ) { ARMAMode1* am = LibVEX_Alloc(sizeof(ARMAMode1)); am->tag = ARMam1_I12A; am->ARMam1.I12A.imm = imm; return am;}ARMAMode1* ARMAMode1_ShlI ( HReg Rm, ARMImm5 imm ) { ARMAMode1* am = LibVEX_Alloc(sizeof(ARMAMode1)); am->tag = ARMam1_ShlI; am->ARMam1.ShlI.Rm = Rm; am->ARMam1.ShlI.imm = imm; return am;}ARMAMode1* ARMAMode1_ShrI ( HReg Rm, ARMImm5 imm ) { ARMAMode1* am = LibVEX_Alloc(sizeof(ARMAMode1)); am->tag = ARMam1_ShrI; am->ARMam1.ShrI.Rm = Rm; am->ARMam1.ShrI.imm = imm; return am;}ARMAMode1* ARMAMode1_SarI ( HReg Rm, ARMImm5 imm ) { ARMAMode1* am = LibVEX_Alloc(sizeof(ARMAMode1)); am->tag = ARMam1_SarI; am->ARMam1.SarI.Rm = Rm; am->ARMam1.SarI.imm = imm; return am;}ARMAMode1* ARMAMode1_ShlR ( HReg Rm, HReg Rs ) { ARMAMode1* am = LibVEX_Alloc(sizeof(ARMAMode1)); am->tag = ARMam1_ShlR; am->ARMam1.ShlR.Rm = Rm; am->ARMam1.ShlR.Rs = Rs; return am;}ARMAMode1* ARMAMode1_ShrR ( HReg Rm, HReg Rs ) { ARMAMode1* am = LibVEX_Alloc(sizeof(ARMAMode1)); am->tag = ARMam1_ShrR; am->ARMam1.ShrR.Rm = Rm; am->ARMam1.ShrR.Rs = Rs; return am;}ARMAMode1* ARMAMode1_SarR ( HReg Rm, HReg Rs ) { ARMAMode1* am = LibVEX_Alloc(sizeof(ARMAMode1)); am->tag = ARMam1_SarR; am->ARMam1.SarR.Rm = Rm; am->ARMam1.SarR.Rs = Rs; return am;}ARMAMode1* dopyARMAMode1 ( ARMAMode1* am ) { switch (am->tag) { case ARMam1_I12A: return ARMAMode1_I12A( am->ARMam1.I12A.imm ); case ARMam1_ShlI: return ARMAMode1_ShlI( am->ARMam1.ShlI.Rm, am->ARMam1.ShlI.imm ); case ARMam1_ShrI: return ARMAMode1_ShrI( am->ARMam1.ShrI.Rm, am->ARMam1.ShrI.imm ); case ARMam1_SarI: return ARMAMode1_SarI( am->ARMam1.SarI.Rm, am->ARMam1.SarI.imm ); case ARMam1_ShlR: return ARMAMode1_ShlR( am->ARMam1.ShlR.Rm, am->ARMam1.ShlR.Rs ); case ARMam1_ShrR: return ARMAMode1_ShrR( am->ARMam1.ShrR.Rm, am->ARMam1.ShrR.Rs ); case ARMam1_SarR: return ARMAMode1_SarR( am->ARMam1.SarR.Rm, am->ARMam1.SarR.Rs ); default: vpanic("dopyARMAMode1"); }}void ppARMAMode1 ( ARMAMode1* am ) { switch (am->tag) { case ARMam1_I12A: case ARMam1_ShlI: case ARMam1_ShrI: case ARMam1_SarI: case ARMam1_ShlR: case ARMam1_ShrR: case ARMam1_SarR: vex_printf("ppARMAMode1: Not implemented"); break; default: vpanic("ppARMAMode1"); }}/*static void addRegUsage_ARMAMode1 ( HRegUsage* u, ARMAMode1* am ) {static void mapRegs_ARMAMode1 ( HRegRemap* m, ARMAMode1* am ) {*//* ------ ARMAMode1_I12A Helper function ------ Given imm32, find immed_8, rotate_imm. ARM ARM A5-6: imm32 = immed_8 ROR (rotate_imm * 2)*/Bool mk_ARMImm12A ( UInt imm32, ARMImm12A* imm12a ) {// UInt imm32_orig = imm32; UInt shr=0, rot=0; imm12a->imm = 0; imm12a->rot = 0; // Easiest case: no shift needed if (imm32 > 0xFF) { // Next easiest: just a shift to the right needed while ((imm32 & 1) == 0) { imm32 = imm32 >> 1; shr++; } rot = 32 - shr; if (imm32 > 0xFF) { // Hardest: Need to rol (some minimum amount) // valid byte could be split over first and last bytes... // ROL 7 (worst case for still valid imm32): imm32 = (imm32 << 7) | (imm32 << (32-7)); // ShR (reverse rol) if went too far: while ((imm32 & 1) == 0) { imm32 = imm32 >> 1; shr++; } rot = 7 - shr; // if valid imm32, shr < 7 if (imm32 > 0xFF) { // Can't represent this value// vex_printf("Error: Can't represent imm32: 0x%x", imm32_orig); return False; } } } // Valid imm32 so far... if (rot & 1) { rot--; imm32 = imm32 << 1; if (imm32 > 0xFF) { // Can't represent this value (can only shift even n)// vex_printf("Error: Can't represent imm32: 0x%x\n", imm32_orig); return False; } } imm12a->imm = imm32; imm12a->rot = rot / 2; vassert((imm12a->imm & 0xFF) == imm12a->imm); vassert((imm12a->rot & 0xF ) == imm12a->rot); return True;}/* --------- ARMAMode2: memory address expressions. --------- */ARMAMode2* ARMAMode2_RI ( HReg Rn, ARMImm12 imm ) { ARMAMode2* am = LibVEX_Alloc(sizeof(ARMAMode2)); am->tag = ARMam2_RI; am->ARMam2.RI.Rn = Rn; am->ARMam2.RI.imm = imm; return am;}ARMAMode2* ARMAMode2_RR ( HReg Rn, HReg Rm ) { ARMAMode2* am = LibVEX_Alloc(sizeof(ARMAMode2)); am->tag = ARMam2_RR; am->ARMam2.RR.Rn = Rn; am->ARMam2.RR.Rm = Rm; return am;}ARMAMode2* ARMAMode2_RRS ( HReg Rn, HReg Rm, ARMImm5 shift ) { ARMAMode2* am = LibVEX_Alloc(sizeof(ARMAMode2)); am->tag = ARMam2_RRS; am->ARMam2.RRS.Rn = Rn; am->ARMam2.RRS.Rm = Rm; am->ARMam2.RRS.shift = shift; return am;}ARMAMode2* dopyARMAMode2 ( ARMAMode2* am ) { switch (am->tag) { case ARMam2_RI: return ARMAMode2_RI( am->ARMam2.RI.Rn, am->ARMam2.RI.imm ); case ARMam2_RR: return ARMAMode2_RR( am->ARMam2.RR.Rn, am->ARMam2.RR.Rm ); case ARMam2_RRS: return ARMAMode2_RRS( am->ARMam2.RRS.Rn, am->ARMam2.RRS.Rm, am->ARMam2.RRS.shift ); default: vpanic("dopyARMAMode2"); }}void ppARMAMode2 ( ARMAMode2* am ) { switch (am->tag) { case ARMam2_RI: case ARMam2_RR: case ARMam2_RRS: vex_printf("ppARMAMode2: Not implemented"); break; default: vpanic("ppARMAMode2"); }}/*static void addRegUsage_ARMAMode2 ( HRegUsage* u, ARMAMode1* am ) {static void mapRegs_ARMAMode2 ( HRegRemap* m, ARMAMode1* am ) {*//* --------- ARMAMode3: memory address expressions. --------- */ARMAMode3* ARMAMode3_RI ( HReg Rn, ARMImm8 imm ) { ARMAMode3* am = LibVEX_Alloc(sizeof(ARMAMode3)); am->tag = ARMam3_RI; am->ARMam3.RI.Rn = Rn; am->ARMam3.RI.imm = imm; return am;}ARMAMode3* ARMAMode3_RR ( HReg Rn, HReg Rm ) { ARMAMode3* am = LibVEX_Alloc(sizeof(ARMAMode3)); am->tag = ARMam3_RR; am->ARMam3.RR.Rn = Rn; am->ARMam3.RR.Rm = Rm; return am;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -