Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-07-25 09:35:37

0001 
0002 /*---------------------------------------------------------------*/
0003 /*--- begin                                libvex_guest_arm.h ---*/
0004 /*---------------------------------------------------------------*/
0005 
0006 /*
0007    This file is part of Valgrind, a dynamic binary instrumentation
0008    framework.
0009 
0010    Copyright (C) 2004-2017 OpenWorks LLP
0011       info@open-works.net
0012 
0013    This program is free software; you can redistribute it and/or
0014    modify it under the terms of the GNU General Public License as
0015    published by the Free Software Foundation; either version 3 of the
0016    License, or (at your option) any later version.
0017 
0018    This program is distributed in the hope that it will be useful, but
0019    WITHOUT ANY WARRANTY; without even the implied warranty of
0020    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0021    General Public License for more details.
0022 
0023    You should have received a copy of the GNU General Public License
0024    along with this program; if not, see <http://www.gnu.org/licenses/>.
0025 
0026    The GNU General Public License is contained in the file COPYING.
0027 */
0028 
0029 #ifndef __LIBVEX_PUB_GUEST_ARM_H
0030 #define __LIBVEX_PUB_GUEST_ARM_H
0031 
0032 #include "libvex_basictypes.h"
0033 
0034 
0035 /*---------------------------------------------------------------*/
0036 /*--- Vex's representation of the ARM CPU state.              ---*/
0037 /*---------------------------------------------------------------*/
0038 
0039 typedef
0040    struct {
0041       /* 0 */
0042       /* Event check fail addr and counter. */
0043       UInt host_EvC_FAILADDR; /* 0 */
0044       UInt host_EvC_COUNTER;  /* 4 */
0045       UInt guest_R0;
0046       UInt guest_R1;
0047       UInt guest_R2;
0048       UInt guest_R3;
0049       UInt guest_R4;
0050       UInt guest_R5;
0051       UInt guest_R6;
0052       UInt guest_R7;
0053       UInt guest_R8;
0054       UInt guest_R9;
0055       UInt guest_R10;
0056       UInt guest_R11;
0057       UInt guest_R12;
0058       UInt guest_R13;     /* stack pointer */
0059       UInt guest_R14;     /* link register */
0060       UInt guest_R15T;
0061       /* program counter[31:1] ++ [T], encoding both the current
0062          instruction address and the ARM vs Thumb state of the
0063          machine.  T==1 is Thumb, T==0 is ARM.  Hence values of the
0064          form X--(31)--X1 denote a Thumb instruction at location
0065          X--(31)--X0, values of the form X--(30)--X00 denote an ARM
0066          instruction at precisely that address, and values of the form
0067          X--(30)--10 are invalid since they would imply an ARM
0068          instruction at a non-4-aligned address. */
0069 
0070       /* 4-word thunk used to calculate N(sign) Z(zero) C(carry,
0071          unsigned overflow) and V(signed overflow) flags. */
0072       /* 72 */
0073       UInt guest_CC_OP;
0074       UInt guest_CC_DEP1;
0075       UInt guest_CC_DEP2;
0076       UInt guest_CC_NDEP;
0077 
0078       /* A 32-bit value which is used to compute the APSR.Q (sticky
0079          saturation) flag, when necessary.  If the value stored here
0080          is zero, APSR.Q is currently zero.  If it is any other value,
0081          APSR.Q is currently one. */
0082       UInt guest_QFLAG32;
0083 
0084       /* 32-bit values to represent APSR.GE0 .. GE3.  Same
0085          zero-vs-nonzero scheme as for QFLAG32. */
0086       UInt guest_GEFLAG0;
0087       UInt guest_GEFLAG1;
0088       UInt guest_GEFLAG2;
0089       UInt guest_GEFLAG3;
0090 
0091       /* Various pseudo-regs mandated by Vex or Valgrind. */
0092       /* Emulation notes */
0093       UInt guest_EMNOTE;
0094 
0095       /* For clinval/clflush: record start and length of area */
0096       UInt guest_CMSTART;
0097       UInt guest_CMLEN;
0098 
0099       /* Used to record the unredirected guest address at the start of
0100          a translation whose start has been redirected.  By reading
0101          this pseudo-register shortly afterwards, the translation can
0102          find out what the corresponding no-redirection address was.
0103          Note, this is only set for wrap-style redirects, not for
0104          replace-style ones. */
0105       UInt guest_NRADDR;
0106 
0107       /* 124 */
0108       UInt padding1;
0109 
0110       /* VFP state.  D0 .. D15 must be 8-aligned. */
0111       /* 128 */
0112       ULong guest_D0;
0113       ULong guest_D1;
0114       ULong guest_D2;
0115       ULong guest_D3;
0116       ULong guest_D4;
0117       ULong guest_D5;
0118       ULong guest_D6;
0119       ULong guest_D7;
0120       ULong guest_D8;
0121       ULong guest_D9;
0122       ULong guest_D10;
0123       ULong guest_D11;
0124       ULong guest_D12;
0125       ULong guest_D13;
0126       ULong guest_D14;
0127       ULong guest_D15;
0128       ULong guest_D16;
0129       ULong guest_D17;
0130       ULong guest_D18;
0131       ULong guest_D19;
0132       ULong guest_D20;
0133       ULong guest_D21;
0134       ULong guest_D22;
0135       ULong guest_D23;
0136       ULong guest_D24;
0137       ULong guest_D25;
0138       ULong guest_D26;
0139       ULong guest_D27;
0140       ULong guest_D28;
0141       ULong guest_D29;
0142       ULong guest_D30;
0143       ULong guest_D31;
0144       UInt  guest_FPSCR;
0145 
0146       /* Not a town in Cornwall, but instead the TPIDRURO, on of the
0147          Thread ID registers present in CP15 (the system control
0148          coprocessor), register set "c13", register 3 (the User
0149          Read-only Thread ID Register).  arm-linux apparently uses it
0150          to hold the TLS pointer for the thread.  It's read-only in
0151          user space.  On Linux it is set in user space by various
0152          thread-related syscalls. */
0153       UInt guest_TPIDRURO;
0154 
0155       /* TPIDRURW is also apparently used as a thread register, but one
0156          controlled entirely by, and writable from, user space.  We model
0157          it as a completely vanilla piece of integer state. */
0158       UInt guest_TPIDRURW;
0159 
0160       /* Representation of the Thumb IT state.  ITSTATE is a 32-bit
0161          value with 4 8-bit lanes.  [7:0] pertain to the next insn to
0162          execute, [15:8] for the one after that, etc.  The per-insn
0163          update to ITSTATE is to unsignedly shift it right 8 bits,
0164          hence introducing a zero byte for the furthest ahead
0165          instruction.  As per the next para, a zero byte denotes the
0166          condition ALWAYS.
0167 
0168          Each byte lane has one of the two following formats:
0169 
0170          cccc 0001  for an insn which is part of an IT block.  cccc is
0171                     the guarding condition (standard ARM condition
0172                     code) XORd with 0xE, so as to cause 'cccc == 0'
0173                     to encode the condition ALWAYS.
0174 
0175          0000 0000  for an insn which is not part of an IT block.
0176 
0177          If the bottom 4 bits are zero then the top 4 must be too.
0178 
0179          Given the byte lane for an instruction, the guarding
0180          condition for the instruction is (((lane >> 4) & 0xF) ^ 0xE).
0181          This is not as stupid as it sounds, because the front end
0182          elides the shift.  And the am-I-in-an-IT-block check is
0183          (lane != 0).
0184 
0185          In the case where (by whatever means) we know at JIT time
0186          that an instruction is not in an IT block, we can prefix its
0187          IR with assignments ITSTATE = 0 and hence have iropt fold out
0188          the testing code.
0189 
0190          The condition "is outside or last in IT block" corresponds
0191          to the top 24 bits of ITSTATE being zero.
0192       */
0193       UInt guest_ITSTATE;
0194    }
0195    VexGuestARMState;
0196 
0197 _Static_assert(sizeof(VexGuestARMState)%16 == 0, "sizeof VexGuestX86State is not a multiple of 16");
0198 
0199 /*---------------------------------------------------------------*/
0200 /*--- Utility functions for ARM guest stuff.                  ---*/
0201 /*---------------------------------------------------------------*/
0202 
0203 /* ALL THE FOLLOWING ARE VISIBLE TO LIBRARY CLIENT */
0204 
0205 /* Initialise all guest ARM state. */
0206 
0207 extern
0208 void LibVEX_GuestARM_initialise ( /*OUT*/VexGuestARMState* vex_state );
0209 
0210 /* Calculate the ARM flag state from the saved data. */
0211 
0212 extern
0213 UInt LibVEX_GuestARM_get_cpsr ( /*IN*/const VexGuestARMState* vex_state );
0214 
0215 
0216 #endif /* ndef __LIBVEX_PUB_GUEST_ARM_H */
0217 
0218 
0219 /*---------------------------------------------------------------*/
0220 /*---                                      libvex_guest_arm.h ---*/
0221 /*---------------------------------------------------------------*/