• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@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