summaryrefslogtreecommitdiffstats
path: root/runtime/verifier/register_line.h
diff options
context:
space:
mode:
authorIan Rogers <irogers@google.com>2014-11-05 11:07:30 -0800
committerIan Rogers <irogers@google.com>2014-11-14 14:48:54 -0800
commit8e1f4f8f848f2dbb36265a019310498a61cd674d (patch)
treeb6b539b3314fc734aab7bd0d9a3972119202829b /runtime/verifier/register_line.h
parent81852bf5a1d4640b7b22b8a0404ce8401a7219c6 (diff)
downloadart-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.h31
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