| |
| /*---------------------------------------------------------------*/ |
| /*--- ---*/ |
| /*--- This file (guest-arm/gdefs.h) 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. |
| */ |
| |
| /* Only to be used within the guest-arm directory. */ |
| |
| #ifndef __LIBVEX_GUEST_ARM_DEFS_H |
| #define __LIBVEX_GUEST_ARM_DEFS_H |
| |
| |
| /*---------------------------------------------------------*/ |
| /*--- arm to IR conversion ---*/ |
| /*---------------------------------------------------------*/ |
| |
| extern |
| IRBB* bbToIR_ARM ( UChar* armCode, |
| Addr64 eip, |
| VexGuestExtents* vge, |
| Bool (*byte_accessible)(Addr64), |
| Bool (*resteerOkFn)(Addr64), |
| Bool host_bigendian, |
| VexArchInfo* archinfo_guest ); |
| |
| /* Used by the optimiser to specialise calls to helpers. */ |
| extern |
| IRExpr* guest_arm_spechelper ( HChar* function_name, |
| IRExpr** args ); |
| |
| /* Describes to the optimser which part of the guest state require |
| precise memory exceptions. This is logically part of the guest |
| state description. */ |
| extern |
| Bool guest_arm_state_requires_precise_mem_exns ( Int, Int ); |
| |
| extern |
| VexGuestLayout armGuest_layout; |
| |
| |
| /*---------------------------------------------------------*/ |
| /*--- arm guest helpers ---*/ |
| /*---------------------------------------------------------*/ |
| |
| /* --- CLEAN HELPERS --- */ |
| |
| extern UInt armg_calculate_flags_all ( |
| UInt cc_op, UInt cc_dep1, UInt cc_dep2 |
| ); |
| extern UInt armg_calculate_flags_c ( |
| UInt cc_op, UInt cc_dep1, UInt cc_dep2 |
| ); |
| |
| extern UInt armg_calculate_condition ( |
| UInt/*ARMCondcode*/ cond, |
| UInt cc_op, |
| UInt cc_dep1, UInt cc_dep2 |
| ); |
| |
| |
| /*---------------------------------------------------------*/ |
| /*--- Condition code stuff ---*/ |
| /*---------------------------------------------------------*/ |
| |
| /* Flags masks. Defines positions of flags bits in the CPSR. */ |
| #define ARMG_CC_SHIFT_N 31 |
| #define ARMG_CC_SHIFT_Z 30 |
| #define ARMG_CC_SHIFT_C 29 |
| #define ARMG_CC_SHIFT_V 28 |
| |
| #define ARMG_CC_MASK_N (1 << ARMG_CC_SHIFT_N) |
| #define ARMG_CC_MASK_Z (1 << ARMG_CC_SHIFT_Z) |
| #define ARMG_CC_MASK_V (1 << ARMG_CC_SHIFT_V) |
| #define ARMG_CC_MASK_C (1 << ARMG_CC_SHIFT_C) |
| |
| /* Flag thunk descriptors. A three-word thunk is used to record |
| details of the most recent flag-setting operation, so the flags can |
| be computed later if needed. |
| |
| The three words are: |
| |
| CC_OP, which describes the operation. |
| |
| CC_DEP1 and CC_DEP2. These are arguments to the operation. |
| We want Memcheck to believe that the resulting flags are |
| data-dependent on both CC_DEP1 and CC_DEP2, hence the |
| name DEP. |
| |
| When building the thunk, it is always necessary to write words into |
| CC_DEP1 and CC_DEP2, even if those args are not used given the |
| CC_OP field. This is important because otherwise Memcheck could |
| give false positives as it does not understand the relationship |
| between the CC_OP field and CC_DEP1 and CC_DEP2, and so believes |
| that the definedness of the stored flags always depends on both |
| CC_DEP1 and CC_DEP2. |
| |
| A summary of the field usages is: |
| TODO: make this right |
| |
| Operation DEP1 DEP2 NDEP |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| and/or/xor result shift_carry_out |
| tst/teq/bic result shift_carry_out |
| mov/mvn result shift_carry_out |
| |
| add/cmn first arg second arg |
| sub/cmp first arg second arg |
| |
| ... |
| |
| |
| Therefore Memcheck will believe the following: |
| |
| * ... |
| |
| */ |
| enum { |
| ARMG_CC_OP_COPY, /* DEP1 = current flags, DEP2 = 0 */ |
| /* just copy DEP1 to output */ |
| |
| ARMG_CC_OP_LOGIC, /* DEP1 = result, DEP2 = shifter_carry_out */ |
| |
| ARMG_CC_OP_SUB, /* DEP1 = arg1(Rn), DEP2 = arg2 (shifter_op) */ |
| ARMG_CC_OP_ADD, /* DEP1 = arg1(Rn), DEP2 = arg2 (shifter_op) */ |
| |
| ARMG_CC_OP_NUMBER |
| }; |
| |
| /* requires further study */ |
| |
| |
| |
| /* Defines conditions which we can ask for (ARM ARM 2e page A3-6) */ |
| |
| typedef |
| enum { |
| ARMCondEQ = 0, /* equal : Z=1 */ |
| ARMCondNE = 1, /* not equal : Z=0 */ |
| |
| ARMCondHS = 2, /* >=u (higher or same) : C=1 */ |
| ARMCondLO = 3, /* <u (lower) : C=0 */ |
| |
| ARMCondMI = 4, /* minus (negative) : N=1 */ |
| ARMCondPL = 5, /* plus (zero or +ve) : N=0 */ |
| |
| ARMCondVS = 6, /* overflow : V=1 */ |
| ARMCondVC = 7, /* no overflow : V=0 */ |
| |
| ARMCondHI = 8, /* >u (higher) : C=1 && Z=0 */ |
| ARMCondLS = 9, /* <=u (lower or same) : C=0 || Z=1 */ |
| |
| ARMCondGE = 10, /* >=s (signed greater or equal) : N=V */ |
| ARMCondLT = 11, /* <s (signed less than) : N!=V */ |
| |
| ARMCondGT = 12, /* >s (signed greater) : Z=0 && N=V */ |
| ARMCondLE = 13, /* <=s (signed less or equal) : Z=1 || N!=V */ |
| |
| ARMCondAL = 14, /* always (unconditional) : */ |
| ARMCondNV = 15 /* never (basically undefined meaning) : */ |
| /* NB: ARM have deprecated the use of the NV condition code |
| - you are now supposed to use MOV R0,R0 as a noop |
| rather than MOVNV R0,R0 as was previously recommended. |
| Future processors may have the NV condition code reused to do other things. */ |
| } |
| ARMCondcode; |
| |
| #endif /* ndef __LIBVEX_GUEST_ARM_DEFS_H */ |
| |
| /*---------------------------------------------------------------*/ |
| /*--- end guest-arm/gdefs.h ---*/ |
| /*---------------------------------------------------------------*/ |