Home | History | Annotate | Download | only in priv
      1 
      2 /*---------------------------------------------------------------*/
      3 /*--- begin                                  guest_arm_defs.h ---*/
      4 /*---------------------------------------------------------------*/
      5 /*
      6    This file is part of Valgrind, a dynamic binary instrumentation
      7    framework.
      8 
      9    Copyright (C) 2004-2017 OpenWorks LLP
     10       info (at) open-works.net
     11 
     12    This program is free software; you can redistribute it and/or
     13    modify it under the terms of the GNU General Public License as
     14    published by the Free Software Foundation; either version 2 of the
     15    License, or (at your option) any later version.
     16 
     17    This program is distributed in the hope that it will be useful, but
     18    WITHOUT ANY WARRANTY; without even the implied warranty of
     19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     20    General Public License for more details.
     21 
     22    You should have received a copy of the GNU General Public License
     23    along with this program; if not, write to the Free Software
     24    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
     25    02110-1301, USA.
     26 
     27    The GNU General Public License is contained in the file COPYING.
     28 */
     29 
     30 /* Only to be used within the guest-arm directory. */
     31 
     32 #ifndef __VEX_GUEST_ARM_DEFS_H
     33 #define __VEX_GUEST_ARM_DEFS_H
     34 
     35 #include "libvex_basictypes.h"
     36 #include "guest_generic_bb_to_IR.h"     // DisResult
     37 
     38 /*---------------------------------------------------------*/
     39 /*--- arm to IR conversion                              ---*/
     40 /*---------------------------------------------------------*/
     41 
     42 /* Convert one ARM insn to IR.  See the type DisOneInstrFn in
     43   geust_generic_ bb_to_IR.h. */
     44 extern
     45 DisResult disInstr_ARM ( IRSB*        irbb,
     46                          Bool         (*resteerOkFn) ( void*, Addr ),
     47                          Bool         resteerCisOk,
     48                          void*        callback_opaque,
     49                          const UChar* guest_code,
     50                          Long         delta,
     51                          Addr         guest_IP,
     52                          VexArch      guest_arch,
     53                          const VexArchInfo* archinfo,
     54                          const VexAbiInfo*  abiinfo,
     55                          VexEndness   host_endness,
     56                          Bool         sigill_diag );
     57 
     58 /* Used by the optimiser to specialise calls to helpers. */
     59 extern
     60 IRExpr* guest_arm_spechelper ( const HChar* function_name,
     61                                IRExpr** args,
     62                                IRStmt** precedingStmts,
     63                                Int      n_precedingStmts );
     64 
     65 /* Describes to the optimser which part of the guest state require
     66    precise memory exceptions.  This is logically part of the guest
     67    state description. */
     68 extern
     69 Bool guest_arm_state_requires_precise_mem_exns ( Int, Int,
     70                                                  VexRegisterUpdates );
     71 
     72 extern
     73 VexGuestLayout armGuest_layout;
     74 
     75 
     76 /*---------------------------------------------------------*/
     77 /*--- arm guest helpers                                 ---*/
     78 /*---------------------------------------------------------*/
     79 
     80 /* --- CLEAN HELPERS --- */
     81 
     82 /* Calculate NZCV from the supplied thunk components, in the positions
     83    they appear in the CPSR, viz bits 31:28 for N Z V C respectively.
     84    Returned bits 27:0 are zero. */
     85 extern
     86 UInt armg_calculate_flags_nzcv ( UInt cc_op, UInt cc_dep1,
     87                                  UInt cc_dep2, UInt cc_dep3 );
     88 
     89 /* Calculate the C flag from the thunk components, in the lowest bit
     90    of the word (bit 0). */
     91 extern
     92 UInt armg_calculate_flag_c ( UInt cc_op, UInt cc_dep1,
     93                              UInt cc_dep2, UInt cc_dep3 );
     94 
     95 /* Calculate the V flag from the thunk components, in the lowest bit
     96    of the word (bit 0). */
     97 extern
     98 UInt armg_calculate_flag_v ( UInt cc_op, UInt cc_dep1,
     99                              UInt cc_dep2, UInt cc_dep3 );
    100 
    101 /* Calculate the specified condition from the thunk components, in the
    102    lowest bit of the word (bit 0). */
    103 extern
    104 UInt armg_calculate_condition ( UInt cond_n_op /* ARMCondcode << 4 | cc_op */,
    105                                 UInt cc_dep1,
    106                                 UInt cc_dep2, UInt cc_dep3 );
    107 
    108 /* Calculate the QC flag from the thunk components, in the lowest bit
    109    of the word (bit 0). */
    110 extern
    111 UInt armg_calculate_flag_qc ( UInt resL1, UInt resL2,
    112                               UInt resR1, UInt resR2 );
    113 
    114 /* --- DIRTY HELPERS --- */
    115 
    116 /* Confusingly, for the AES insns, the 32-bit ARM docs refers to the
    117    one-and-only source register as 'm' whereas the 64-bit docs refer to
    118    it as 'n'.  We sidestep that here by just calling it 'arg32_*'. */
    119 
    120 extern
    121 void armg_dirtyhelper_AESE (
    122         /*OUT*/V128* res,
    123         UInt arg32_3, UInt arg32_2, UInt arg32_1, UInt arg32_0
    124      );
    125 
    126 extern
    127 void armg_dirtyhelper_AESD (
    128         /*OUT*/V128* res,
    129         UInt arg32_3, UInt arg32_2, UInt arg32_1, UInt arg32_0
    130      );
    131 
    132 extern
    133 void armg_dirtyhelper_AESMC (
    134         /*OUT*/V128* res,
    135         UInt arg32_3, UInt arg32_2, UInt arg32_1, UInt arg32_0
    136      );
    137 
    138 extern
    139 void armg_dirtyhelper_AESIMC (
    140         /*OUT*/V128* res,
    141         UInt arg32_3, UInt arg32_2, UInt arg32_1, UInt arg32_0
    142      );
    143 
    144 extern
    145 void armg_dirtyhelper_SHA1C (
    146         /*OUT*/V128* res,
    147         UInt argD3, UInt argD2, UInt argD1, UInt argD0,
    148         UInt argN3, UInt argN2, UInt argN1, UInt argN0,
    149         UInt argM3, UInt argM2, UInt argM1, UInt argM0
    150      );
    151 
    152 extern
    153 void armg_dirtyhelper_SHA1P (
    154         /*OUT*/V128* res,
    155         UInt argD3, UInt argD2, UInt argD1, UInt argD0,
    156         UInt argN3, UInt argN2, UInt argN1, UInt argN0,
    157         UInt argM3, UInt argM2, UInt argM1, UInt argM0
    158      );
    159 
    160 extern
    161 void armg_dirtyhelper_SHA1M (
    162         /*OUT*/V128* res,
    163         UInt argD3, UInt argD2, UInt argD1, UInt argD0,
    164         UInt argN3, UInt argN2, UInt argN1, UInt argN0,
    165         UInt argM3, UInt argM2, UInt argM1, UInt argM0
    166      );
    167 
    168 extern
    169 void armg_dirtyhelper_SHA1SU0 (
    170         /*OUT*/V128* res,
    171         UInt argD3, UInt argD2, UInt argD1, UInt argD0,
    172         UInt argN3, UInt argN2, UInt argN1, UInt argN0,
    173         UInt argM3, UInt argM2, UInt argM1, UInt argM0
    174      );
    175 
    176 extern
    177 void armg_dirtyhelper_SHA256H (
    178         /*OUT*/V128* res,
    179         UInt argD3, UInt argD2, UInt argD1, UInt argD0,
    180         UInt argN3, UInt argN2, UInt argN1, UInt argN0,
    181         UInt argM3, UInt argM2, UInt argM1, UInt argM0
    182      );
    183 
    184 extern
    185 void armg_dirtyhelper_SHA256H2 (
    186         /*OUT*/V128* res,
    187         UInt argD3, UInt argD2, UInt argD1, UInt argD0,
    188         UInt argN3, UInt argN2, UInt argN1, UInt argN0,
    189         UInt argM3, UInt argM2, UInt argM1, UInt argM0
    190      );
    191 
    192 extern
    193 void armg_dirtyhelper_SHA256SU1 (
    194         /*OUT*/V128* res,
    195         UInt argD3, UInt argD2, UInt argD1, UInt argD0,
    196         UInt argN3, UInt argN2, UInt argN1, UInt argN0,
    197         UInt argM3, UInt argM2, UInt argM1, UInt argM0
    198      );
    199 
    200 extern
    201 void armg_dirtyhelper_SHA1SU1 (
    202         /*OUT*/V128* res,
    203         UInt argD3, UInt argD2, UInt argD1, UInt argD0,
    204         UInt argM3, UInt argM2, UInt argM1, UInt argM0
    205      );
    206 
    207 extern
    208 void armg_dirtyhelper_SHA256SU0 (
    209         /*OUT*/V128* res,
    210         UInt argD3, UInt argD2, UInt argD1, UInt argD0,
    211         UInt argM3, UInt argM2, UInt argM1, UInt argM0
    212      );
    213 
    214 extern
    215 void armg_dirtyhelper_SHA1H (
    216         /*OUT*/V128* res,
    217         UInt argM3, UInt argM2, UInt argM1, UInt argM0
    218      );
    219 
    220 extern
    221 void armg_dirtyhelper_VMULLP64 (
    222         /*OUT*/V128* res,
    223         UInt argN1, UInt argN0, UInt argM1, UInt argM0
    224      );
    225 
    226 
    227 /*---------------------------------------------------------*/
    228 /*--- Condition code stuff                              ---*/
    229 /*---------------------------------------------------------*/
    230 
    231 /* Flags masks.  Defines positions of flags bits in the CPSR. */
    232 #define ARMG_CC_SHIFT_N  31
    233 #define ARMG_CC_SHIFT_Z  30
    234 #define ARMG_CC_SHIFT_C  29
    235 #define ARMG_CC_SHIFT_V  28
    236 #define ARMG_CC_SHIFT_Q  27
    237 
    238 #define ARMG_CC_MASK_N    (1 << ARMG_CC_SHIFT_N)
    239 #define ARMG_CC_MASK_Z    (1 << ARMG_CC_SHIFT_Z)
    240 #define ARMG_CC_MASK_C    (1 << ARMG_CC_SHIFT_C)
    241 #define ARMG_CC_MASK_V    (1 << ARMG_CC_SHIFT_V)
    242 #define ARMG_CC_MASK_Q    (1 << ARMG_CC_SHIFT_Q)
    243 
    244 /* Flag thunk descriptors.  A four-word thunk is used to record
    245    details of the most recent flag-setting operation, so NZCV can
    246    be computed later if needed.
    247 
    248    The four words are:
    249 
    250       CC_OP, which describes the operation.
    251 
    252       CC_DEP1, CC_DEP2, CC_DEP3.  These are arguments to the
    253          operation.  We want set up the mcx_masks in flag helper calls
    254          involving these fields so that Memcheck "believes" that the
    255          resulting flags are data-dependent on both CC_DEP1 and
    256          CC_DEP2.  Hence the name DEP.
    257 
    258    When building the thunk, it is always necessary to write words into
    259    CC_DEP1/2/3, even if those args are not used given the
    260    CC_OP field.  This is important because otherwise Memcheck could
    261    give false positives as it does not understand the relationship
    262    between the CC_OP field and CC_DEP1/2/3, and so believes
    263    that the definedness of the stored flags always depends on
    264    all 3 DEP values.
    265 
    266    Fields carrying only 1 or 2 bits of useful information (old_C,
    267    shifter_co, old_V, oldC:oldV) must have their top 31 or 30 bits
    268    (respectively) zero.  The text "31x0:" or "30x0:" denotes this.
    269 
    270    A summary of the field usages is:
    271 
    272    OP                DEP1              DEP2              DEP3
    273    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    274 
    275    OP_COPY           curr_NZCV:28x0    unused            unused
    276    OP_ADD            argL              argR              unused
    277    OP_SUB            argL              argR              unused
    278    OP_ADC            argL              argR              31x0:old_C
    279    OP_SBB            argL              argR              31x0:old_C
    280    OP_LOGIC          result            31x0:shifter_co   31x0:old_V
    281    OP_MUL            result            unused            30x0:old_C:old_V
    282    OP_MULL           resLO32           resHI32           30x0:old_C:old_V
    283 */
    284 
    285 enum {
    286    ARMG_CC_OP_COPY=0,  /* DEP1 = NZCV in 31:28, DEP2 = 0, DEP3 = 0
    287                           just copy DEP1 to output */
    288 
    289    ARMG_CC_OP_ADD,     /* DEP1 = argL (Rn), DEP2 = argR (shifter_op),
    290                           DEP3 = 0 */
    291 
    292    ARMG_CC_OP_SUB,     /* DEP1 = argL (Rn), DEP2 = argR (shifter_op),
    293                           DEP3 = 0 */
    294 
    295    ARMG_CC_OP_ADC,     /* DEP1 = argL (Rn), DEP2 = arg2 (shifter_op),
    296                           DEP3 = oldC (in LSB) */
    297 
    298    ARMG_CC_OP_SBB,     /* DEP1 = argL (Rn), DEP2 = arg2 (shifter_op),
    299                           DEP3 = oldC (in LSB) */
    300 
    301    ARMG_CC_OP_LOGIC,   /* DEP1 = result, DEP2 = shifter_carry_out (in LSB),
    302                           DEP3 = old V flag (in LSB) */
    303 
    304    ARMG_CC_OP_MUL,     /* DEP1 = result, DEP2 = 0, DEP3 = oldC:old_V
    305                           (in bits 1:0) */
    306 
    307    ARMG_CC_OP_MULL,    /* DEP1 = resLO32, DEP2 = resHI32, DEP3 = oldC:old_V
    308                           (in bits 1:0) */
    309 
    310    ARMG_CC_OP_NUMBER
    311 };
    312 
    313 /* XXXX because of the calling conventions for
    314    armg_calculate_condition, all this OP values MUST be in the range
    315    0 .. 15 only (viz, 4-bits). */
    316 
    317 
    318 
    319 /* Defines conditions which we can ask for (ARM ARM 2e page A3-6) */
    320 
    321 typedef
    322    enum {
    323       ARMCondEQ     = 0,  /* equal                         : Z=1 */
    324       ARMCondNE     = 1,  /* not equal                     : Z=0 */
    325 
    326       ARMCondHS     = 2,  /* >=u (higher or same)          : C=1 */
    327       ARMCondLO     = 3,  /* <u  (lower)                   : C=0 */
    328 
    329       ARMCondMI     = 4,  /* minus (negative)              : N=1 */
    330       ARMCondPL     = 5,  /* plus (zero or +ve)            : N=0 */
    331 
    332       ARMCondVS     = 6,  /* overflow                      : V=1 */
    333       ARMCondVC     = 7,  /* no overflow                   : V=0 */
    334 
    335       ARMCondHI     = 8,  /* >u   (higher)                 : C=1 && Z=0 */
    336       ARMCondLS     = 9,  /* <=u  (lower or same)          : C=0 || Z=1 */
    337 
    338       ARMCondGE     = 10, /* >=s (signed greater or equal) : N=V */
    339       ARMCondLT     = 11, /* <s  (signed less than)        : N!=V */
    340 
    341       ARMCondGT     = 12, /* >s  (signed greater)          : Z=0 && N=V */
    342       ARMCondLE     = 13, /* <=s (signed less or equal)    : Z=1 || N!=V */
    343 
    344       ARMCondAL     = 14, /* always (unconditional)        : 1 */
    345       ARMCondNV     = 15  /* never (unconditional):        : 0 */
    346       /* NB: ARM have deprecated the use of the NV condition code.
    347          You are now supposed to use MOV R0,R0 as a noop rather than
    348          MOVNV R0,R0 as was previously recommended.  Future processors
    349          may have the NV condition code reused to do other things.  */
    350    }
    351    ARMCondcode;
    352 
    353 #endif /* ndef __VEX_GUEST_ARM_DEFS_H */
    354 
    355 /*---------------------------------------------------------------*/
    356 /*--- end                                    guest_arm_defs.h ---*/
    357 /*---------------------------------------------------------------*/
    358