diff options
author | Ian Rogers <irogers@google.com> | 2014-11-05 11:07:30 -0800 |
---|---|---|
committer | Ian Rogers <irogers@google.com> | 2014-11-14 14:48:54 -0800 |
commit | 8e1f4f8f848f2dbb36265a019310498a61cd674d (patch) | |
tree | b6b539b3314fc734aab7bd0d9a3972119202829b /runtime/verifier/register_line.h | |
parent | 81852bf5a1d4640b7b22b8a0404ce8401a7219c6 (diff) | |
download | art-8e1f4f8f848f2dbb36265a019310498a61cd674d.zip art-8e1f4f8f848f2dbb36265a019310498a61cd674d.tar.gz art-8e1f4f8f848f2dbb36265a019310498a61cd674d.tar.bz2 |
Avoid abort in malformed dex code.
Don't allow a perceived double monitor-enter on a register
to abort libartd.
Allow expected verifier errors in the smali tests.
Tidy includes in the method verifier.
Bug: 17978759
Change-Id: Ic44924c788cd2334f91a047fb41b459b89a1843b
Diffstat (limited to 'runtime/verifier/register_line.h')
-rw-r--r-- | runtime/verifier/register_line.h | 31 |
1 files changed, 15 insertions, 16 deletions
diff --git a/runtime/verifier/register_line.h b/runtime/verifier/register_line.h index 8f7823a..52b5c13 100644 --- a/runtime/verifier/register_line.h +++ b/runtime/verifier/register_line.h @@ -20,14 +20,16 @@ #include <memory> #include <vector> -#include "dex_instruction.h" -#include "reg_type.h" #include "safe_map.h" namespace art { + +class Instruction; + namespace verifier { class MethodVerifier; +class RegType; /* * Register type categories, for type checking. @@ -275,15 +277,7 @@ class RegisterLine { bool MergeRegisters(MethodVerifier* verifier, const RegisterLine* incoming_line) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - size_t GetMaxNonZeroReferenceReg(MethodVerifier* verifier, size_t max_ref_reg) { - size_t i = static_cast<int>(max_ref_reg) < 0 ? 0 : max_ref_reg; - for (; i < num_regs_; i++) { - if (GetRegisterType(verifier, i).IsNonZeroReferenceTypes()) { - max_ref_reg = i; - } - } - return max_ref_reg; - } + size_t GetMaxNonZeroReferenceReg(MethodVerifier* verifier, size_t max_ref_reg) const; // Write a bit at each register location that holds a reference. void WriteReferenceBitMap(MethodVerifier* verifier, std::vector<uint8_t>* data, size_t max_bytes); @@ -313,15 +307,18 @@ class RegisterLine { } } - void SetRegToLockDepth(size_t reg, size_t depth) { + bool SetRegToLockDepth(size_t reg, size_t depth) { CHECK_LT(depth, 32u); - DCHECK(!IsSetLockDepth(reg, depth)); + if (IsSetLockDepth(reg, depth)) { + return false; // Register already holds lock so locking twice is erroneous. + } auto it = reg_to_lock_depths_.find(reg); if (it == reg_to_lock_depths_.end()) { reg_to_lock_depths_.Put(reg, 1 << depth); } else { it->second |= (1 << depth); } + return true; } void ClearRegToLockDepth(size_t reg, size_t depth) { @@ -347,21 +344,23 @@ class RegisterLine { SetResultTypeToUnknown(verifier); } - // Storage for the result register's type, valid after an invocation + // Storage for the result register's type, valid after an invocation. uint16_t result_[2]; // Length of reg_types_ const uint32_t num_regs_; - // A stack of monitor enter locations + // A stack of monitor enter locations. std::vector<uint32_t, TrackingAllocator<uint32_t, kAllocatorTagVerifier>> monitors_; // A map from register to a bit vector of indices into the monitors_ stack. As we pop the monitor // stack we verify that monitor-enter/exit are correctly nested. That is, if there was a - // monitor-enter on v5 and then on v6, we expect the monitor-exit to be on v6 then on v5 + // monitor-enter on v5 and then on v6, we expect the monitor-exit to be on v6 then on v5. AllocationTrackingSafeMap<uint32_t, uint32_t, kAllocatorTagVerifier> reg_to_lock_depths_; // An array of RegType Ids associated with each dex register. uint16_t line_[0]; + + DISALLOW_COPY_AND_ASSIGN(RegisterLine); }; } // namespace verifier |