Move dex_file_verifier_test and dexlayout to ClassAccessor
Bug: 79758018
Test: test-art-host
Change-Id: I01d53eaf45d28fd762800c2716d6bf2dd3c9ad9e
diff --git a/dexlayout/dex_ir_builder.cc b/dexlayout/dex_ir_builder.cc
index a04a234..a83a46b 100644
--- a/dexlayout/dex_ir_builder.cc
+++ b/dexlayout/dex_ir_builder.cc
@@ -21,6 +21,7 @@
#include "dex_ir_builder.h"
+#include "dex/class_accessor-inl.h"
#include "dex/code_item_accessors-inl.h"
#include "dex/dex_file_exception_helpers.h"
#include "dexlayout.h"
@@ -162,7 +163,7 @@
const DexFile::CodeItem* disk_code_item,
uint32_t offset,
uint32_t dex_method_index);
- ClassData* CreateClassData(const DexFile& dex_file, const uint8_t* encoded_data, uint32_t offset);
+ ClassData* CreateClassData(const DexFile& dex_file, const DexFile::ClassDef& class_def);
void AddAnnotationsFromMapListSection(const DexFile& dex_file,
uint32_t start_offset,
@@ -197,7 +198,7 @@
uint8_t length,
EncodedValue* item);
- MethodItem GenerateMethodItem(const DexFile& dex_file, ClassDataItemIterator& cdii);
+ MethodItem GenerateMethodItem(const DexFile& dex_file, const ClassAccessor::Method& method);
ParameterAnnotation* GenerateParameterAnnotation(
const DexFile& dex_file,
@@ -488,8 +489,7 @@
const uint8_t* static_data = dex_file.GetEncodedStaticFieldValuesArray(disk_class_def);
EncodedArrayItem* static_values =
CreateEncodedArrayItem(dex_file, static_data, disk_class_def.static_values_off_);
- ClassData* class_data = CreateClassData(
- dex_file, dex_file.GetClassData(disk_class_def), disk_class_def.class_data_off_);
+ ClassData* class_data = CreateClassData(dex_file, disk_class_def);
CreateAndAddIndexedItem(header_->ClassDefs(),
header_->ClassDefs().GetOffset() + i * ClassDef::ItemSize(),
i,
@@ -894,36 +894,43 @@
return code_item;
}
-ClassData* BuilderMaps::CreateClassData(
- const DexFile& dex_file, const uint8_t* encoded_data, uint32_t offset) {
+ClassData* BuilderMaps::CreateClassData(const DexFile& dex_file,
+ const DexFile::ClassDef& class_def) {
// Read the fields and methods defined by the class, resolving the circular reference from those
// to classes by setting class at the same time.
+ const uint32_t offset = class_def.class_data_off_;
ClassData* class_data = class_datas_map_.GetExistingObject(offset);
- if (class_data == nullptr && encoded_data != nullptr) {
- ClassDataItemIterator cdii(dex_file, encoded_data);
+ if (class_data == nullptr && offset != 0u) {
+ ClassAccessor accessor(dex_file, class_def);
// Static fields.
FieldItemVector* static_fields = new FieldItemVector();
- for (; cdii.HasNextStaticField(); cdii.Next()) {
- FieldId* field_item = header_->FieldIds()[cdii.GetMemberIndex()];
- uint32_t access_flags = cdii.GetRawMemberAccessFlags();
+ for (const ClassAccessor::Field& field : accessor.GetStaticFields()) {
+ FieldId* field_item = header_->FieldIds()[field.GetIndex()];
+ uint32_t access_flags = field.GetRawAccessFlags();
static_fields->emplace_back(access_flags, field_item);
}
- // Instance fields.
FieldItemVector* instance_fields = new FieldItemVector();
- for (; cdii.HasNextInstanceField(); cdii.Next()) {
- FieldId* field_item = header_->FieldIds()[cdii.GetMemberIndex()];
- uint32_t access_flags = cdii.GetRawMemberAccessFlags();
+ for (const ClassAccessor::Field& field : accessor.GetInstanceFields()) {
+ FieldId* field_item = header_->FieldIds()[field.GetIndex()];
+ uint32_t access_flags = field.GetRawAccessFlags();
instance_fields->emplace_back(access_flags, field_item);
}
// Direct methods.
MethodItemVector* direct_methods = new MethodItemVector();
- for (; cdii.HasNextDirectMethod(); cdii.Next()) {
- direct_methods->push_back(GenerateMethodItem(dex_file, cdii));
+ auto direct_methods_it = accessor.GetDirectMethods();
+ for (auto it = direct_methods_it.begin(); it != direct_methods_it.end(); ++it) {
+ direct_methods->push_back(GenerateMethodItem(dex_file, *it));
}
// Virtual methods.
MethodItemVector* virtual_methods = new MethodItemVector();
- for (; cdii.HasNextVirtualMethod(); cdii.Next()) {
- virtual_methods->push_back(GenerateMethodItem(dex_file, cdii));
+ auto virtual_methods_it = accessor.GetVirtualMethods();
+ const uint8_t* last_data_ptr;
+ for (auto it = virtual_methods_it.begin(); ; ++it) {
+ if (it == virtual_methods_it.end()) {
+ last_data_ptr = it->GetDataPointer();
+ break;
+ }
+ virtual_methods->push_back(GenerateMethodItem(dex_file, *it));
}
class_data = class_datas_map_.CreateAndAddItem(header_->ClassDatas(),
eagerly_assign_offsets_,
@@ -932,7 +939,7 @@
instance_fields,
direct_methods,
virtual_methods);
- class_data->SetSize(cdii.EndDataPointer() - encoded_data);
+ class_data->SetSize(last_data_ptr - dex_file.GetClassData(class_def));
}
return class_data;
}
@@ -1168,16 +1175,17 @@
}
}
-MethodItem BuilderMaps::GenerateMethodItem(const DexFile& dex_file, ClassDataItemIterator& cdii) {
- MethodId* method_id = header_->MethodIds()[cdii.GetMemberIndex()];
- uint32_t access_flags = cdii.GetRawMemberAccessFlags();
- const DexFile::CodeItem* disk_code_item = cdii.GetMethodCodeItem();
+MethodItem BuilderMaps::GenerateMethodItem(const DexFile& dex_file,
+ const ClassAccessor::Method& method) {
+ MethodId* method_id = header_->MethodIds()[method.GetIndex()];
+ uint32_t access_flags = method.GetRawAccessFlags();
+ const DexFile::CodeItem* disk_code_item = method.GetCodeItem();
// Temporary hack to prevent incorrectly deduping code items if they have the same offset since
// they may have different debug info streams.
CodeItem* code_item = DedupeOrCreateCodeItem(dex_file,
disk_code_item,
- cdii.GetMethodCodeItemOffset(),
- cdii.GetMemberIndex());
+ method.GetCodeItemOffset(),
+ method.GetIndex());
return MethodItem(access_flags, method_id, code_item);
}
diff --git a/dexlayout/dexlayout_test.cc b/dexlayout/dexlayout_test.cc
index 2b1352d..a20930b 100644
--- a/dexlayout/dexlayout_test.cc
+++ b/dexlayout/dexlayout_test.cc
@@ -26,6 +26,7 @@
#include "common_runtime_test.h"
#include "dex/art_dex_file_loader.h"
#include "dex/base64_test_util.h"
+#include "dex/class_accessor-inl.h"
#include "dex/code_item_accessors-inl.h"
#include "dex/dex_file-inl.h"
#include "dex/dex_file_loader.h"
@@ -682,16 +683,9 @@
MutateDexFile(temp_dex.GetFile(), GetTestDexFileName("ManyMethods"), [] (DexFile* dex) {
bool mutated_successfully = false;
// Change the dex instructions to make an opcode that spans past the end of the code item.
- for (size_t i = 0; i < dex->NumClassDefs(); ++i) {
- const DexFile::ClassDef& def = dex->GetClassDef(i);
- const uint8_t* data = dex->GetClassData(def);
- if (data == nullptr) {
- continue;
- }
- ClassDataItemIterator it(*dex, data);
- it.SkipAllFields();
- while (it.HasNextMethod()) {
- DexFile::CodeItem* item = const_cast<DexFile::CodeItem*>(it.GetMethodCodeItem());
+ for (ClassAccessor accessor : dex->GetClasses()) {
+ for (const ClassAccessor::Method& method : accessor.GetMethods()) {
+ DexFile::CodeItem* item = const_cast<DexFile::CodeItem*>(method.GetCodeItem());
if (item != nullptr) {
CodeItemInstructionAccessor instructions(*dex, item);
if (instructions.begin() != instructions.end()) {
@@ -714,7 +708,6 @@
}
}
}
- it.Next();
}
}
CHECK(mutated_successfully)
diff --git a/libdexfile/dex/class_accessor.h b/libdexfile/dex/class_accessor.h
index 896fcad..9b9ac87 100644
--- a/libdexfile/dex/class_accessor.h
+++ b/libdexfile/dex/class_accessor.h
@@ -61,6 +61,10 @@
return dex_file_;
}
+ const uint8_t* GetDataPointer() const {
+ return ptr_pos_;
+ }
+
protected:
// Internal data pointer for reading.
const DexFile& dex_file_;
diff --git a/libdexfile/dex/dex_file_verifier_test.cc b/libdexfile/dex/dex_file_verifier_test.cc
index 78b53a0..a22a457 100644
--- a/libdexfile/dex/dex_file_verifier_test.cc
+++ b/libdexfile/dex/dex_file_verifier_test.cc
@@ -25,6 +25,7 @@
#include "base/leb128.h"
#include "base/macros.h"
#include "base64_test_util.h"
+#include "class_accessor-inl.h"
#include "descriptors_names.h"
#include "dex_file-inl.h"
#include "dex_file_loader.h"
@@ -238,27 +239,10 @@
static const uint8_t* FindMethodData(const DexFile* dex_file,
const char* name,
/*out*/ uint32_t* method_idx = nullptr) {
- const DexFile::ClassDef& class_def = dex_file->GetClassDef(0);
- const uint8_t* class_data = dex_file->GetClassData(class_def);
+ ClassAccessor accessor(*dex_file, dex_file->GetClassDef(0));
- ClassDataItemIterator it(*dex_file, class_data);
-
- const uint8_t* trailing = class_data;
- // Need to manually decode the four entries. DataPointer() doesn't work for this, as the first
- // element has already been loaded into the iterator.
- DecodeUnsignedLeb128(&trailing);
- DecodeUnsignedLeb128(&trailing);
- DecodeUnsignedLeb128(&trailing);
- DecodeUnsignedLeb128(&trailing);
-
- // Skip all fields.
- while (it.HasNextStaticField() || it.HasNextInstanceField()) {
- trailing = it.DataPointer();
- it.Next();
- }
-
- while (it.HasNextMethod()) {
- uint32_t method_index = it.GetMemberIndex();
+ for (const ClassAccessor::Method& method : accessor.GetMethods()) {
+ uint32_t method_index = method.GetIndex();
dex::StringIndex name_index = dex_file->GetMethodId(method_index).name_idx_;
const DexFile::StringId& string_id = dex_file->GetStringId(name_index);
const char* str = dex_file->GetStringData(string_id);
@@ -266,12 +250,11 @@
if (method_idx != nullptr) {
*method_idx = method_index;
}
- DecodeUnsignedLeb128(&trailing);
+ // Go back 2 lebs to the access flags.
+ const uint8_t* trailing = ReverseSearchUnsignedLeb128(method.GetDataPointer());
+ trailing = ReverseSearchUnsignedLeb128(trailing);
return trailing;
}
-
- trailing = it.DataPointer();
- it.Next();
}
return nullptr;
@@ -849,31 +832,17 @@
// is to the access flags, so that the caller doesn't have to handle the leb128-encoded method-index
// delta.
static const uint8_t* FindFieldData(const DexFile* dex_file, const char* name) {
- const DexFile::ClassDef& class_def = dex_file->GetClassDef(0);
- const uint8_t* class_data = dex_file->GetClassData(class_def);
+ ClassAccessor accessor(*dex_file, dex_file->GetClassDef(0));
- ClassDataItemIterator it(*dex_file, class_data);
-
- const uint8_t* trailing = class_data;
- // Need to manually decode the four entries. DataPointer() doesn't work for this, as the first
- // element has already been loaded into the iterator.
- DecodeUnsignedLeb128(&trailing);
- DecodeUnsignedLeb128(&trailing);
- DecodeUnsignedLeb128(&trailing);
- DecodeUnsignedLeb128(&trailing);
-
- while (it.HasNextStaticField() || it.HasNextInstanceField()) {
- uint32_t field_index = it.GetMemberIndex();
+ for (const ClassAccessor::Field& field : accessor.GetFields()) {
+ uint32_t field_index = field.GetIndex();
dex::StringIndex name_index = dex_file->GetFieldId(field_index).name_idx_;
const DexFile::StringId& string_id = dex_file->GetStringId(name_index);
const char* str = dex_file->GetStringData(string_id);
if (strcmp(name, str) == 0) {
- DecodeUnsignedLeb128(&trailing);
- return trailing;
+ // Go to the back of the access flags.
+ return ReverseSearchUnsignedLeb128(field.GetDataPointer());
}
-
- trailing = it.DataPointer();
- it.Next();
}
return nullptr;