Merge "Fix potential out of bounds access in 151-OpenFileLimit test."
diff --git a/Android.mk b/Android.mk
index cb0b709..0a90a0b 100644
--- a/Android.mk
+++ b/Android.mk
@@ -135,11 +135,11 @@
else
test-art-target-sync: $(TEST_ART_TARGET_SYNC_DEPS)
$(TEST_ART_ADB_ROOT_AND_REMOUNT)
- adb wait-for-device push $(ANDROID_PRODUCT_OUT)/system $(ART_TEST_ANDROID_ROOT)
+ adb wait-for-device push $(PRODUCT_OUT)/system $(ART_TEST_ANDROID_ROOT)
# Push the contents of the `data` dir into `/data` on the device. If
# `/data` already exists on the device, it is not overwritten, but its
# contents are updated.
- adb push $(ANDROID_PRODUCT_OUT)/data /
+ adb push $(PRODUCT_OUT)/data /
endif
endif
diff --git a/compiler/exception_test.cc b/compiler/exception_test.cc
index 4dbef0d..59d20f8 100644
--- a/compiler/exception_test.cc
+++ b/compiler/exception_test.cc
@@ -24,6 +24,7 @@
#include "common_runtime_test.h"
#include "dex_file-inl.h"
#include "dex_file.h"
+#include "dex_file_exception_helpers.h"
#include "gtest/gtest.h"
#include "handle_scope-inl.h"
#include "leb128.h"
@@ -129,20 +130,18 @@
TEST_F(ExceptionTest, FindCatchHandler) {
ScopedObjectAccess soa(Thread::Current());
- const DexFile::CodeItem* code_item = dex_->GetCodeItem(method_f_->GetCodeItemOffset());
- CodeItemDataAccessor accessor(dex_, code_item);
+ CodeItemDataAccessor accessor(dex_, dex_->GetCodeItem(method_f_->GetCodeItemOffset()));
- ASSERT_TRUE(code_item != nullptr);
+ ASSERT_TRUE(accessor.HasCodeItem());
ASSERT_EQ(2u, accessor.TriesSize());
ASSERT_NE(0u, accessor.InsnsSizeInCodeUnits());
- const DexFile::TryItem *t0, *t1;
- t0 = dex_->GetTryItems(*code_item, 0);
- t1 = dex_->GetTryItems(*code_item, 1);
- EXPECT_LE(t0->start_addr_, t1->start_addr_);
+ const DexFile::TryItem& t0 = accessor.TryItems().begin()[0];
+ const DexFile::TryItem& t1 = accessor.TryItems().begin()[1];
+ EXPECT_LE(t0.start_addr_, t1.start_addr_);
{
- CatchHandlerIterator iter(*code_item, 4 /* Dex PC in the first try block */);
+ CatchHandlerIterator iter(accessor, 4 /* Dex PC in the first try block */);
EXPECT_STREQ("Ljava/io/IOException;", dex_->StringByTypeIdx(iter.GetHandlerTypeIndex()));
ASSERT_TRUE(iter.HasNext());
iter.Next();
@@ -152,14 +151,14 @@
EXPECT_FALSE(iter.HasNext());
}
{
- CatchHandlerIterator iter(*code_item, 8 /* Dex PC in the second try block */);
+ CatchHandlerIterator iter(accessor, 8 /* Dex PC in the second try block */);
EXPECT_STREQ("Ljava/io/IOException;", dex_->StringByTypeIdx(iter.GetHandlerTypeIndex()));
ASSERT_TRUE(iter.HasNext());
iter.Next();
EXPECT_FALSE(iter.HasNext());
}
{
- CatchHandlerIterator iter(*code_item, 11 /* Dex PC not in any try block */);
+ CatchHandlerIterator iter(accessor, 11 /* Dex PC not in any try block */);
EXPECT_FALSE(iter.HasNext());
}
}
diff --git a/compiler/optimizing/block_builder.cc b/compiler/optimizing/block_builder.cc
index c505efa..0c92600 100644
--- a/compiler/optimizing/block_builder.cc
+++ b/compiler/optimizing/block_builder.cc
@@ -19,6 +19,7 @@
#include "base/logging.h" // FOR VLOG.
#include "bytecode_utils.h"
#include "code_item_accessors-inl.h"
+#include "dex_file_exception_helpers.h"
#include "quicken_info.h"
namespace art {
diff --git a/dexdump/dexdump.cc b/dexdump/dexdump.cc
index 730d4b9..ba2a922 100644
--- a/dexdump/dexdump.cc
+++ b/dexdump/dexdump.cc
@@ -48,6 +48,7 @@
#include "dex_file-inl.h"
#include "dex_file_loader.h"
#include "dex_file_types.h"
+#include "dex_file_exception_helpers.h"
#include "dex_instruction-inl.h"
#include "dexdump_cfg.h"
@@ -735,7 +736,8 @@
* Dumps the catches table associated with the code.
*/
static void dumpCatches(const DexFile* pDexFile, const DexFile::CodeItem* pCode) {
- const u4 triesSize = CodeItemDataAccessor(pDexFile, pCode).TriesSize();
+ CodeItemDataAccessor accessor(pDexFile, pCode);
+ const u4 triesSize = accessor.TriesSize();
// No catch table.
if (triesSize == 0) {
@@ -745,12 +747,11 @@
// Dump all table entries.
fprintf(gOutFile, " catches : %d\n", triesSize);
- for (u4 i = 0; i < triesSize; i++) {
- const DexFile::TryItem* pTry = pDexFile->GetTryItems(*pCode, i);
- const u4 start = pTry->start_addr_;
- const u4 end = start + pTry->insn_count_;
+ for (const DexFile::TryItem& try_item : accessor.TryItems()) {
+ const u4 start = try_item.start_addr_;
+ const u4 end = start + try_item.insn_count_;
fprintf(gOutFile, " 0x%04x - 0x%04x\n", start, end);
- for (CatchHandlerIterator it(*pCode, *pTry); it.HasNext(); it.Next()) {
+ for (CatchHandlerIterator it(accessor, try_item); it.HasNext(); it.Next()) {
const dex::TypeIndex tidx = it.GetHandlerTypeIndex();
const char* descriptor = (!tidx.IsValid()) ? "<any>" : pDexFile->StringByTypeIdx(tidx);
fprintf(gOutFile, " %s -> 0x%04x\n", descriptor, it.GetHandlerAddress());
diff --git a/dexdump/dexdump_cfg.cc b/dexdump/dexdump_cfg.cc
index dd57a11..7e9f113 100644
--- a/dexdump/dexdump_cfg.cc
+++ b/dexdump/dexdump_cfg.cc
@@ -27,6 +27,7 @@
#include "code_item_accessors-no_art-inl.h"
#include "dex_file-inl.h"
+#include "dex_file_exception_helpers.h"
#include "dex_instruction-inl.h"
namespace art {
@@ -38,7 +39,7 @@
os << "digraph {\n";
os << " # /* " << dex_file->PrettyMethod(dex_method_idx, true) << " */\n";
- CodeItemInstructionAccessor accessor(dex_file, code_item);
+ CodeItemDataAccessor accessor(dex_file, code_item);
std::set<uint32_t> dex_pc_is_branch_target;
{
@@ -195,7 +196,7 @@
}
// Look at the exceptions of the first entry.
- CatchHandlerIterator catch_it(*code_item, dex_pc);
+ CatchHandlerIterator catch_it(accessor, dex_pc);
for (; catch_it.HasNext(); catch_it.Next()) {
exception_targets.insert(catch_it.GetHandlerAddress());
}
@@ -254,7 +255,7 @@
// Exception edges. If this is not the first instruction in the block
if (block_start_dex_pc != dex_pc) {
std::set<uint32_t> current_handler_pcs;
- CatchHandlerIterator catch_it(*code_item, dex_pc);
+ CatchHandlerIterator catch_it(accessor, dex_pc);
for (; catch_it.HasNext(); catch_it.Next()) {
current_handler_pcs.insert(catch_it.GetHandlerAddress());
}
@@ -295,7 +296,7 @@
const Instruction* inst = &accessor.InstructionAt(dex_pc);
uint32_t this_node_id = dex_pc_to_incl_id.find(dex_pc)->second;
while (true) {
- CatchHandlerIterator catch_it(*code_item, dex_pc);
+ CatchHandlerIterator catch_it(accessor, dex_pc);
if (catch_it.HasNext()) {
std::set<uint32_t> handled_targets;
for (; catch_it.HasNext(); catch_it.Next()) {
diff --git a/dexlayout/dex_ir.cc b/dexlayout/dex_ir.cc
index a163bd9..157d4ef 100644
--- a/dexlayout/dex_ir.cc
+++ b/dexlayout/dex_ir.cc
@@ -23,6 +23,7 @@
#include "dex_ir.h"
#include "code_item_accessors-inl.h"
+#include "dex_file_exception_helpers.h"
#include "dex_instruction-inl.h"
#include "dex_ir_builder.h"
@@ -610,7 +611,7 @@
if (handlers == nullptr) {
bool catch_all = false;
TypeAddrPairVector* addr_pairs = new TypeAddrPairVector();
- for (CatchHandlerIterator it(disk_code_item, disk_try_item); it.HasNext(); it.Next()) {
+ for (CatchHandlerIterator it(accessor, disk_try_item); it.HasNext(); it.Next()) {
const dex::TypeIndex type_index = it.GetHandlerTypeIndex();
const TypeId* type_id = GetTypeIdOrNullPtr(type_index.index_);
catch_all |= type_id == nullptr;
diff --git a/runtime/Android.bp b/runtime/Android.bp
index 1e5fe16..8fe901d 100644
--- a/runtime/Android.bp
+++ b/runtime/Android.bp
@@ -58,8 +58,9 @@
"compiler_filter.cc",
"debugger.cc",
"dex_file.cc",
- "dex_file_loader.cc",
"dex_file_annotations.cc",
+ "dex_file_exception_helpers.cc",
+ "dex_file_loader.cc",
"dex_file_layout.cc",
"dex_file_tracking_registrar.cc",
"dex_file_verifier.cc",
diff --git a/runtime/art_method.cc b/runtime/art_method.cc
index 7ddaa7e..d6e4ce5 100644
--- a/runtime/art_method.cc
+++ b/runtime/art_method.cc
@@ -26,6 +26,7 @@
#include "class_linker-inl.h"
#include "debugger.h"
#include "dex_file-inl.h"
+#include "dex_file_exception_helpers.h"
#include "dex_instruction.h"
#include "entrypoints/runtime_asm_entrypoints.h"
#include "gc/accounting/card_table-inl.h"
@@ -263,7 +264,6 @@
uint32_t ArtMethod::FindCatchBlock(Handle<mirror::Class> exception_type,
uint32_t dex_pc, bool* has_no_move_exception) {
- const DexFile::CodeItem* code_item = GetCodeItem();
// Set aside the exception while we resolve its type.
Thread* self = Thread::Current();
StackHandleScope<1> hs(self);
@@ -272,7 +272,8 @@
// Default to handler not found.
uint32_t found_dex_pc = dex::kDexNoIndex;
// Iterate over the catch handlers associated with dex_pc.
- for (CatchHandlerIterator it(*code_item, dex_pc); it.HasNext(); it.Next()) {
+ CodeItemDataAccessor accessor(this);
+ for (CatchHandlerIterator it(accessor, dex_pc); it.HasNext(); it.Next()) {
dex::TypeIndex iter_type_idx = it.GetHandlerTypeIndex();
// Catch all case
if (!iter_type_idx.IsValid()) {
@@ -297,7 +298,7 @@
}
}
if (found_dex_pc != dex::kDexNoIndex) {
- const Instruction& first_catch_instr = DexInstructions().InstructionAt(found_dex_pc);
+ const Instruction& first_catch_instr = accessor.InstructionAt(found_dex_pc);
*has_no_move_exception = (first_catch_instr.Opcode() != Instruction::MOVE_EXCEPTION);
}
// Put the exception back.
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 24fcce4..192517f 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -51,6 +51,7 @@
#include "compiler_callbacks.h"
#include "debugger.h"
#include "dex_file-inl.h"
+#include "dex_file_exception_helpers.h"
#include "dex_file_loader.h"
#include "entrypoints/entrypoint_utils.h"
#include "entrypoints/runtime_asm_entrypoints.h"
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index 246f89e..3dca2f9 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -795,6 +795,12 @@
}
};
+struct ArrayElementVarHandleOffsets : public CheckOffsets<mirror::ArrayElementVarHandle> {
+ ArrayElementVarHandleOffsets() : CheckOffsets<mirror::ArrayElementVarHandle>(
+ false, "Ljava/lang/invoke/ArrayElementVarHandle;") {
+ }
+};
+
struct ByteArrayViewVarHandleOffsets : public CheckOffsets<mirror::ByteArrayViewVarHandle> {
ByteArrayViewVarHandleOffsets() : CheckOffsets<mirror::ByteArrayViewVarHandle>(
false, "Ljava/lang/invoke/ByteArrayViewVarHandle;") {
@@ -838,6 +844,7 @@
EXPECT_TRUE(CallSiteOffsets().Check());
EXPECT_TRUE(VarHandleOffsets().Check());
EXPECT_TRUE(FieldVarHandleOffsets().Check());
+ EXPECT_TRUE(ArrayElementVarHandleOffsets().Check());
EXPECT_TRUE(ByteArrayViewVarHandleOffsets().Check());
EXPECT_TRUE(ByteBufferViewVarHandleOffsets().Check());
}
diff --git a/runtime/dex_file.cc b/runtime/dex_file.cc
index 4aed402..d136dc3 100644
--- a/runtime/dex_file.cc
+++ b/runtime/dex_file.cc
@@ -802,85 +802,6 @@
ptr_ += width;
}
-CatchHandlerIterator::CatchHandlerIterator(const DexFile::CodeItem& code_item, uint32_t address) {
- handler_.address_ = -1;
- int32_t offset = -1;
-
- // Short-circuit the overwhelmingly common cases.
- switch (code_item.tries_size_) {
- case 0:
- break;
- case 1: {
- const DexFile::TryItem* tries = DexFile::GetTryItems(code_item, 0);
- uint32_t start = tries->start_addr_;
- if (address >= start) {
- uint32_t end = start + tries->insn_count_;
- if (address < end) {
- offset = tries->handler_off_;
- }
- }
- break;
- }
- default:
- offset = DexFile::FindCatchHandlerOffset(code_item, address);
- }
- Init(code_item, offset);
-}
-
-CatchHandlerIterator::CatchHandlerIterator(const DexFile::CodeItem& code_item,
- const DexFile::TryItem& try_item) {
- handler_.address_ = -1;
- Init(code_item, try_item.handler_off_);
-}
-
-void CatchHandlerIterator::Init(const DexFile::CodeItem& code_item,
- int32_t offset) {
- if (offset >= 0) {
- Init(DexFile::GetCatchHandlerData(code_item, offset));
- } else {
- // Not found, initialize as empty
- current_data_ = nullptr;
- remaining_count_ = -1;
- catch_all_ = false;
- DCHECK(!HasNext());
- }
-}
-
-void CatchHandlerIterator::Init(const uint8_t* handler_data) {
- current_data_ = handler_data;
- remaining_count_ = DecodeSignedLeb128(¤t_data_);
-
- // If remaining_count_ is non-positive, then it is the negative of
- // the number of catch types, and the catches are followed by a
- // catch-all handler.
- if (remaining_count_ <= 0) {
- catch_all_ = true;
- remaining_count_ = -remaining_count_;
- } else {
- catch_all_ = false;
- }
- Next();
-}
-
-void CatchHandlerIterator::Next() {
- if (remaining_count_ > 0) {
- handler_.type_idx_ = dex::TypeIndex(DecodeUnsignedLeb128(¤t_data_));
- handler_.address_ = DecodeUnsignedLeb128(¤t_data_);
- remaining_count_--;
- return;
- }
-
- if (catch_all_) {
- handler_.type_idx_ = dex::TypeIndex(DexFile::kDexNoIndex16);
- handler_.address_ = DecodeUnsignedLeb128(¤t_data_);
- catch_all_ = false;
- return;
- }
-
- // no more handler
- remaining_count_ = -1;
-}
-
namespace dex {
std::ostream& operator<<(std::ostream& os, const StringIndex& index) {
diff --git a/runtime/dex_file.h b/runtime/dex_file.h
index f3a88f7..e80a13c 100644
--- a/runtime/dex_file.h
+++ b/runtime/dex_file.h
@@ -342,12 +342,10 @@
private:
ART_FRIEND_TEST(CodeItemAccessorsTest, TestDexInstructionsAccessor);
- friend class CatchHandlerIterator;
friend class CodeItemDataAccessor;
friend class CodeItemDebugInfoAccessor;
friend class CodeItemInstructionAccessor;
friend class DexFile; // TODO: Remove this one when it's cleaned up.
- friend class DexFileVerifier;
friend class VdexFile; // TODO: Remove this one when it's cleaned up.
DISALLOW_COPY_AND_ASSIGN(CodeItem);
};
@@ -1466,47 +1464,6 @@
};
std::ostream& operator<<(std::ostream& os, const CallSiteArrayValueIterator::ValueType& code);
-class CatchHandlerIterator {
- public:
- CatchHandlerIterator(const DexFile::CodeItem& code_item, uint32_t address);
-
- CatchHandlerIterator(const DexFile::CodeItem& code_item,
- const DexFile::TryItem& try_item);
-
- explicit CatchHandlerIterator(const uint8_t* handler_data) {
- Init(handler_data);
- }
-
- dex::TypeIndex GetHandlerTypeIndex() const {
- return handler_.type_idx_;
- }
- uint32_t GetHandlerAddress() const {
- return handler_.address_;
- }
- void Next();
- bool HasNext() const {
- return remaining_count_ != -1 || catch_all_;
- }
- // End of this set of catch blocks, convenience method to locate next set of catch blocks
- const uint8_t* EndDataPointer() const {
- CHECK(!HasNext());
- return current_data_;
- }
-
- private:
- void Init(const DexFile::CodeItem& code_item, int32_t offset);
- void Init(const uint8_t* handler_data);
-
- struct CatchHandlerItem {
- dex::TypeIndex type_idx_; // type index of the caught exception type
- uint32_t address_; // handler address
- } handler_;
- const uint8_t* current_data_; // the current handler in dex file.
- int32_t remaining_count_; // number of handlers not read.
- bool catch_all_; // is there a handler that will catch all exceptions in case
- // that all typed handler does not match.
-};
-
} // namespace art
#endif // ART_RUNTIME_DEX_FILE_H_
diff --git a/runtime/dex_file_exception_helpers.cc b/runtime/dex_file_exception_helpers.cc
new file mode 100644
index 0000000..ad56eb0
--- /dev/null
+++ b/runtime/dex_file_exception_helpers.cc
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "dex_file_exception_helpers.h"
+
+#include "code_item_accessors-no_art-inl.h"
+
+namespace art {
+
+CatchHandlerIterator::CatchHandlerIterator(const CodeItemDataAccessor& accessor, uint32_t address) {
+ handler_.address_ = -1;
+ int32_t offset = -1;
+
+ // Short-circuit the overwhelmingly common cases.
+ switch (accessor.TriesSize()) {
+ case 0:
+ break;
+ case 1: {
+ const DexFile::TryItem* tries = accessor.TryItems().begin();
+ uint32_t start = tries->start_addr_;
+ if (address >= start) {
+ uint32_t end = start + tries->insn_count_;
+ if (address < end) {
+ offset = tries->handler_off_;
+ }
+ }
+ break;
+ }
+ default: {
+ const DexFile::TryItem* try_item = accessor.FindTryItem(address);
+ offset = try_item != nullptr ? try_item->handler_off_ : -1;
+ break;
+ }
+ }
+ Init(accessor, offset);
+}
+
+CatchHandlerIterator::CatchHandlerIterator(const CodeItemDataAccessor& accessor,
+ const DexFile::TryItem& try_item) {
+ handler_.address_ = -1;
+ Init(accessor, try_item.handler_off_);
+}
+
+void CatchHandlerIterator::Init(const CodeItemDataAccessor& accessor, int32_t offset) {
+ if (offset >= 0) {
+ Init(accessor.GetCatchHandlerData(offset));
+ } else {
+ // Not found, initialize as empty
+ current_data_ = nullptr;
+ remaining_count_ = -1;
+ catch_all_ = false;
+ DCHECK(!HasNext());
+ }
+}
+
+void CatchHandlerIterator::Init(const uint8_t* handler_data) {
+ current_data_ = handler_data;
+ remaining_count_ = DecodeSignedLeb128(¤t_data_);
+
+ // If remaining_count_ is non-positive, then it is the negative of
+ // the number of catch types, and the catches are followed by a
+ // catch-all handler.
+ if (remaining_count_ <= 0) {
+ catch_all_ = true;
+ remaining_count_ = -remaining_count_;
+ } else {
+ catch_all_ = false;
+ }
+ Next();
+}
+
+void CatchHandlerIterator::Next() {
+ if (remaining_count_ > 0) {
+ handler_.type_idx_ = dex::TypeIndex(DecodeUnsignedLeb128(¤t_data_));
+ handler_.address_ = DecodeUnsignedLeb128(¤t_data_);
+ remaining_count_--;
+ return;
+ }
+
+ if (catch_all_) {
+ handler_.type_idx_ = dex::TypeIndex(DexFile::kDexNoIndex16);
+ handler_.address_ = DecodeUnsignedLeb128(¤t_data_);
+ catch_all_ = false;
+ return;
+ }
+
+ // no more handler
+ remaining_count_ = -1;
+}
+
+} // namespace art
diff --git a/runtime/dex_file_exception_helpers.h b/runtime/dex_file_exception_helpers.h
new file mode 100644
index 0000000..739ed1f
--- /dev/null
+++ b/runtime/dex_file_exception_helpers.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_RUNTIME_DEX_FILE_EXCEPTION_HELPERS_H_
+#define ART_RUNTIME_DEX_FILE_EXCEPTION_HELPERS_H_
+
+#include "dex_file.h"
+
+namespace art {
+
+class CodeItemDataAccessor;
+
+class CatchHandlerIterator {
+ public:
+ CatchHandlerIterator(const CodeItemDataAccessor& accessor, uint32_t address);
+
+ CatchHandlerIterator(const CodeItemDataAccessor& accessor, const DexFile::TryItem& try_item);
+
+ explicit CatchHandlerIterator(const uint8_t* handler_data) {
+ Init(handler_data);
+ }
+
+ dex::TypeIndex GetHandlerTypeIndex() const {
+ return handler_.type_idx_;
+ }
+ uint32_t GetHandlerAddress() const {
+ return handler_.address_;
+ }
+ void Next();
+ bool HasNext() const {
+ return remaining_count_ != -1 || catch_all_;
+ }
+ // End of this set of catch blocks, convenience method to locate next set of catch blocks
+ const uint8_t* EndDataPointer() const {
+ CHECK(!HasNext());
+ return current_data_;
+ }
+
+ private:
+ void Init(const CodeItemDataAccessor& accessor, int32_t offset);
+ void Init(const uint8_t* handler_data);
+
+ struct CatchHandlerItem {
+ dex::TypeIndex type_idx_; // type index of the caught exception type
+ uint32_t address_; // handler address
+ } handler_;
+ const uint8_t* current_data_; // the current handler in dex file.
+ int32_t remaining_count_; // number of handlers not read.
+ bool catch_all_; // is there a handler that will catch all exceptions in case
+ // that all typed handler does not match.
+};
+
+} // namespace art
+
+#endif // ART_RUNTIME_DEX_FILE_EXCEPTION_HELPERS_H_
diff --git a/runtime/dex_file_verifier.cc b/runtime/dex_file_verifier.cc
index edf5650..8656bcc 100644
--- a/runtime/dex_file_verifier.cc
+++ b/runtime/dex_file_verifier.cc
@@ -23,6 +23,7 @@
#include "android-base/stringprintf.h"
+#include "code_item_accessors-no_art-inl.h"
#include "dex_file-inl.h"
#include "experimental_flags.h"
#include "leb128.h"
@@ -572,7 +573,8 @@
bool DexFileVerifier::CheckAndGetHandlerOffsets(const DexFile::CodeItem* code_item,
uint32_t* handler_offsets, uint32_t handlers_size) {
- const uint8_t* handlers_base = DexFile::GetCatchHandlerData(*code_item, 0);
+ CodeItemDataAccessor accessor(dex_file_, code_item);
+ const uint8_t* handlers_base = accessor.GetCatchHandlerData();
for (uint32_t i = 0; i < handlers_size; i++) {
bool catch_all;
@@ -600,7 +602,7 @@
}
DECODE_UNSIGNED_CHECKED_FROM(ptr_, addr);
- if (UNLIKELY(addr >= code_item->insns_size_in_code_units_)) {
+ if (UNLIKELY(addr >= accessor.InsnsSizeInCodeUnits())) {
ErrorStringPrintf("Invalid handler addr: %x", addr);
return false;
}
@@ -608,7 +610,7 @@
if (catch_all) {
DECODE_UNSIGNED_CHECKED_FROM(ptr_, addr);
- if (UNLIKELY(addr >= code_item->insns_size_in_code_units_)) {
+ if (UNLIKELY(addr >= accessor.InsnsSizeInCodeUnits())) {
ErrorStringPrintf("Invalid handler catch_all_addr: %x", addr);
return false;
}
@@ -1224,14 +1226,14 @@
return false;
}
- if (UNLIKELY(code_item->ins_size_ > code_item->registers_size_)) {
+ CodeItemDataAccessor accessor(dex_file_, code_item);
+ if (UNLIKELY(accessor.InsSize() > accessor.RegistersSize())) {
ErrorStringPrintf("ins_size (%ud) > registers_size (%ud)",
- code_item->ins_size_, code_item->registers_size_);
+ accessor.InsSize(), accessor.RegistersSize());
return false;
}
- if (UNLIKELY((code_item->outs_size_ > 5) &&
- (code_item->outs_size_ > code_item->registers_size_))) {
+ if (UNLIKELY(accessor.OutsSize() > 5 && accessor.OutsSize() > accessor.RegistersSize())) {
/*
* outs_size can be up to 5, even if registers_size is smaller, since the
* short forms of method invocation allow repetitions of a register multiple
@@ -1239,18 +1241,18 @@
* need to be represented in-order in the register file.
*/
ErrorStringPrintf("outs_size (%ud) > registers_size (%ud)",
- code_item->outs_size_, code_item->registers_size_);
+ accessor.OutsSize(), accessor.RegistersSize());
return false;
}
- const uint16_t* insns = code_item->insns_;
- uint32_t insns_size = code_item->insns_size_in_code_units_;
+ const uint16_t* insns = accessor.Insns();
+ uint32_t insns_size = accessor.InsnsSizeInCodeUnits();
if (!CheckListSize(insns, insns_size, sizeof(uint16_t), "insns size")) {
return false;
}
// Grab the end of the insns if there are no try_items.
- uint32_t try_items_size = code_item->tries_size_;
+ uint32_t try_items_size = accessor.TriesSize();
if (try_items_size == 0) {
ptr_ = reinterpret_cast<const uint8_t*>(&insns[insns_size]);
return true;
@@ -1262,12 +1264,12 @@
return false;
}
- const DexFile::TryItem* try_items = DexFile::GetTryItems(*code_item, 0);
+ const DexFile::TryItem* try_items = accessor.TryItems().begin();
if (!CheckListSize(try_items, try_items_size, sizeof(DexFile::TryItem), "try_items size")) {
return false;
}
- ptr_ = DexFile::GetCatchHandlerData(*code_item, 0);
+ ptr_ = accessor.GetCatchHandlerData();
DECODE_UNSIGNED_CHECKED_FROM(ptr_, handlers_size);
if (UNLIKELY((handlers_size == 0) || (handlers_size >= 65536))) {
diff --git a/runtime/mirror/var_handle.h b/runtime/mirror/var_handle.h
index a2a5d8c..54a6d27 100644
--- a/runtime/mirror/var_handle.h
+++ b/runtime/mirror/var_handle.h
@@ -26,6 +26,7 @@
template<class T> class Handle;
struct VarHandleOffsets;
struct FieldVarHandleOffsets;
+struct ArrayElementVarHandleOffsets;
struct ByteArrayViewVarHandleOffsets;
struct ByteBufferViewVarHandleOffsets;
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index be6915f..63f21f8 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -32,6 +32,7 @@
#include "class_linker.h"
#include "compiler_callbacks.h"
#include "dex_file-inl.h"
+#include "dex_file_exception_helpers.h"
#include "dex_instruction-inl.h"
#include "dex_instruction_utils.h"
#include "experimental_flags.h"
@@ -3630,7 +3631,7 @@
bool has_catch_all_handler = false;
const DexFile::TryItem* try_item = code_item_accessor_.FindTryItem(work_insn_idx_);
CHECK(try_item != nullptr);
- CatchHandlerIterator iterator(code_item_accessor_.GetCatchHandlerData(try_item->handler_off_));
+ CatchHandlerIterator iterator(code_item_accessor_, *try_item);
// Need the linker to try and resolve the handled class to check if it's Throwable.
ClassLinker* linker = Runtime::Current()->GetClassLinker();