Home | History | Annotate | Download | only in pub
      1 
      2 /*---------------------------------------------------------------*/
      3 /*--- begin                                libvex_guest_arm.h ---*/
      4 /*---------------------------------------------------------------*/
      5 
      6 /*
      7    This file is part of Valgrind, a dynamic binary instrumentation
      8    framework.
      9 
     10    Copyright (C) 2004-2012 OpenWorks LLP
     11       info (at) open-works.net
     12 
     13    This program is free software; you can redistribute it and/or
     14    modify it under the terms of the GNU General Public License as
     15    published by the Free Software Foundation; either version 2 of the
     16    License, or (at your option) any later version.
     17 
     18    This program is distributed in the hope that it will be useful, but
     19    WITHOUT ANY WARRANTY; without even the implied warranty of
     20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     21    General Public License for more details.
     22 
     23    You should have received a copy of the GNU General Public License
     24    along with this program; if not, write to the Free Software
     25    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
     26    02110-1301, USA.
     27 
     28    The GNU General Public License is contained in the file COPYING.
     29 */
     30 
     31 #ifndef __LIBVEX_PUB_GUEST_ARM_H
     32 #define __LIBVEX_PUB_GUEST_ARM_H
     33 
     34 #include "libvex_basictypes.h"
     35 #include "libvex_emwarn.h"
     36 
     37 
     38 /*---------------------------------------------------------------*/
     39 /*--- Vex's representation of the ARM CPU state.              ---*/
     40 /*---------------------------------------------------------------*/
     41 
     42 typedef
     43    struct {
     44       /* 0 */
     45       /* Event check fail addr and counter. */
     46       UInt host_EvC_FAILADDR; /* 0 */
     47       UInt host_EvC_COUNTER;  /* 4 */
     48       UInt guest_R0;
     49       UInt guest_R1;
     50       UInt guest_R2;
     51       UInt guest_R3;
     52       UInt guest_R4;
     53       UInt guest_R5;
     54       UInt guest_R6;
     55       UInt guest_R7;
     56       UInt guest_R8;
     57       UInt guest_R9;
     58       UInt guest_R10;
     59       UInt guest_R11;
     60       UInt guest_R12;
     61       UInt guest_R13;     /* stack pointer */
     62       UInt guest_R14;     /* link register */
     63       UInt guest_R15T;
     64       /* program counter[31:1] ++ [T], encoding both the current
     65          instruction address and the ARM vs Thumb state of the
     66          machine.  T==1 is Thumb, T==0 is ARM.  Hence values of the
     67          form X--(31)--X1 denote a Thumb instruction at location
     68          X--(31)--X0, values of the form X--(30)--X00 denote an ARM
     69          instruction at precisely that address, and values of the form
     70          X--(30)--10 are invalid since they would imply an ARM
     71          instruction at a non-4-aligned address. */
     72 
     73       /* 4-word thunk used to calculate N(sign) Z(zero) C(carry,
     74          unsigned overflow) and V(signed overflow) flags. */
     75       /* 72 */
     76       UInt guest_CC_OP;
     77       UInt guest_CC_DEP1;
     78       UInt guest_CC_DEP2;
     79       UInt guest_CC_NDEP;
     80 
     81       /* A 32-bit value which is used to compute the APSR.Q (sticky
     82          saturation) flag, when necessary.  If the value stored here
     83          is zero, APSR.Q is currently zero.  If it is any other value,
     84          APSR.Q is currently one. */
     85       UInt guest_QFLAG32;
     86 
     87       /* 32-bit values to represent APSR.GE0 .. GE3.  Same
     88          zero-vs-nonzero scheme as for QFLAG32. */
     89       UInt guest_GEFLAG0;
     90       UInt guest_GEFLAG1;
     91       UInt guest_GEFLAG2;
     92       UInt guest_GEFLAG3;
     93 
     94       /* Various pseudo-regs mandated by Vex or Valgrind. */
     95       /* Emulation warnings */
     96       UInt guest_EMWARN;
     97 
     98       /* For clflush: record start and length of area to invalidate */
     99       UInt guest_TISTART;
    100       UInt guest_TILEN;
    101 
    102       /* Used to record the unredirected guest address at the start of
    103          a translation whose start has been redirected.  By reading
    104          this pseudo-register shortly afterwards, the translation can
    105          find out what the corresponding no-redirection address was.
    106          Note, this is only set for wrap-style redirects, not for
    107          replace-style ones. */
    108       UInt guest_NRADDR;
    109 
    110       /* Needed for Darwin (but mandated for all guest architectures):
    111          program counter at the last syscall insn (int 0x80/81/82,
    112          sysenter, syscall, svc).  Used when backing up to restart a
    113          syscall that has been interrupted by a signal. */
    114       /* 124 */
    115       UInt guest_IP_AT_SYSCALL;
    116 
    117       /* VFP state.  D0 .. D15 must be 8-aligned. */
    118       /* 128 */
    119       ULong guest_D0;
    120       ULong guest_D1;
    121       ULong guest_D2;
    122       ULong guest_D3;
    123       ULong guest_D4;
    124       ULong guest_D5;
    125       ULong guest_D6;
    126       ULong guest_D7;
    127       ULong guest_D8;
    128       ULong guest_D9;
    129       ULong guest_D10;
    130       ULong guest_D11;
    131       ULong guest_D12;
    132       ULong guest_D13;
    133       ULong guest_D14;
    134       ULong guest_D15;
    135       ULong guest_D16;
    136       ULong guest_D17;
    137       ULong guest_D18;
    138       ULong guest_D19;
    139       ULong guest_D20;
    140       ULong guest_D21;
    141       ULong guest_D22;
    142       ULong guest_D23;
    143       ULong guest_D24;
    144       ULong guest_D25;
    145       ULong guest_D26;
    146       ULong guest_D27;
    147       ULong guest_D28;
    148       ULong guest_D29;
    149       ULong guest_D30;
    150       ULong guest_D31;
    151       UInt  guest_FPSCR;
    152 
    153       /* Not a town in Cornwall, but instead the TPIDRURO, on of the
    154          Thread ID registers present in CP15 (the system control
    155          coprocessor), register set "c13", register 3 (the User
    156          Read-only Thread ID Register).  arm-linux apparently uses it
    157          to hold the TLS pointer for the thread.  It's read-only in
    158          user space.  On Linux it is set in user space by various
    159          thread-related syscalls. */
    160       UInt guest_TPIDRURO;
    161 
    162       /* Representation of the Thumb IT state.  ITSTATE is a 32-bit
    163          value with 4 8-bit lanes.  [7:0] pertain to the next insn to
    164          execute, [15:8] for the one after that, etc.  The per-insn
    165          update to ITSTATE is to unsignedly shift it right 8 bits,
    166          hence introducing a zero byte for the furthest ahead
    167          instruction.  As per the next para, a zero byte denotes the
    168          condition ALWAYS.
    169 
    170          Each byte lane has one of the two following formats:
    171 
    172          cccc 0001  for an insn which is part of an IT block.  cccc is
    173                     the guarding condition (standard ARM condition
    174                     code) XORd with 0xE, so as to cause 'cccc == 0'
    175                     to encode the condition ALWAYS.
    176 
    177          0000 0000  for an insn which is not part of an IT block.
    178 
    179          If the bottom 4 bits are zero then the top 4 must be too.
    180 
    181          Given the byte lane for an instruction, the guarding
    182          condition for the instruction is (((lane >> 4) & 0xF) ^ 0xE).
    183          This is not as stupid as it sounds, because the front end
    184          elides the shift.  And the am-I-in-an-IT-block check is
    185          (lane != 0).
    186 
    187          In the case where (by whatever means) we know at JIT time
    188          that an instruction is not in an IT block, we can prefix its
    189          IR with assignments ITSTATE = 0 and hence have iropt fold out
    190          the testing code.
    191 
    192          The condition "is outside or last in IT block" corresponds
    193          to the top 24 bits of ITSTATE being zero.
    194       */
    195       UInt guest_ITSTATE;
    196 
    197       /* Padding to make it have an 32-aligned size */
    198       UInt padding1;
    199       UInt padding2;
    200       UInt padding3;
    201       UInt padding4;
    202       UInt padding5;
    203    }
    204    VexGuestARMState;
    205 
    206 
    207 /*---------------------------------------------------------------*/
    208 /*--- Utility functions for ARM guest stuff.                  ---*/
    209 /*---------------------------------------------------------------*/
    210 
    211 /* ALL THE FOLLOWING ARE VISIBLE TO LIBRARY CLIENT */
    212 
    213 /* Initialise all guest ARM state. */
    214 
    215 extern
    216 void LibVEX_GuestARM_initialise ( /*OUT*/VexGuestARMState* vex_state );
    217 
    218 /* Calculate the ARM flag state from the saved data. */
    219 
    220 extern
    221 UInt LibVEX_GuestARM_get_cpsr ( /*IN*/VexGuestARMState* vex_state );
    222 
    223 
    224 #endif /* ndef __LIBVEX_PUB_GUEST_ARM_H */
    225 
    226 
    227 /*---------------------------------------------------------------*/
    228 /*---                                      libvex_guest_arm.h ---*/
    229 /*---------------------------------------------------------------*/
    230