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