| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. |
| 3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 #include "native_client/src/trusted/validator_arm/inst_classes.h" | 7 #include "native_client/src/trusted/validator_arm/inst_classes.h" |
| 8 | 8 |
| 9 /* | 9 /* |
| 10 * Implementations of instruction classes, for those not completely defined in | 10 * Implementations of instruction classes, for those not completely defined in |
| 11 * the header. | 11 * the header. |
| 12 */ | 12 */ |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 208 if (defs(i)[kRegisterPc]) return FORBIDDEN_OPERANDS; | 208 if (defs(i)[kRegisterPc]) return FORBIDDEN_OPERANDS; |
| 209 | 209 |
| 210 return MAY_BE_SAFE; | 210 return MAY_BE_SAFE; |
| 211 } | 211 } |
| 212 | 212 |
| 213 RegisterList AbstractLoad::defs(const Instruction i) const { | 213 RegisterList AbstractLoad::defs(const Instruction i) const { |
| 214 return i.reg(15, 12) + immediate_addressing_defs(i); | 214 return i.reg(15, 12) + immediate_addressing_defs(i); |
| 215 } | 215 } |
| 216 | 216 |
| 217 | 217 |
| 218 SafetyLevel LoadRegister::safety(const Instruction i) const { |
| 219 bool pre_index = i.bit(24); |
| 220 if (pre_index) { |
| 221 // If pre_index is set, the address of the load is computed as the sum |
| 222 // of the two register parameters. We have checked that the first register |
| 223 // is within the sandbox, but this would allow adding an arbitrary value |
| 224 // to it, so it is not safe. |
| 225 return FORBIDDEN; |
| 226 } |
| 227 |
| 228 // Don't let addressing writeback alter PC. |
| 229 if (defs(i)[kRegisterPc]) return FORBIDDEN_OPERANDS; |
| 230 |
| 231 return MAY_BE_SAFE; |
| 232 } |
| 233 |
| 218 RegisterList LoadRegister::defs(const Instruction i) const { | 234 RegisterList LoadRegister::defs(const Instruction i) const { |
| 219 if (writeback(i)) { | 235 if (writeback(i)) { |
| 220 Register rn(i.bits(19, 16)); | 236 Register rn(i.bits(19, 16)); |
| 221 return AbstractLoad::defs(i) + rn; | 237 return AbstractLoad::defs(i) + rn; |
| 222 } else { | 238 } else { |
| 223 return AbstractLoad::defs(i); | 239 return AbstractLoad::defs(i); |
| 224 } | 240 } |
| 225 } | 241 } |
| 226 | 242 |
| 243 Register LoadRegister::base_address_register(const Instruction i) const { |
| 244 return i.reg(19, 16); |
| 245 } |
| 246 |
| 227 | 247 |
| 228 RegisterList LoadImmediate::immediate_addressing_defs(const Instruction i) | 248 RegisterList LoadImmediate::immediate_addressing_defs(const Instruction i) |
| 229 const { | 249 const { |
| 230 if (writeback(i)) { | 250 if (writeback(i)) { |
| 231 Register rn(i.bits(19, 16)); | 251 Register rn(i.bits(19, 16)); |
| 232 return rn; | 252 return rn; |
| 233 } else { | 253 } else { |
| 234 return kRegisterNone; | 254 return kRegisterNone; |
| 235 } | 255 } |
| 236 } | 256 } |
| 237 | 257 |
| 258 Register LoadImmediate::base_address_register(const Instruction i) const { |
| 259 return i.reg(19, 16); |
| 260 } |
| 261 |
| 262 bool LoadImmediate::offset_is_immediate(Instruction i) const { |
| 263 UNREFERENCED_PARAMETER(i); |
| 264 return true; |
| 265 } |
| 266 |
| 238 | 267 |
| 239 RegisterList LoadDoubleI::defs(const Instruction i) const { | 268 RegisterList LoadDoubleI::defs(const Instruction i) const { |
| 240 return LoadImmediate::defs(i) + Register(i.bits(15, 12) + 1); | 269 return LoadImmediate::defs(i) + Register(i.bits(15, 12) + 1); |
| 241 } | 270 } |
| 242 | 271 |
| 272 Register LoadDoubleI::base_address_register(const Instruction i) const { |
| 273 return i.reg(19, 16); |
| 274 } |
| 275 |
| 276 bool LoadDoubleI::offset_is_immediate(Instruction i) const { |
| 277 UNREFERENCED_PARAMETER(i); |
| 278 return true; |
| 279 } |
| 280 |
| 281 |
| 282 SafetyLevel LoadDoubleR::safety(const Instruction i) const { |
| 283 bool pre_index = i.bit(24); |
| 284 if (pre_index) { |
| 285 // If pre_index is set, the address of the load is computed as the sum |
| 286 // of the two register parameters. We have checked that the first register |
| 287 // is within the sandbox, but this would allow adding an arbitrary value |
| 288 // to it, so it is not safe. |
| 289 return FORBIDDEN; |
| 290 } |
| 291 |
| 292 // Don't let addressing writeback alter PC. |
| 293 if (defs(i)[kRegisterPc]) return FORBIDDEN_OPERANDS; |
| 294 |
| 295 return MAY_BE_SAFE; |
| 296 } |
| 243 | 297 |
| 244 RegisterList LoadDoubleR::defs(const Instruction i) const { | 298 RegisterList LoadDoubleR::defs(const Instruction i) const { |
| 245 return LoadRegister::defs(i) + Register(i.bits(15, 12) + 1); | 299 return LoadRegister::defs(i) + Register(i.bits(15, 12) + 1); |
| 246 } | 300 } |
| 247 | 301 |
| 302 Register LoadDoubleR::base_address_register(const Instruction i) const { |
| 303 return i.reg(19, 16); |
| 304 } |
| 305 |
| 306 Register LoadExclusive::base_address_register(const Instruction i) const { |
| 307 return i.reg(19, 16); |
| 308 } |
| 309 |
| 248 RegisterList LoadDoubleExclusive::defs(const Instruction i) const { | 310 RegisterList LoadDoubleExclusive::defs(const Instruction i) const { |
| 249 return LoadExclusive::defs(i) + Register(i.bits(15, 12) + 1); | 311 return LoadExclusive::defs(i) + Register(i.bits(15, 12) + 1); |
| 250 } | 312 } |
| 251 | 313 |
| 314 Register LoadDoubleExclusive::base_address_register(const Instruction i) const { |
| 315 return i.reg(19, 16); |
| 316 } |
| 317 |
| 252 | 318 |
| 253 SafetyLevel LoadMultiple::safety(const Instruction i) const { | 319 SafetyLevel LoadMultiple::safety(const Instruction i) const { |
| 254 uint32_t rn = i.bits(19, 16); | 320 uint32_t rn = i.bits(19, 16); |
| 255 if (i.bit(21) && i.bit(rn)) { | 321 if (i.bit(21) && i.bit(rn)) { |
| 256 // In ARMv7, cannot update base register both by popping and by indexing. | 322 // In ARMv7, cannot update base register both by popping and by indexing. |
| 257 // (Pre-v7 this was still a weird thing to do.) | 323 // (Pre-v7 this was still a weird thing to do.) |
| 258 return UNPREDICTABLE; | 324 return UNPREDICTABLE; |
| 259 } | 325 } |
| 260 | 326 |
| 261 if (defs(i)[kRegisterPc]) { | 327 if (defs(i)[kRegisterPc]) { |
| 262 return FORBIDDEN_OPERANDS; | 328 return FORBIDDEN_OPERANDS; |
| 263 } | 329 } |
| 264 return MAY_BE_SAFE; | 330 return MAY_BE_SAFE; |
| 265 } | 331 } |
| 266 | 332 |
| 267 RegisterList LoadMultiple::defs(const Instruction i) const { | 333 RegisterList LoadMultiple::defs(const Instruction i) const { |
| 268 return RegisterList(i.bits(15, 0)) + immediate_addressing_defs(i); | 334 return RegisterList(i.bits(15, 0)) + immediate_addressing_defs(i); |
| 269 } | 335 } |
| 270 | 336 |
| 271 RegisterList LoadMultiple::immediate_addressing_defs( | 337 RegisterList LoadMultiple::immediate_addressing_defs( |
| 272 const Instruction i) const { | 338 const Instruction i) const { |
| 273 return i.bit(21)? i.reg(19, 16) : kRegisterNone; | 339 return i.bit(21)? i.reg(19, 16) : kRegisterNone; |
| 274 } | 340 } |
| 275 | 341 |
| 342 Register LoadMultiple::base_address_register(const Instruction i) const { |
| 343 return i.reg(19, 16); |
| 344 } |
| 345 |
| 276 | 346 |
| 277 /* | 347 /* |
| 278 * Vector load/stores | 348 * Vector load/stores |
| 279 */ | 349 */ |
| 280 | 350 |
| 281 SafetyLevel VectorLoad::safety(Instruction i) const { | 351 SafetyLevel VectorLoad::safety(Instruction i) const { |
| 282 if (defs(i)[kRegisterPc]) return FORBIDDEN_OPERANDS; | 352 if (defs(i)[kRegisterPc]) return FORBIDDEN_OPERANDS; |
| 283 | 353 |
| 284 return MAY_BE_SAFE; | 354 return MAY_BE_SAFE; |
| 285 } | 355 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 297 // Rm == SP indicates automatic update based on size of load. | 367 // Rm == SP indicates automatic update based on size of load. |
| 298 if (i.reg(3, 0) == kRegisterStack) { | 368 if (i.reg(3, 0) == kRegisterStack) { |
| 299 // Rn is updated by a small static displacement. | 369 // Rn is updated by a small static displacement. |
| 300 return i.reg(19, 16); | 370 return i.reg(19, 16); |
| 301 } | 371 } |
| 302 | 372 |
| 303 // Any writeback is not treated as immediate otherwise. | 373 // Any writeback is not treated as immediate otherwise. |
| 304 return kRegisterNone; | 374 return kRegisterNone; |
| 305 } | 375 } |
| 306 | 376 |
| 377 Register VectorLoad::base_address_register(const Instruction i) const { |
| 378 return i.reg(19, 16); |
| 379 } |
| 380 |
| 307 | 381 |
| 308 SafetyLevel VectorStore::safety(Instruction i) const { | 382 SafetyLevel VectorStore::safety(Instruction i) const { |
| 309 if (defs(i)[kRegisterPc]) return FORBIDDEN_OPERANDS; | 383 if (defs(i)[kRegisterPc]) return FORBIDDEN_OPERANDS; |
| 310 | 384 |
| 311 return MAY_BE_SAFE; | 385 return MAY_BE_SAFE; |
| 312 } | 386 } |
| 313 | 387 |
| 314 RegisterList VectorStore::defs(Instruction i) const { | 388 RegisterList VectorStore::defs(Instruction i) const { |
| 315 // Rm == PC indicates no address writeback. Otherwise Rn is affected. | 389 // Rm == PC indicates no address writeback. Otherwise Rn is affected. |
| 316 if (i.reg(3, 0) != kRegisterPc) { | 390 if (i.reg(3, 0) != kRegisterPc) { |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 413 return kRegisterPc + (i.bit(24)? kRegisterLink : kRegisterNone); | 487 return kRegisterPc + (i.bit(24)? kRegisterLink : kRegisterNone); |
| 414 } | 488 } |
| 415 | 489 |
| 416 int32_t Branch::branch_target_offset(const Instruction i) const { | 490 int32_t Branch::branch_target_offset(const Instruction i) const { |
| 417 // Sign extend and shift left 2: | 491 // Sign extend and shift left 2: |
| 418 int32_t offset = (int32_t)(i.bits(23, 0) << 8) >> 6; | 492 int32_t offset = (int32_t)(i.bits(23, 0) << 8) >> 6; |
| 419 return offset + 8; // because r15 reads as 8 bytes ahead | 493 return offset + 8; // because r15 reads as 8 bytes ahead |
| 420 } | 494 } |
| 421 | 495 |
| 422 } // namespace | 496 } // namespace |
| OLD | NEW |