OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2009 The Native Client Authors. All rights reserved. | 2 * Copyright 2011 The Native Client Authors. All rights reserved. |
3 * Use of this source code is governed by a BSD-style license that can | 3 * Use of this source code is governed by a BSD-style license that can |
4 * be found in the LICENSE file. | 4 * be found in the LICENSE file. |
5 * Copyright 2009, Google Inc. | 5 * Copyright 2011, Google Inc. |
6 */ | 6 */ |
7 | 7 |
8 #ifndef NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_ARM_V2_VALIDATOR_H | 8 #ifndef NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_ARM_V2_VALIDATOR_H |
9 #define NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_ARM_V2_VALIDATOR_H | 9 #define NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_ARM_V2_VALIDATOR_H |
10 | 10 |
11 /* | 11 /* |
| 12 * MRM DEBUG Header, clean this out |
| 13 */ |
| 14 #include <stdio.h> |
| 15 |
| 16 /* |
12 * The SFI validator, and some utility classes it uses. | 17 * The SFI validator, and some utility classes it uses. |
13 */ | 18 */ |
14 | 19 |
15 #include <stdint.h> | 20 #include <stdint.h> |
16 #include <stdlib.h> | 21 #include <stdlib.h> |
17 #include <vector> | 22 #include <vector> |
18 | 23 |
19 #include "native_client/src/include/nacl_string.h" | 24 #include "native_client/src/include/nacl_string.h" |
20 #include "native_client/src/trusted/validator_arm/address_set.h" | 25 #include "native_client/src/trusted/validator_arm/address_set.h" |
21 #include "native_client/src/trusted/validator_arm/decode.h" | 26 #include "native_client/src/trusted/validator_arm/decode.h" |
(...skipping 22 matching lines...) Expand all Loading... |
44 Bundle(uint32_t virtual_base, uint32_t size_bytes) | 49 Bundle(uint32_t virtual_base, uint32_t size_bytes) |
45 : virtual_base_(virtual_base), size_(size_bytes) {} | 50 : virtual_base_(virtual_base), size_(size_bytes) {} |
46 | 51 |
47 uint32_t begin_addr() const { return virtual_base_; } | 52 uint32_t begin_addr() const { return virtual_base_; } |
48 uint32_t end_addr() const { return virtual_base_ + size_; } | 53 uint32_t end_addr() const { return virtual_base_ + size_; } |
49 | 54 |
50 bool operator!=(const Bundle &other) const { | 55 bool operator!=(const Bundle &other) const { |
51 // Note that all Bundles are currently assumed to be the same size. | 56 // Note that all Bundles are currently assumed to be the same size. |
52 return virtual_base_ != other.virtual_base_; | 57 return virtual_base_ != other.virtual_base_; |
53 } | 58 } |
| 59 bool operator==(const Bundle &other) const { |
| 60 return virtual_base_ == other.virtual_base_; |
| 61 } |
54 | 62 |
55 private: | 63 private: |
56 uint32_t virtual_base_; | 64 uint32_t virtual_base_; |
57 uint32_t size_; | 65 uint32_t size_; |
58 }; | 66 }; |
59 | 67 |
| 68 class SfiValidator; |
| 69 |
| 70 // A possible result from a validator pattern. |
| 71 enum PatternMatchMode { |
| 72 // The pattern does not apply to the instructions it was given. |
| 73 NO_MATCH_MODE, |
| 74 // The pattern matches, and is safe; do not allow jumps to split it. |
| 75 PATTERN_SAFE_MODE, |
| 76 // The pattern matches, and has detected a problem. |
| 77 PATTERN_UNSAFE_MODE |
| 78 }; |
| 79 |
| 80 // Full result from a pattern. Describes whether it matched, and if it did, |
| 81 // specifies how long the matching pattern was. |
| 82 typedef struct { |
| 83 PatternMatchMode pm_mode; |
| 84 int8_t size; |
| 85 } PatternMatch; |
| 86 |
| 87 /* Pattern matching type */ |
| 88 typedef PatternMatch (*Pattern)(const SfiValidator &, |
| 89 DecodedInstruction insns[], |
| 90 ProblemSink *out); |
60 | 91 |
61 /* | 92 /* |
62 * The SFI validator itself. The validator is controlled by the following | 93 * The SFI validator itself. The validator is controlled by the following |
63 * inputs: | 94 * inputs: |
64 * bytes_per_bundle: the number of bytes in each bundle of instructions. | 95 * bytes_per_bundle: the number of bytes in each bundle of instructions. |
65 * Currently this tends to be 16, but we've evaluated alternatives. | 96 * Currently this tends to be 16, but we've evaluated alternatives. |
66 * code_region_bytes: number of bytes in the code region, starting at address | 97 * code_region_bytes: number of bytes in the code region, starting at address |
67 * 0 and including the trampolines, etc. Must be a power of two. | 98 * 0 and including the trampolines, etc. Must be a power of two. |
68 * data_region_bits: number of bytes in the data region, starting at address | 99 * data_region_bits: number of bytes in the data region, starting at address |
69 * 0 and including the code region. Must be a power of two. | 100 * 0 and including the code region. Must be a power of two. |
70 * read_only_registers: registers that untrusted code must not alter (but may | 101 * read_only_registers: registers that untrusted code must not alter (but may |
71 * read). This currently applies to r9, where we store some thread state. | 102 * read). This currently applies to r9, where we store some thread state. |
72 * data_address_registers: registers that must contain a valid data-region | 103 * data_address_registers: registers that must contain a valid data-region |
73 * address at all times. This currently applies to the stack pointer, but | 104 * address at all times. This currently applies to the stack pointer, but |
74 * could be extended to include a frame pointer for C-like languages. | 105 * could be extended to include a frame pointer for C-like languages. |
75 * | 106 * |
76 * The values of these inputs will typically be taken from the headers of | 107 * The values of these inputs will typically be taken from the headers of |
77 * untrusted code -- either by the ABI version they indicate, or (perhaps in | 108 * untrusted code -- either by the ABI version they indicate, or (perhaps in |
78 * the future) explicit indicators of what SFI model they follow. | 109 * the future) explicit indicators of what SFI model they follow. |
79 */ | 110 */ |
80 class SfiValidator { | 111 class SfiValidator { |
81 public: | 112 public: |
82 SfiValidator(uint32_t bytes_per_bundle, | 113 SfiValidator(uint32_t bytes_per_bundle, |
83 uint32_t code_region_bytes, | 114 uint32_t code_region_bytes, |
84 uint32_t data_region_bytes, | 115 uint32_t data_region_bytes, |
85 nacl_arm_dec::RegisterList read_only_registers, | 116 nacl_arm_dec::RegisterList read_only_registers, |
86 nacl_arm_dec::RegisterList data_address_registers); | 117 nacl_arm_dec::RegisterList data_address_registers, |
| 118 bool thumb); |
87 | 119 |
88 /* | 120 /* |
89 * The main validator entry point. Validates the provided CodeSegments, | 121 * The main validator entry point. Validates the provided CodeSegments, |
90 * which must be in sorted order, reporting any problems through the | 122 * which must be in sorted order, reporting any problems through the |
91 * ProblemSink. | 123 * ProblemSink. |
92 * | 124 * |
93 * Returns true iff no problems were found. | 125 * Returns true iff no problems were found. |
94 */ | 126 */ |
95 bool validate(const std::vector<CodeSegment> &, ProblemSink *out); | 127 bool validate(const std::vector<CodeSegment> &, ProblemSink *out); |
96 | 128 |
97 /* | 129 /* |
98 * Checks whether the given Register always holds a valid data region address. | 130 * Checks whether the given Register always holds a valid data region address. |
99 * This implies that the register is safe to use in unguarded stores. | 131 * This implies that the register is safe to use in unguarded stores. |
100 */ | 132 */ |
101 bool is_data_address_register(nacl_arm_dec::Register) const; | 133 bool is_data_address_register(nacl_arm_dec::Register) const; |
102 | 134 |
103 uint32_t data_address_mask() const { return data_address_mask_; } | 135 uint32_t data_address_mask() const { return data_address_mask_; } |
104 uint32_t code_address_mask() const { return code_address_mask_; } | 136 uint32_t code_address_mask() const { return code_address_mask_; } |
| 137 uint32_t code_address_ormask() const { return code_address_ormask_; } |
105 | 138 |
106 nacl_arm_dec::RegisterList read_only_registers() const { | 139 nacl_arm_dec::RegisterList read_only_registers() const { |
107 return read_only_registers_; | 140 return read_only_registers_; |
108 } | 141 } |
109 nacl_arm_dec::RegisterList data_address_registers() const { | 142 nacl_arm_dec::RegisterList data_address_registers() const { |
110 return data_address_registers_; | 143 return data_address_registers_; |
111 } | 144 } |
112 | 145 |
113 // Returns the Bundle containing a given address. | 146 // Returns the Bundle containing a given address. |
114 const Bundle bundle_for_address(uint32_t) const; | 147 const Bundle bundle_for_address(uint32_t) const; |
115 | 148 |
116 /* | 149 /* |
117 * Change masks: this is useful for debugging and cannot be completely | 150 * Change masks: this is useful for debugging and cannot be completely |
118 * controlled with constructor arguments | 151 * controlled with constructor arguments |
119 */ | 152 */ |
120 void change_masks(uint32_t code_address_mask, uint32_t data_address_mask) { | 153 void change_masks(uint32_t code_address_mask, |
121 code_address_mask_ = code_address_mask; | 154 uint32_t code_address_ormask, |
122 data_address_mask_ = data_address_mask; | 155 uint32_t data_address_mask) { |
| 156 code_address_mask_ = code_address_mask; |
| 157 code_address_ormask_ = code_address_ormask; |
| 158 data_address_mask_ = data_address_mask; |
123 } | 159 } |
124 | 160 |
125 private: | 161 private: |
126 bool is_bundle_head(uint32_t address) const; | 162 bool is_bundle_head(uint32_t address) const; |
127 | 163 |
128 /* | 164 /* |
129 * Validates a straight-line execution of the code, applying patterns. This | 165 * Validates a straight-line execution of the code, applying patterns. This |
130 * is the first validation pass, which fills out the AddressSets for | 166 * is the first validation pass, which fills out the AddressSets for |
131 * consumption by later analyses. | 167 * consumption by later analyses. |
132 * branches: gets filled in with the address of every direct branch. | 168 * branches: gets filled in with the address of every direct branch. |
133 * critical: gets filled in with every address that isn't safe to jump to, | 169 * critical: gets filled in with every address that isn't safe to jump to, |
134 * because it would split an otherwise-safe pseudo-op. | 170 * because it would split an otherwise-safe pseudo-op. |
135 * | 171 * |
136 * Returns true iff no problems were found. | 172 * Returns true iff no problems were found. |
137 */ | 173 */ |
138 bool validate_fallthrough(const CodeSegment &, ProblemSink *, | 174 bool validate_fallthrough(const CodeSegment &, ProblemSink *, |
139 AddressSet *branches, AddressSet *critical); | 175 AddressSet *branches, AddressSet *critical); |
140 | 176 |
141 /* | 177 /* |
142 * Factor of validate_fallthrough, above. Checks a single instruction using | |
143 * the instruction patterns defined in the .cc file, with two possible | |
144 * results: | |
145 * 1. No patterns matched, or all were safe: nothing happens. | |
146 * 2. Patterns matched and were unsafe: problems get sent to 'out'. | |
147 */ | |
148 bool apply_patterns(const DecodedInstruction &, ProblemSink *out); | |
149 | |
150 /* | |
151 * Factor of validate_fallthrough, above. Checks a pair of instructions using | 178 * Factor of validate_fallthrough, above. Checks a pair of instructions using |
152 * the instruction patterns defined in the .cc file, with three possible | 179 * the instruction patterns defined in the .cc file, with three possible |
153 * results: | 180 * results: |
154 * 1. No patterns matched: nothing happens. | 181 * 1. No patterns matched: nothing happens. |
155 * 2. Patterns matched and were safe: the addresses are filled into | 182 * 2. Patterns matched and were safe: the addresses are filled into |
156 * 'critical' for use by the second pass. | 183 * 'critical' for use by the second pass. |
157 * 3. Patterns matched and were unsafe: problems get sent to 'out'. | 184 * 3. Patterns matched and were unsafe: problems get sent to 'out'. |
158 */ | 185 */ |
159 bool apply_patterns(const DecodedInstruction &first, | 186 bool apply_patterns(DecodedInstruction insns[], |
160 const DecodedInstruction &second, AddressSet *critical, ProblemSink *out); | 187 const Pattern patterns[], unsigned int nPatterns, |
| 188 AddressSet *critical, ProblemSink *out); |
161 | 189 |
162 /* | 190 /* |
163 * Validates all branches found by a previous pass, checking destinations. | 191 * Validates all branches found by a previous pass, checking destinations. |
164 * Returns true iff no problems were found. | 192 * Returns true iff no problems were found. |
165 */ | 193 */ |
166 bool validate_branches(const std::vector<CodeSegment> &, | 194 bool validate_branches(const std::vector<CodeSegment> &, |
167 const AddressSet &branches, const AddressSet &critical, | 195 const AddressSet &branches, const AddressSet &critical, |
168 ProblemSink *); | 196 ProblemSink *); |
169 | 197 |
170 | 198 |
171 uint32_t bytes_per_bundle_; | 199 uint32_t bytes_per_bundle_; |
172 uint32_t data_address_mask_; | 200 uint32_t data_address_mask_; |
173 uint32_t code_address_mask_; | 201 uint32_t code_address_mask_; |
| 202 uint32_t code_address_ormask_; |
174 uint32_t code_region_bytes_; | 203 uint32_t code_region_bytes_; |
175 // Registers which cannot be modified by untrusted code. | 204 // Registers which cannot be modified by untrusted code. |
176 nacl_arm_dec::RegisterList read_only_registers_; | 205 nacl_arm_dec::RegisterList read_only_registers_; |
177 // Registers which must always contain a valid data region address. | 206 // Registers which must always contain a valid data region address. |
178 nacl_arm_dec::RegisterList data_address_registers_; | 207 nacl_arm_dec::RegisterList data_address_registers_; |
| 208 // thumb_ is always either 1 or 0 |
| 209 uint32_t thumb_; |
179 const nacl_arm_dec::DecoderState *decode_state_; | 210 const nacl_arm_dec::DecoderState *decode_state_; |
180 }; | 211 }; |
181 | 212 |
| 213 /* |
| 214 * Defines the maximal pattern size to be made available to the pattern |
| 215 * matcher. |
| 216 * I know 5 seems a little big, but it is required for the IT matcher. |
| 217 * 16 is a hack, it is a magic number to make sure that the second pattern |
| 218 * matching phase interacts properly with breakpoint. |
| 219 */ |
| 220 const uint8_t kMaxPattern = 5; |
182 | 221 |
183 /* | 222 /* |
184 * A facade that combines an Instruction with its address and a ClassDecoder. | 223 * A facade that combines an Instruction with its address and a ClassDecoder. |
185 * This makes the patterns substantially easier to write and read than managing | 224 * This makes the patterns substantially easier to write and read than managing |
186 * all three variables separately. | 225 * all three variables separately. |
187 * | 226 * |
188 * ClassDecoders do all decoding on-demand, with no caching. DecodedInstruction | 227 * ClassDecoders do all decoding on-demand, with no caching. DecodedInstruction |
189 * has knowledge of the validator, and pairs a ClassDecoder with a constant | 228 * has knowledge of the validator, and pairs a ClassDecoder with a constant |
190 * Instruction -- so it can cache commonly used values, and does. Caching | 229 * Instruction -- so it can cache commonly used values, and does. Caching |
191 * safety and defs doubles validator performance. Add other values only | 230 * safety and defs doubles validator performance. Add other values only |
192 * under guidance of a profiler. | 231 * under guidance of a profiler. |
193 */ | 232 */ |
194 class DecodedInstruction { | 233 class DecodedInstruction { |
195 public: | 234 public: |
196 DecodedInstruction(uint32_t vaddr, nacl_arm_dec::Instruction inst, | 235 DecodedInstruction(uint32_t vaddr, nacl_arm_dec::Instruction inst, |
197 const nacl_arm_dec::ClassDecoder &decoder); | 236 const nacl_arm_dec::ClassDecoder &decoder); |
198 // We permit the default copy ctor and assignment operator. | 237 // We permit the default copy ctor and assignment operator. |
199 | 238 |
200 uint32_t addr() const { return vaddr_; } | 239 uint32_t addr() const { return vaddr_; } |
201 | 240 |
202 /* | 241 /* |
203 * Checks that 'this' always precedes 'other' -- meaning that if 'other' | 242 * Checks that 'this' always precedes 'other' -- meaning that if 'other' |
204 * executes, 'this' is guaranteed to have executed. This is important if | 243 * executes, 'this' is guaranteed to have executed. This is important if |
205 * 'this' produces a sandboxed value that 'other' must consume. | 244 * 'this' produces a sandboxed value that 'other' must consume. |
206 * | 245 * |
207 * Note that this function can't see the bundle size, so this result does not | 246 * Note that this function can't see the bundle size, so this result does not |
208 * take it into account. The SfiValidator reasons on this separately. | 247 * take it into account. The SfiValidator reasons on this separately. |
209 */ | 248 */ |
210 bool always_precedes(const DecodedInstruction &other) const { | 249 bool always_precedes(const DecodedInstruction &other) const { |
211 return inst_.condition() == other.inst_.condition(); | 250 return condition() == other.condition(); |
212 } | 251 } |
213 | 252 // TODO(jasonwkim) These predicates will all be able to lie |
| 253 // without an IT predicator |
214 /* | 254 /* |
215 * Checks that 'this' always follows 'other' -- meaning that if 'other' | 255 * Checks that 'this' always follows 'other' -- meaning that if 'other' |
216 * executes, 'this' is guaranteed to follow. This is important if 'other' | 256 * executes, 'this' is guaranteed to follow. This is important if 'other' |
217 * produces an unsafe value that 'this' fixes before it can leak out. | 257 * produces an unsafe value that 'this' fixes before it can leak out. |
218 * | 258 * |
219 * Note that this function can't see the bundle size, so this result does not | 259 * Note that this function can't see the bundle size, so this result does not |
220 * take it into account. The SfiValidator reasons on this separately. | 260 * take it into account. The SfiValidator reasons on this separately. |
221 */ | 261 */ |
222 bool always_follows(const DecodedInstruction &other) const { | 262 bool always_follows(const DecodedInstruction &other) const { |
223 return inst_.condition() == other.inst_.condition() | 263 return condition() == condition() |
224 && !other.defines(nacl_arm_dec::kRegisterFlags); | 264 && !other.defines(nacl_arm_dec::kRegisterFlags); |
225 } | 265 } |
226 | 266 |
227 /* | 267 /* |
228 * Checks that the execution of 'this' is conditional on the test result | 268 * Checks that the execution of 'this' is conditional on the test result |
229 * (specifically, the Z flag being set) from 'other' -- which must be | 269 * (specifically, the Z flag being set) from 'other' -- which must be |
230 * adjacent for this simple check to be meaningful. | 270 * adjacent for this simple check to be meaningful. |
231 */ | 271 */ |
232 bool is_conditional_on(const DecodedInstruction &other) const { | 272 bool is_conditional_on(const DecodedInstruction &other) const { |
233 return inst_.condition() == nacl_arm_dec::Instruction::EQ | 273 return condition() == nacl_arm_dec::Instruction::EQ |
234 && other.inst_.condition() == nacl_arm_dec::Instruction::AL | 274 && other.condition() == nacl_arm_dec::Instruction::AL |
235 && other.defines(nacl_arm_dec::kRegisterFlags); | 275 && other.defines(nacl_arm_dec::kRegisterFlags); |
236 } | 276 } |
237 | 277 |
238 // The methods below mirror those on ClassDecoder, but are cached and cheap. | 278 // The methods below mirror those on ClassDecoder, but are cached and cheap. |
239 nacl_arm_dec::SafetyLevel safety() const { return safety_; } | 279 nacl_arm_dec::SafetyLevel safety() const { return safety_; } |
240 nacl_arm_dec::RegisterList defs() const { return defs_; } | 280 nacl_arm_dec::RegisterList defs() const { return defs_; } |
241 | 281 |
| 282 /* Passes through queries about the it status */ |
| 283 nacl_arm_dec::ITCond it() const { |
| 284 return decoder_->it_sequence(inst_); |
| 285 } |
| 286 |
| 287 /* Passes through queries about it safety */ |
| 288 nacl_arm_dec::ITSafety it_safe() const { |
| 289 return decoder_->it_safe(inst_); |
| 290 } |
| 291 |
| 292 // Calculates the size of the current instruction. It is here instead of |
| 293 // ClassDecoder because it needs the vaddr. |
| 294 nacl_arm_dec::Instruction::Condition condition() const { |
| 295 if (vaddr_ & 1) { |
| 296 if (condition_ != nacl_arm_dec::Instruction::UNCONDITIONAL) |
| 297 return condition_; |
| 298 return decoder_->condition(inst_); |
| 299 } else { |
| 300 return inst_.condition(); |
| 301 } |
| 302 } |
| 303 uint8_t size() const { |
| 304 if (vaddr_ & 1) { |
| 305 switch (inst_.bits(15, 11)) { |
| 306 case 0x1D: // 0b11101 |
| 307 case 0x1E: // 0b11110 |
| 308 case 0x1F: return 4; // 0b11111 |
| 309 default: return 2; |
| 310 } |
| 311 } else { |
| 312 return 4; |
| 313 } |
| 314 } |
| 315 |
242 // The methods below pull values from ClassDecoder on demand. | 316 // The methods below pull values from ClassDecoder on demand. |
243 bool is_relative_branch() const { | 317 bool is_relative_branch() const { |
244 return decoder_->is_relative_branch(inst_); | 318 return decoder_->is_relative_branch(inst_); |
245 } | 319 } |
246 | 320 |
247 const nacl_arm_dec::Register branch_target_register() const { | 321 const nacl_arm_dec::Register branch_target_register() const { |
248 return decoder_->branch_target_register(inst_); | 322 return decoder_->branch_target_register(inst_); |
249 } | 323 } |
250 | 324 |
251 bool is_literal_pool_head() const { | 325 bool is_literal_pool_head() const { |
252 return decoder_->is_literal_pool_head(inst_); | 326 return decoder_->is_literal_pool_head(inst_); |
253 } | 327 } |
254 | 328 |
255 uint32_t branch_target() const { | 329 uint32_t branch_target() const { |
256 return vaddr_ + decoder_->branch_target_offset(inst_); | 330 return vaddr_ + decoder_->branch_target_offset(inst_); |
257 } | 331 } |
258 | 332 |
259 const nacl_arm_dec::Register base_address_register() const { | 333 const nacl_arm_dec::Register base_address_register() const { |
260 return decoder_->base_address_register(inst_); | 334 return decoder_->base_address_register(inst_); |
261 } | 335 } |
262 | 336 |
| 337 bool sets_bits(uint32_t mask) const { |
| 338 return decoder_->sets_bits(inst_, mask); |
| 339 } |
| 340 |
263 bool clears_bits(uint32_t mask) const { | 341 bool clears_bits(uint32_t mask) const { |
264 return decoder_->clears_bits(inst_, mask); | 342 return decoder_->clears_bits(inst_, mask); |
265 } | 343 } |
266 | 344 |
267 bool sets_Z_if_bits_clear(nacl_arm_dec::Register r, uint32_t mask) const { | 345 bool sets_Z_if_bits_clear(nacl_arm_dec::Register r, uint32_t mask) const { |
268 return decoder_->sets_Z_if_bits_clear(inst_, r, mask); | 346 return decoder_->sets_Z_if_bits_clear(inst_, r, mask); |
269 } | 347 } |
270 | 348 |
271 nacl_arm_dec::RegisterList immediate_addressing_defs() const { | 349 nacl_arm_dec::RegisterList immediate_addressing_defs() const { |
272 return decoder_->immediate_addressing_defs(inst_); | 350 return decoder_->immediate_addressing_defs(inst_); |
273 } | 351 } |
274 | 352 |
275 // Some convenience methods, defined in terms of ClassDecoder: | 353 // Some convenience methods, defined in terms of ClassDecoder: |
276 bool defines(nacl_arm_dec::Register r) const { | 354 bool defines(nacl_arm_dec::Register r) const { |
277 return defs().contains_all(r); | 355 return defs().contains_all(r); |
278 } | 356 } |
279 | 357 |
280 bool defines_any(nacl_arm_dec::RegisterList rl) const { | 358 bool defines_any(nacl_arm_dec::RegisterList rl) const { |
281 return defs().contains_any(rl); | 359 return defs().contains_any(rl); |
282 } | 360 } |
283 | 361 |
284 bool defines_all(nacl_arm_dec::RegisterList rl) const { | 362 bool defines_all(nacl_arm_dec::RegisterList rl) const { |
285 return defs().contains_all(rl); | 363 return defs().contains_all(rl); |
286 } | 364 } |
287 | 365 |
| 366 /* |
| 367 * Overrides the conditional for this insn, if thumb mode is active. |
| 368 * It should be used only once on any given insn, as it should originate |
| 369 * only from within an IT block, and IT blocks must not overlap. |
| 370 */ |
| 371 void set_condition(nacl_arm_dec::Instruction::Condition condition) { |
| 372 condition_ = condition; |
| 373 } |
| 374 |
288 private: | 375 private: |
289 uint32_t vaddr_; | 376 uint32_t vaddr_; |
290 nacl_arm_dec::Instruction inst_; | 377 nacl_arm_dec::Instruction inst_; |
291 const nacl_arm_dec::ClassDecoder *decoder_; | 378 const nacl_arm_dec::ClassDecoder *decoder_; |
292 | 379 |
293 nacl_arm_dec::SafetyLevel safety_; | 380 nacl_arm_dec::SafetyLevel safety_; |
294 nacl_arm_dec::RegisterList defs_; | 381 nacl_arm_dec::RegisterList defs_; |
| 382 nacl_arm_dec::Instruction::Condition condition_; |
295 }; | 383 }; |
296 | 384 |
297 | 385 |
298 /* | 386 /* |
299 * Describes a memory region that contains executable code. Note that the code | 387 * Describes a memory region that contains executable code. Note that the code |
300 * need not live in its final location -- we pretend the code lives at the | 388 * need not live in its final location -- we pretend the code lives at the |
301 * provided start_addr, regardless of where the base pointer actually points. | 389 * provided start_addr, regardless of where the base pointer actually points. |
302 */ | 390 */ |
303 class CodeSegment { | 391 class CodeSegment { |
304 public: | 392 public: |
305 CodeSegment(const uint8_t *base, uint32_t start_addr, size_t size) | 393 CodeSegment(const uint8_t *base, uint32_t start_addr, size_t size) |
306 : base_(base), start_addr_(start_addr), size_(size) {} | 394 : base_(base), start_addr_(start_addr), size_(size) {} |
307 | 395 |
308 uint32_t begin_addr() const { return start_addr_; } | 396 uint32_t begin_addr() const { return start_addr_; } |
309 uint32_t end_addr() const { return start_addr_ + size_; } | 397 uint32_t end_addr() const { return start_addr_ + size_; } |
310 uint32_t size() const { return size_; } | 398 uint32_t size() const { return size_; } |
311 bool contains_address(uint32_t a) const { | 399 bool contains_address(uint32_t a) const { |
312 return (a >= begin_addr()) && (a < end_addr()); | 400 return (a >= begin_addr()) && (a < end_addr()); |
313 } | 401 } |
314 | 402 |
315 const nacl_arm_dec::Instruction operator[](uint32_t address) const { | 403 const nacl_arm_dec::Instruction operator[](uint32_t address) const { |
316 const uint8_t *element = &base_[address - start_addr_]; | 404 const uint8_t *element = &base_[address - start_addr_]; |
317 return nacl_arm_dec::Instruction( | 405 // Special case to allow addresses two from the end to be read |
318 *reinterpret_cast<const uint32_t *>(element)); | 406 if ((address - start_addr_) + 2 < size_) { |
| 407 return nacl_arm_dec::Instruction( |
| 408 *reinterpret_cast<const uint32_t *>(element)); |
| 409 } else if ((address - start_addr_) + 2 == size_) { |
| 410 return nacl_arm_dec::Instruction(((uint32_t) |
| 411 (*reinterpret_cast<const uint16_t *>(element)))); |
| 412 } else { |
| 413 fprintf(stderr, "Out of bounds access to code segment: %x\n", address); |
| 414 exit(1); |
| 415 } |
319 } | 416 } |
320 | 417 |
321 bool operator<(const CodeSegment &other) const { | 418 bool operator<(const CodeSegment &other) const { |
322 return start_addr_ < other.start_addr_; | 419 return start_addr_ < other.start_addr_; |
323 } | 420 } |
324 | 421 |
325 private: | 422 private: |
326 const uint8_t *base_; | 423 const uint8_t *base_; |
327 uint32_t start_addr_; | 424 uint32_t start_addr_; |
328 size_t size_; | 425 size_t size_; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
373 | 470 |
374 /* | 471 /* |
375 * Strings used to describe the current set of validator problems. These may | 472 * Strings used to describe the current set of validator problems. These may |
376 * be worth splitting into a separate header file, so that dev tools can | 473 * be worth splitting into a separate header file, so that dev tools can |
377 * process them into localized messages without needing to pull in the whole | 474 * process them into localized messages without needing to pull in the whole |
378 * validator...we'll see. | 475 * validator...we'll see. |
379 */ | 476 */ |
380 | 477 |
381 // An instruction is unsafe -- more information in the SafetyLevel. | 478 // An instruction is unsafe -- more information in the SafetyLevel. |
382 const char * const kProblemUnsafe = "kProblemUnsafe"; | 479 const char * const kProblemUnsafe = "kProblemUnsafe"; |
| 480 // An instruction runs off the end of a segment |
| 481 const char * const kProblemStraddlesSegment = "kProblemStraddlesSegment"; |
| 482 // An IT instruction is unconditional, meaning the condition is uninvertable. |
| 483 const char * const kProblemUnconditionalIT = "kProblemUnconditionalIT"; |
383 // A branch would break a pseudo-operation pattern. | 484 // A branch would break a pseudo-operation pattern. |
384 const char * const kProblemBranchSplitsPattern = "kProblemBranchSplitsPattern"; | 485 const char * const kProblemBranchSplitsPattern = "kProblemBranchSplitsPattern"; |
385 // A branch targets an invalid code address (out of segment). | 486 // A branch targets an invalid code address (out of segment). |
386 const char * const kProblemBranchInvalidDest = "kProblemBranchInvalidDest"; | 487 const char * const kProblemBranchInvalidDest = "kProblemBranchInvalidDest"; |
387 // A store uses an unsafe (non-masked) base address. | 488 // A store uses an unsafe (non-masked) base address. |
388 const char * const kProblemUnsafeStore = "kProblemUnsafeStore"; | 489 const char * const kProblemUnsafeStore = "kProblemUnsafeStore"; |
389 // A branch uses an unsafe (non-masked) destination address. | 490 // A branch uses an unsafe (non-masked) destination address. |
390 const char * const kProblemUnsafeBranch = "kProblemUnsafeBranch"; | 491 const char * const kProblemUnsafeBranch = "kProblemUnsafeBranch"; |
391 // An instruction updates a data-address register (e.g. SP) without masking. | 492 // An instruction updates a data-address register (e.g. SP) without masking. |
392 const char * const kProblemUnsafeDataWrite = "kProblemUnsafeDataWrite"; | 493 const char * const kProblemUnsafeDataWrite = "kProblemUnsafeDataWrite"; |
393 // An instruction updates a read-only register (e.g. r9). | 494 // An instruction updates a read-only register (e.g. r9). |
394 const char * const kProblemReadOnlyRegister = "kProblemReadOnlyRegister"; | 495 const char * const kProblemReadOnlyRegister = "kProblemReadOnlyRegister"; |
395 // A pseudo-op pattern crosses a bundle boundary. | 496 // A pseudo-op pattern crosses a bundle boundary. |
396 const char * const kProblemPatternCrossesBundle = | 497 const char * const kProblemPatternCrossesBundle = |
397 "kProblemPatternCrossesBundle"; | 498 "kProblemPatternCrossesBundle"; |
398 // A linking branch instruction is not in the last bundle slot. | 499 // A linking branch instruction is not in the last bundle slot. |
399 const char * const kProblemMisalignedCall = "kProblemMisalignedCall"; | 500 const char * const kProblemMisalignedCall = "kProblemMisalignedCall"; |
400 | 501 |
401 } // namespace | 502 } // namespace |
402 | 503 |
403 #endif // NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_ARM_V2_VALIDATOR_H | 504 #endif // NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_ARM_V2_VALIDATOR_H |
OLD | NEW |