1 : /*
2 : * Copyright (c) 2012 The Native Client Authors. All rights reserved.
3 : * Use of this source code is governed by a BSD-style license that can be
4 : * found in the LICENSE file.
5 : */
6 :
7 : #ifndef NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_ARM_V2_MODEL_H
8 : #define NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_ARM_V2_MODEL_H
9 :
10 : /*
11 : * Models instructions and decode results.
12 : *
13 : * Implementation Note:
14 : * All the classes in this file are designed to be fully inlined as 32-bit
15 : * (POD) integers. The goal: to provide a nice, fluent interface for
16 : * describing instruction bit operations, with zero runtime cost. Compare:
17 : *
18 : * return (1 << ((insn >> 12) & 0xF)) | (1 << ((insn >> 19) & 0xF));
19 : *
20 : * return insn.reg(15,12) + insn.reg(19,16);
21 : *
22 : * Both lines compile to the same machine code, but the second one is easier
23 : * to read, and eliminates a common error (using X in place of 1 << X).
24 : *
25 : * To this end, keep the following in mind:
26 : * - Avoid virtual methods.
27 : * - Mark all methods as inline. Small method bodies may be included here,
28 : * but anything nontrivial should go in model-inl.h.
29 : * - Do not declare destructors. A destructor causes an object to be passed
30 : * on the stack, even when passed by value. (This may be a GCC bug.)
31 : * Adding a destructor to Instruction slowed the decoder down by 10% on
32 : * gcc 4.3.3.
33 : */
34 :
35 : #include <cstddef>
36 : #include <string>
37 : #include "native_client/src/include/arm_sandbox.h"
38 : #include "native_client/src/include/portability.h"
39 : #include "native_client/src/include/portability_bits.h"
40 :
41 : namespace nacl_arm_dec {
42 :
43 : class RegisterList;
44 :
45 : // Defines the architecture version of the ARM processor. Currently assumes
46 : // always 7.
47 : // TODO(karl): Generalize this to handle multiple versions, once we know how
48 : // to do this.
49 0 : inline uint32_t ArchVersion() {
50 0 : return 7;
51 0 : }
52 :
53 : // Returns FALSE if all of the 32 registers D0-D31 can be accessed, and TRUE if
54 : // only the 16 registers D0-D15 can be accessed.
55 0 : inline bool VFPSmallRegisterBank() {
56 : // Note: The minimum supported platform, which is checked in (see
57 : // native_client/src/trusted/platform_qualify/arch/arm/nacl_arm_qualify.h)
58 : // allows access to all 32 registers D0-D31.
59 0 : return false;
60 0 : }
61 :
62 : // A (POD) value class that names a single register. We could use a typedef
63 : // for this, but it introduces some ambiguity problems because of the
64 : // implicit conversion to/from int.
65 : //
66 : // The 32-bit ARM v7 ARM and Thumb instruction sets have:
67 : // - 15 32-bit GPRs, with:
68 : // - R13/R14/R15 serving as SP/LR/PC.
69 : // - R8-R15 being inaccessible in most 16-bit Thumb instructions.
70 : // - FPRs, with:
71 : // - 16 128-bit quadword registers, denoted Q0-Q15.
72 : // - 32 64-bit doubleword registers, denoted D0-D31.
73 : // - 32 32-bit single word registers, denoted S0-S31.
74 : // - Note that the above holds true for only some ARM processors:
75 : // different VFP implementations might have only D0-D15 with S0-S31,
76 : // and Advanced SIMD support is required for the quadword registers.
77 : // - The above FPRs are overlaid and accessing S/D/Q registers
78 : // interchangeably is sometimes expected by the ARM ISA.
79 : // Specifically S0-S3 correspond to D0-D1 as well as Q0,
80 : // S4-S7 to D2-D3 and Q1, and so on.
81 : // D16-D31 and Q8-Q15 do not correspond to any single word register.
82 : //
83 : // TODO(jfb) detail aarch64 when we support ARM v8.
84 : class Register {
85 : public:
86 : typedef uint8_t Number;
87 : // RegisterMask wide enough for aarch32, including "special" registers.
88 : // TODO(jfb) Update for aarch64.
89 : typedef uint32_t Mask;
90 : // aarch32 only has 16 GPRs, we steal other registers for flags and such.
91 : // TODO(jfb) Update for aarch64.
92 : static const Mask kGprMask = 0xFFFF;
93 :
94 : Register() : number_(kNone) {}
95 0 : explicit Register(Number number) : number_(number) {}
96 0 : Register(const Register& r) : number_(r.number_) {}
97 :
98 : // Produces the bitmask used to represent this register, in both RegisterList
99 : // and ARM's LDM instruction.
100 0 : Mask BitMask() const {
101 0 : return (number_ == kNone) ? 0 : (1u << number_);
102 0 : }
103 :
104 0 : Number number() const { return number_; }
105 0 : bool Equals(const Register& r) const { return number_ == r.number_; }
106 :
107 : Register& Copy(const Register& r) {
108 : number_ = r.number_;
109 : return *this;
110 : }
111 :
112 : const char* ToString() const;
113 :
114 : // TODO(jfb) Need different numbers for aarch64.
115 : static const Number kTp = 9; // Thread local pointer.
116 : static const Number kSp = 13; // Stack pointer.
117 : static const Number kLr = 14; // Link register.
118 : static const Number kPc = 15; // Program counter.
119 : static const Number kNumberGPRs = 16; // Number of General purpose registers.
120 : static const Number kConditions = 16;
121 : static const Number kNone = 32; // Out of GPR and FPR range.
122 :
123 : // A special value used to indicate that a register field is not used.
124 : // This is specially chosen to ensure that bitmask() == 0, so it can be added
125 : // to any RegisterList with no effect.
126 0 : static Register None() { return Register(kNone); }
127 :
128 : // The conditions (i.e. APSR N, Z, C, and V) are collectively modeled as
129 : // a single register, out of the usual ARM GPR range.
130 : // These bits of the APSR register are separately tracked, so we can
131 : // test when any of the 4 bits (and hence conditional execution) is
132 : // affected. If you need to track other bits in the APSR, add them as
133 : // a separate register.
134 0 : static Register Conditions() { return Register(kConditions); }
135 :
136 : // Registers with special meaning in our model:
137 0 : static Register Tp() { return Register(kTp); }
138 0 : static Register Sp() { return Register(kSp); }
139 0 : static Register Lr() { return Register(kLr); }
140 0 : static Register Pc() { return Register(kPc); }
141 :
142 : private:
143 : Number number_;
144 : Register& operator=(const Register& r); // Disallow assignment.
145 : };
146 :
147 :
148 : // A collection of Registers. Used to describe the side effects of operations.
149 : //
150 : // Note that this is technically a set, not a list -- but RegisterSet is a
151 : // well-known term that means something else.
152 : class RegisterList {
153 : public:
154 : // Defines an empty register list.
155 0 : RegisterList() : bits_(0) {}
156 :
157 : // Produces a RegisterList that contains the registers specified in the
158 : // given bitmask. To indicate rN, the bitmask must include (1 << N).
159 0 : explicit RegisterList(Register::Mask bitmask) : bits_(bitmask) {}
160 :
161 0 : RegisterList(const RegisterList& other) : bits_(other.bits_) {}
162 :
163 : // Produces a RegisterList containing a single register.
164 0 : explicit RegisterList(const Register& r) : bits_(r.BitMask()) {}
165 :
166 : // Checks whether this list contains the given register.
167 0 : bool Contains(const Register& r) const {
168 0 : return bits_ & r.BitMask();
169 0 : }
170 :
171 : // Checks whether this list contains all the registers in the operand.
172 0 : bool ContainsAll(const RegisterList& other) const {
173 0 : return (bits_ & other.bits_) == other.bits_;
174 0 : }
175 :
176 : // Checks whether this list contains any of the registers in the operand.
177 0 : bool ContainsAny(const RegisterList& other) const {
178 0 : return bits_ & other.bits_;
179 0 : }
180 :
181 : // Returns true if the two register lists are identical.
182 : bool Equals(const RegisterList& other) const {
183 : return bits_ == other.bits_;
184 : }
185 :
186 : // Adds a register to the register list.
187 0 : RegisterList& Add(const Register& r) {
188 0 : bits_ |= r.BitMask();
189 0 : return *this;
190 0 : }
191 :
192 : // Removes a register from the register list.
193 : RegisterList& Remove(const Register& r) {
194 : bits_ &= ~r.BitMask();
195 : return *this;
196 : }
197 :
198 : // Unions this given register list into this.
199 0 : RegisterList& Union(const RegisterList& other) {
200 0 : bits_ |= other.bits_;
201 0 : return *this;
202 0 : }
203 :
204 : // Intersects the given register list into this.
205 0 : RegisterList& Intersect(const RegisterList& other) {
206 0 : bits_ &= other.bits_;
207 0 : return *this;
208 0 : }
209 :
210 : // Copies the other register list into this.
211 0 : RegisterList& Copy(const RegisterList& other) {
212 0 : bits_ = other.bits_;
213 0 : return *this;
214 0 : }
215 :
216 : // Returns the bits defined in the register list.
217 : Register::Mask bits() const {
218 : return bits_;
219 : }
220 :
221 : // Number of ARM GPRs in the list.
222 0 : uint32_t numGPRs() const {
223 0 : uint16_t gprs = bits_ & Register::kGprMask;
224 0 : return nacl::PopCount(gprs);
225 0 : }
226 :
227 : // Returns the smallest GPR register in the list.
228 : Register::Number SmallestGPR() const;
229 :
230 : // A list containing every possible register, even some we don't define.
231 : // Used exclusively as a bogus scary return value for forbidden instructions.
232 0 : static RegisterList Everything() { return RegisterList(-1); }
233 :
234 : // A special register list to communicate registers that can't be changed
235 : // when doing dynamic code replacement.
236 0 : static RegisterList DynCodeReplaceFrozenRegs() {
237 : return RegisterList((1 << Register::kPc) |
238 : (1 << Register::kLr) |
239 : (1 << Register::kSp) |
240 0 : (1 << Register::kTp));
241 0 : }
242 :
243 : private:
244 : Register::Mask bits_;
245 : RegisterList& operator=(const RegisterList& r); // Disallow assignment.
246 : };
247 :
248 :
249 : // The number of bits in an ARM instruction.
250 : static const int kArm32InstSize = 32;
251 :
252 : // Special ARM instructions for sandboxing.
253 : static const uint32_t kLiteralPoolHead = NACL_INSTR_ARM_LITERAL_POOL_HEAD;
254 : static const uint32_t kBreakpoint = NACL_INSTR_ARM_BREAKPOINT;
255 : static const uint32_t kHaltFill = NACL_INSTR_ARM_HALT_FILL;
256 : static const uint32_t kAbortNow = NACL_INSTR_ARM_ABORT_NOW;
257 : static const uint32_t kFailValidation = NACL_INSTR_ARM_FAIL_VALIDATION;
258 :
259 : // Not-so-special instructions.
260 : static const uint32_t kNop = NACL_INSTR_ARM_NOP;
261 :
262 : // Models a 32-bit ARM instruction.
263 : //
264 : // This class is designed for efficiency:
265 : // - Its public methods for bitfield extraction are short and inline.
266 : // - It has no vtable, so on 32-bit platforms it's exactly the size of the
267 : // instruction it models.
268 : class Instruction {
269 : public:
270 : Instruction() : bits_(0) {}
271 :
272 0 : Instruction(const Instruction& inst) : bits_(inst.bits_) {}
273 :
274 : // Creates an a 32-bit ARM instruction.
275 0 : explicit Instruction(uint32_t bits) : bits_(bits) {}
276 :
277 : // Returns the entire sequence of bits defined by an instruction.
278 0 : uint32_t Bits() const {
279 0 : return bits_;
280 0 : }
281 :
282 : // Mask for the lowest bits.
283 0 : static uint32_t LowestBitsMask(int bit_count) {
284 0 : return (~(uint32_t)0) >> (32 - bit_count);
285 0 : }
286 :
287 : // Extracts a range of contiguous bits, right-justifies it, and returns it.
288 : // Note that the range follows hardware convention, with the high bit first.
289 0 : uint32_t Bits(int hi, int lo) const {
290 : // When both arguments are constant (the usual case), this can be inlined
291 : // as
292 : // ubfx r0, r0, #hi, #(hi+1-lo)
293 : //
294 : // Curiously, even at aggressive optimization levels, GCC 4.3.2 generates a
295 : // less-efficient sequence of ands, bics, and shifts.
296 : //
297 : // TODO(jfb) Validate and fix this: this function is called very often and
298 : // could speed up validation quite a bit.
299 0 : uint32_t right_justified = bits_ >> lo;
300 0 : int bit_count = hi - lo + 1;
301 0 : return right_justified & LowestBitsMask(bit_count);
302 0 : }
303 :
304 : // Changes the range of contiguous bits, with the given value.
305 : // Note: Assumes the value fits, if not, it is truncated.
306 0 : void SetBits(int hi, int lo, uint32_t value) {
307 : // TODO(jfb) Same as the above function, this should generate a BFI
308 : // when hi and lo are compile-time constants.
309 : //
310 : // Compute bit mask for range of bits.
311 0 : int bit_count = hi - lo + 1;
312 0 : uint32_t clear_mask = LowestBitsMask(bit_count);
313 : // Remove from the value any bits out of range, then shift to location
314 : // to add.
315 0 : value = (value & clear_mask) << lo;
316 : // Shift mask to corresponding position and replace bits with value.
317 0 : clear_mask = ~(clear_mask << lo);
318 0 : bits_ = (bits_ & clear_mask) | value;
319 0 : }
320 :
321 : // A convenience method for converting bits to a register.
322 : const Register Reg(int hi, int lo) const {
323 : return Register(Bits(hi, lo));
324 : }
325 :
326 : // Extracts a single bit (0 - 31).
327 : bool Bit(int index) const {
328 : return (bits_ >> index) & 1;
329 : }
330 :
331 : // Sets the specified bit to the specified value for an ARM instruction.
332 : void SetBit(int index, bool value) {
333 : uint32_t mask = (1 << index);
334 : if (value) {
335 : // Set to 1
336 : bits_ |= mask;
337 : } else {
338 : // Set to 0
339 : bits_ &= ~mask;
340 : }
341 : }
342 :
343 : // Possible values for the condition field, from the ARM ARM section A8.3.
344 : // Conditional execution is determined by the APSR's condition flags: NZCV.
345 : enum Condition {
346 : EQ = 0x0, // Equal | Z == 1
347 : NE = 0x1, // Not equal | Z == 0
348 : CS = 0x2, // Carry set | C == 1
349 : CC = 0x3, // Carry clear | C == 0
350 : MI = 0x4, // Minus, negative | N == 1
351 : PL = 0x5, // Plus, positive or zero | N == 0
352 : VS = 0x6, // Overflow | V == 1
353 : VC = 0x7, // No overflow | V == 0
354 : HI = 0x8, // Unsigned higher | C == 1 && Z == 0
355 : LS = 0x9, // Unsigned lower or same | C == 0 || Z == 1
356 : GE = 0xA, // Signed greater than or equal | N == V
357 : LT = 0xB, // Signed less than | N != V
358 : GT = 0xC, // Signed greater than | Z == 0 && N == V
359 : LE = 0xD, // Signed less than or equal | Z == 1 || N != V
360 : AL = 0xE, // Always (unconditional) | Any
361 : UNCONDITIONAL = 0xF, // Equivalent to AL -- converted in our API
362 : // Aliases:
363 : HS = CS, // Unsigned higher or same
364 : LO = CC // Unsigned lower
365 : };
366 :
367 : // Defines the size of enumerated type Condition, minus
368 : // UNCONDITIONAL (assuming one uses GetCondition() to get the
369 : // condition of an instruction).
370 : static const size_t kConditionSize = 15;
371 :
372 : static const char* ToString(Condition cond);
373 :
374 : static Condition Next(Condition cond) {
375 : return static_cast<Condition>(static_cast<int>(cond) + 1);
376 : }
377 :
378 : // Extracts the condition field. UNCONDITIONAL is converted to AL -- in the
379 : // event that you need to distinguish, (1) make sure that's really true and
380 : // then (2) explicitly extract bits(31,28).
381 0 : Condition GetCondition() const {
382 0 : Instruction::Condition cc = Instruction::Condition(Bits(31, 28));
383 0 : if (cc == Instruction::UNCONDITIONAL) {
384 0 : return Instruction::AL;
385 : }
386 0 : return cc;
387 0 : }
388 :
389 : // Returns true if this and the given instruction are equal.
390 0 : bool Equals(const Instruction& inst) const {
391 0 : return bits_ == inst.bits_;
392 0 : }
393 :
394 : // Copies insn into this.
395 0 : Instruction& Copy(const Instruction& insn) {
396 0 : bits_ = insn.bits_;
397 0 : return *this;
398 0 : }
399 :
400 : private:
401 : uint32_t bits_;
402 : Instruction& operator=(const Instruction& insn); // Disallow assignment.
403 : };
404 :
405 : // Checks if instruction is a valid constant pool head.
406 0 : inline bool IsBreakPointAndConstantPoolHead(Instruction i) {
407 : return ((i.Bits(31, 0) == kLiteralPoolHead) ||
408 0 : (i.Bits(31, 0) == kBreakpoint));
409 0 : }
410 :
411 : // Same as above, but with integer contents of instruction as argument.
412 0 : inline bool IsBreakPointAndConstantPoolHead(uint32_t i) {
413 0 : return IsBreakPointAndConstantPoolHead(Instruction(i));
414 0 : }
415 :
416 : } // namespace nacl_arm_dec
417 :
418 : #endif // NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_ARM_V2_MODEL_H
|