Finish adding checks to dex ir verification.

Adds missing checks for class defs, annotations, class data, code, etc.

Bug: 36107940
Test: mm test-art-host
Change-Id: Ifaac07299cf237827160c29b4230b0dc0845dc41
diff --git a/dexlayout/dex_ir.h b/dexlayout/dex_ir.h
index 96afb90..78ddde8 100644
--- a/dexlayout/dex_ir.h
+++ b/dexlayout/dex_ir.h
@@ -748,8 +748,7 @@
   const TypeId* ClassType() const { return class_type_; }
   uint32_t GetAccessFlags() const { return access_flags_; }
   const TypeId* Superclass() const { return superclass_; }
-  const TypeIdVector* Interfaces()
-      { return interfaces_ == nullptr ? nullptr : interfaces_->GetTypeList(); }
+  const TypeList* Interfaces() { return interfaces_; }
   uint32_t InterfacesOffset() { return interfaces_ == nullptr ? 0 : interfaces_->GetOffset(); }
   const StringId* SourceFile() const { return source_file_; }
   AnnotationsDirectoryItem* Annotations() const { return annotations_; }
@@ -781,7 +780,7 @@
   uint32_t GetAddress() const { return address_; }
 
  private:
-  const TypeId* type_id_;
+  const TypeId* type_id_;  // This can be nullptr.
   uint32_t address_;
 
   DISALLOW_COPY_AND_ASSIGN(TypeAddrPair);
diff --git a/dexlayout/dex_verify.cc b/dexlayout/dex_verify.cc
index aec1d0c..5458129 100644
--- a/dexlayout/dex_verify.cc
+++ b/dexlayout/dex_verify.cc
@@ -20,6 +20,8 @@
 
 #include "dex_verify.h"
 
+#include <inttypes.h>
+
 #include "android-base/stringprintf.h"
 
 namespace art {
@@ -32,7 +34,7 @@
   dex_ir::Collections& orig = orig_header->GetCollections();
   dex_ir::Collections& output = output_header->GetCollections();
 
-  // Compare all id sections.
+  // Compare all id sections. They have a defined order that can't be changed by dexlayout.
   if (!VerifyIds(orig.StringIds(), output.StringIds(), "string ids", error_msg) ||
       !VerifyIds(orig.TypeIds(), output.TypeIds(), "type ids", error_msg) ||
       !VerifyIds(orig.ProtoIds(), output.ProtoIds(), "proto ids", error_msg) ||
@@ -40,6 +42,10 @@
       !VerifyIds(orig.MethodIds(), output.MethodIds(), "method ids", error_msg)) {
     return false;
   }
+  // Compare class defs. The order may have been changed by dexlayout.
+  if (!VerifyClassDefs(orig.ClassDefs(), output.ClassDefs(), error_msg)) {
+    return false;
+  }
   return true;
 }
 
@@ -49,7 +55,7 @@
                                  std::string* error_msg) {
   if (orig.size() != output.size()) {
     *error_msg = StringPrintf(
-        "Mismatched size for %s section, %zu vs %zu.", section_name, orig.size(), output.size());
+        "Mismatched size for %s section: %zu vs %zu.", section_name, orig.size(), output.size());
     return false;
   }
   for (size_t i = 0; i < orig.size(); ++i) {
@@ -62,7 +68,7 @@
 
 bool VerifyId(dex_ir::StringId* orig, dex_ir::StringId* output, std::string* error_msg) {
   if (strcmp(orig->Data(), output->Data()) != 0) {
-    *error_msg = StringPrintf("Mismatched string data for string id %u @ orig offset %x, %s vs %s.",
+    *error_msg = StringPrintf("Mismatched string data for string id %u at offset %x: %s vs %s.",
                               orig->GetIndex(),
                               orig->GetOffset(),
                               orig->Data(),
@@ -74,7 +80,7 @@
 
 bool VerifyId(dex_ir::TypeId* orig, dex_ir::TypeId* output, std::string* error_msg) {
   if (orig->GetStringId()->GetIndex() != output->GetStringId()->GetIndex()) {
-    *error_msg = StringPrintf("Mismatched string index for type id %u @ orig offset %x, %u vs %u.",
+    *error_msg = StringPrintf("Mismatched string index for type id %u at offset %x: %u vs %u.",
                               orig->GetIndex(),
                               orig->GetOffset(),
                               orig->GetStringId()->GetIndex(),
@@ -86,7 +92,7 @@
 
 bool VerifyId(dex_ir::ProtoId* orig, dex_ir::ProtoId* output, std::string* error_msg) {
   if (orig->Shorty()->GetIndex() != output->Shorty()->GetIndex()) {
-    *error_msg = StringPrintf("Mismatched string index for proto id %u @ orig offset %x, %u vs %u.",
+    *error_msg = StringPrintf("Mismatched string index for proto id %u at offset %x: %u vs %u.",
                               orig->GetIndex(),
                               orig->GetOffset(),
                               orig->Shorty()->GetIndex(),
@@ -94,7 +100,7 @@
     return false;
   }
   if (orig->ReturnType()->GetIndex() != output->ReturnType()->GetIndex()) {
-    *error_msg = StringPrintf("Mismatched type index for proto id %u @ orig offset %x, %u vs %u.",
+    *error_msg = StringPrintf("Mismatched type index for proto id %u at offset %x: %u vs %u.",
                               orig->GetIndex(),
                               orig->GetOffset(),
                               orig->ReturnType()->GetIndex(),
@@ -102,7 +108,7 @@
     return false;
   }
   if (!VerifyTypeList(orig->Parameters(), output->Parameters())) {
-    *error_msg = StringPrintf("Mismatched type list for proto id %u @ orig offset %x.",
+    *error_msg = StringPrintf("Mismatched type list for proto id %u at offset %x.",
                               orig->GetIndex(),
                               orig->GetOffset());
   }
@@ -112,7 +118,7 @@
 bool VerifyId(dex_ir::FieldId* orig, dex_ir::FieldId* output, std::string* error_msg) {
   if (orig->Class()->GetIndex() != output->Class()->GetIndex()) {
     *error_msg =
-        StringPrintf("Mismatched class type index for field id %u @ orig offset %x, %u vs %u.",
+        StringPrintf("Mismatched class type index for field id %u at offset %x: %u vs %u.",
                      orig->GetIndex(),
                      orig->GetOffset(),
                      orig->Class()->GetIndex(),
@@ -120,7 +126,7 @@
     return false;
   }
   if (orig->Type()->GetIndex() != output->Type()->GetIndex()) {
-    *error_msg = StringPrintf("Mismatched type index for field id %u @ orig offset %x, %u vs %u.",
+    *error_msg = StringPrintf("Mismatched type index for field id %u at offset %x: %u vs %u.",
                               orig->GetIndex(),
                               orig->GetOffset(),
                               orig->Class()->GetIndex(),
@@ -128,7 +134,7 @@
     return false;
   }
   if (orig->Name()->GetIndex() != output->Name()->GetIndex()) {
-    *error_msg = StringPrintf("Mismatched string index for field id %u @ orig offset %x, %u vs %u.",
+    *error_msg = StringPrintf("Mismatched string index for field id %u at offset %x: %u vs %u.",
                               orig->GetIndex(),
                               orig->GetOffset(),
                               orig->Name()->GetIndex(),
@@ -140,7 +146,7 @@
 
 bool VerifyId(dex_ir::MethodId* orig, dex_ir::MethodId* output, std::string* error_msg) {
   if (orig->Class()->GetIndex() != output->Class()->GetIndex()) {
-    *error_msg = StringPrintf("Mismatched type index for method id %u @ orig offset %x, %u vs %u.",
+    *error_msg = StringPrintf("Mismatched type index for method id %u at offset %x: %u vs %u.",
                               orig->GetIndex(),
                               orig->GetOffset(),
                               orig->Class()->GetIndex(),
@@ -148,7 +154,7 @@
     return false;
   }
   if (orig->Proto()->GetIndex() != output->Proto()->GetIndex()) {
-    *error_msg = StringPrintf("Mismatched proto index for method id %u @ orig offset %x, %u vs %u.",
+    *error_msg = StringPrintf("Mismatched proto index for method id %u at offset %x: %u vs %u.",
                               orig->GetIndex(),
                               orig->GetOffset(),
                               orig->Class()->GetIndex(),
@@ -157,7 +163,7 @@
   }
   if (orig->Name()->GetIndex() != output->Name()->GetIndex()) {
     *error_msg =
-        StringPrintf("Mismatched string index for method id %u @ orig offset %x, %u vs %u.",
+        StringPrintf("Mismatched string index for method id %u at offset %x: %u vs %u.",
                      orig->GetIndex(),
                      orig->GetOffset(),
                      orig->Name()->GetIndex(),
@@ -167,6 +173,96 @@
   return true;
 }
 
+struct ClassDefCompare {
+  bool operator()(dex_ir::ClassDef* lhs, dex_ir::ClassDef* rhs) const {
+    return lhs->ClassType()->GetIndex() < rhs->ClassType()->GetIndex();
+  }
+};
+
+// The class defs may have a new order due to dexlayout. Use the class's class_idx to uniquely
+// identify them and sort them for comparison.
+bool VerifyClassDefs(std::vector<std::unique_ptr<dex_ir::ClassDef>>& orig,
+                     std::vector<std::unique_ptr<dex_ir::ClassDef>>& output,
+                     std::string* error_msg) {
+  if (orig.size() != output.size()) {
+    *error_msg = StringPrintf(
+        "Mismatched size for class defs section: %zu vs %zu.", orig.size(), output.size());
+    return false;
+  }
+  // Store the class defs into sets sorted by the class's type index.
+  std::set<dex_ir::ClassDef*, ClassDefCompare> orig_set;
+  std::set<dex_ir::ClassDef*, ClassDefCompare> output_set;
+  for (size_t i = 0; i < orig.size(); ++i) {
+    orig_set.insert(orig[i].get());
+    output_set.insert(output[i].get());
+  }
+  auto orig_iter = orig_set.begin();
+  auto output_iter = output_set.begin();
+  while (orig_iter != orig_set.end() && output_iter != output_set.end()) {
+    if (!VerifyClassDef(*orig_iter, *output_iter, error_msg)) {
+      return false;
+    }
+    orig_iter++;
+    output_iter++;
+  }
+  return true;
+}
+
+bool VerifyClassDef(dex_ir::ClassDef* orig, dex_ir::ClassDef* output, std::string* error_msg) {
+  if (orig->ClassType()->GetIndex() != output->ClassType()->GetIndex()) {
+    *error_msg =
+        StringPrintf("Mismatched class type index for class def %u at offset %x: %u vs %u.",
+                     orig->GetIndex(),
+                     orig->GetOffset(),
+                     orig->ClassType()->GetIndex(),
+                     output->ClassType()->GetIndex());
+    return false;
+  }
+  if (orig->GetAccessFlags() != output->GetAccessFlags()) {
+    *error_msg =
+        StringPrintf("Mismatched access flags for class def %u at offset %x: %x vs %x.",
+                     orig->GetIndex(),
+                     orig->GetOffset(),
+                     orig->GetAccessFlags(),
+                     output->GetAccessFlags());
+    return false;
+  }
+  uint32_t orig_super = orig->Superclass() == nullptr ? 0 : orig->Superclass()->GetIndex();
+  uint32_t output_super = output->Superclass() == nullptr ? 0 : output->Superclass()->GetIndex();
+  if (orig_super != output_super) {
+    *error_msg =
+        StringPrintf("Mismatched super class for class def %u at offset %x: %u vs %u.",
+                     orig->GetIndex(),
+                     orig->GetOffset(),
+                     orig_super,
+                     output_super);
+    return false;
+  }
+  if (!VerifyTypeList(orig->Interfaces(), output->Interfaces())) {
+    *error_msg = StringPrintf("Mismatched type list for class def %u at offset %x.",
+                              orig->GetIndex(),
+                              orig->GetOffset());
+    return false;
+  }
+  const char* orig_source = orig->SourceFile() == nullptr ? "" : orig->SourceFile()->Data();
+  const char* output_source = output->SourceFile() == nullptr ? "" : output->SourceFile()->Data();
+  if (strcmp(orig_source, output_source) != 0) {
+    *error_msg = StringPrintf("Mismatched source file for class def %u at offset %x: %s vs %s.",
+                              orig->GetIndex(),
+                              orig->GetOffset(),
+                              orig_source,
+                              output_source);
+    return false;
+  }
+  if (!VerifyAnnotationsDirectory(orig->Annotations(), output->Annotations(), error_msg)) {
+    return false;
+  }
+  if (!VerifyClassData(orig->GetClassData(), output->GetClassData(), error_msg)) {
+    return false;
+  }
+  return VerifyEncodedArray(orig->StaticValues(), output->StaticValues(), error_msg);
+}
+
 bool VerifyTypeList(const dex_ir::TypeList* orig, const dex_ir::TypeList* output) {
   if (orig == nullptr || output == nullptr) {
     return orig == output;
@@ -184,4 +280,841 @@
   return true;
 }
 
+bool VerifyAnnotationsDirectory(dex_ir::AnnotationsDirectoryItem* orig,
+                                dex_ir::AnnotationsDirectoryItem* output,
+                                std::string* error_msg) {
+  if (orig == nullptr || output == nullptr) {
+    if (orig != output) {
+      *error_msg = "Found unexpected empty annotations directory.";
+      return false;
+    }
+    return true;
+  }
+  if (!VerifyAnnotationSet(orig->GetClassAnnotation(), output->GetClassAnnotation(), error_msg)) {
+    return false;
+  }
+  if (!VerifyFieldAnnotations(orig->GetFieldAnnotations(),
+                              output->GetFieldAnnotations(),
+                              orig->GetOffset(),
+                              error_msg)) {
+    return false;
+  }
+  if (!VerifyMethodAnnotations(orig->GetMethodAnnotations(),
+                               output->GetMethodAnnotations(),
+                               orig->GetOffset(),
+                               error_msg)) {
+    return false;
+  }
+  return VerifyParameterAnnotations(orig->GetParameterAnnotations(),
+                                    output->GetParameterAnnotations(),
+                                    orig->GetOffset(),
+                                    error_msg);
+}
+
+bool VerifyFieldAnnotations(dex_ir::FieldAnnotationVector* orig,
+                            dex_ir::FieldAnnotationVector* output,
+                            uint32_t orig_offset,
+                            std::string* error_msg) {
+  if (orig == nullptr || output == nullptr) {
+    if (orig != output) {
+      *error_msg = StringPrintf(
+          "Found unexpected empty field annotations for annotations directory at offset %x.",
+          orig_offset);
+      return false;
+    }
+    return true;
+  }
+  if (orig->size() != output->size()) {
+    *error_msg = StringPrintf(
+        "Mismatched field annotations size for annotations directory at offset %x: %zu vs %zu.",
+        orig_offset,
+        orig->size(),
+        output->size());
+    return false;
+  }
+  for (size_t i = 0; i < orig->size(); ++i) {
+    dex_ir::FieldAnnotation* orig_field = (*orig)[i].get();
+    dex_ir::FieldAnnotation* output_field = (*output)[i].get();
+    if (orig_field->GetFieldId()->GetIndex() != output_field->GetFieldId()->GetIndex()) {
+      *error_msg = StringPrintf(
+          "Mismatched field annotation index for annotations directory at offset %x: %u vs %u.",
+          orig_offset,
+          orig_field->GetFieldId()->GetIndex(),
+          output_field->GetFieldId()->GetIndex());
+      return false;
+    }
+    if (!VerifyAnnotationSet(orig_field->GetAnnotationSetItem(),
+                             output_field->GetAnnotationSetItem(),
+                             error_msg)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool VerifyMethodAnnotations(dex_ir::MethodAnnotationVector* orig,
+                             dex_ir::MethodAnnotationVector* output,
+                             uint32_t orig_offset,
+                             std::string* error_msg) {
+  if (orig == nullptr || output == nullptr) {
+    if (orig != output) {
+      *error_msg = StringPrintf(
+          "Found unexpected empty method annotations for annotations directory at offset %x.",
+          orig_offset);
+      return false;
+    }
+    return true;
+  }
+  if (orig->size() != output->size()) {
+    *error_msg = StringPrintf(
+        "Mismatched method annotations size for annotations directory at offset %x: %zu vs %zu.",
+        orig_offset,
+        orig->size(),
+        output->size());
+    return false;
+  }
+  for (size_t i = 0; i < orig->size(); ++i) {
+    dex_ir::MethodAnnotation* orig_method = (*orig)[i].get();
+    dex_ir::MethodAnnotation* output_method = (*output)[i].get();
+    if (orig_method->GetMethodId()->GetIndex() != output_method->GetMethodId()->GetIndex()) {
+      *error_msg = StringPrintf(
+          "Mismatched method annotation index for annotations directory at offset %x: %u vs %u.",
+          orig_offset,
+          orig_method->GetMethodId()->GetIndex(),
+          output_method->GetMethodId()->GetIndex());
+      return false;
+    }
+    if (!VerifyAnnotationSet(orig_method->GetAnnotationSetItem(),
+                             output_method->GetAnnotationSetItem(),
+                             error_msg)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool VerifyParameterAnnotations(dex_ir::ParameterAnnotationVector* orig,
+                                dex_ir::ParameterAnnotationVector* output,
+                                uint32_t orig_offset,
+                                std::string* error_msg) {
+  if (orig == nullptr || output == nullptr) {
+    if (orig != output) {
+      *error_msg = StringPrintf(
+          "Found unexpected empty parameter annotations for annotations directory at offset %x.",
+          orig_offset);
+      return false;
+    }
+    return true;
+  }
+  if (orig->size() != output->size()) {
+    *error_msg = StringPrintf(
+        "Mismatched parameter annotations size for annotations directory at offset %x: %zu vs %zu.",
+        orig_offset,
+        orig->size(),
+        output->size());
+    return false;
+  }
+  for (size_t i = 0; i < orig->size(); ++i) {
+    dex_ir::ParameterAnnotation* orig_param = (*orig)[i].get();
+    dex_ir::ParameterAnnotation* output_param = (*output)[i].get();
+    if (orig_param->GetMethodId()->GetIndex() != output_param->GetMethodId()->GetIndex()) {
+      *error_msg = StringPrintf(
+          "Mismatched parameter annotation index for annotations directory at offset %x: %u vs %u.",
+          orig_offset,
+          orig_param->GetMethodId()->GetIndex(),
+          output_param->GetMethodId()->GetIndex());
+      return false;
+    }
+    if (!VerifyAnnotationSetRefList(orig_param->GetAnnotations(),
+                                    output_param->GetAnnotations(),
+                                    error_msg)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool VerifyAnnotationSetRefList(dex_ir::AnnotationSetRefList* orig,
+                                dex_ir::AnnotationSetRefList* output,
+                                std::string* error_msg) {
+  std::vector<dex_ir::AnnotationSetItem*>* orig_items = orig->GetItems();
+  std::vector<dex_ir::AnnotationSetItem*>* output_items = output->GetItems();
+  if (orig_items->size() != output_items->size()) {
+    *error_msg = StringPrintf(
+        "Mismatched annotation set ref list size at offset %x: %zu vs %zu.",
+        orig->GetOffset(),
+        orig_items->size(),
+        output_items->size());
+    return false;
+  }
+  for (size_t i = 0; i < orig_items->size(); ++i) {
+    if (!VerifyAnnotationSet((*orig_items)[i], (*output_items)[i], error_msg)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool VerifyAnnotationSet(dex_ir::AnnotationSetItem* orig,
+                         dex_ir::AnnotationSetItem* output,
+                         std::string* error_msg) {
+  if (orig == nullptr || output == nullptr) {
+    if (orig != output) {
+      *error_msg = "Found unexpected empty annotation set.";
+      return false;
+    }
+    return true;
+  }
+  std::vector<dex_ir::AnnotationItem*>* orig_items = orig->GetItems();
+  std::vector<dex_ir::AnnotationItem*>* output_items = output->GetItems();
+  if (orig_items->size() != output_items->size()) {
+    *error_msg = StringPrintf("Mismatched size for annotation set at offset %x: %zu vs %zu.",
+                              orig->GetOffset(),
+                              orig_items->size(),
+                              output_items->size());
+    return false;
+  }
+  for (size_t i = 0; i < orig_items->size(); ++i) {
+    if (!VerifyAnnotation((*orig_items)[i], (*output_items)[i], error_msg)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool VerifyAnnotation(dex_ir::AnnotationItem* orig,
+                      dex_ir::AnnotationItem* output,
+                      std::string* error_msg) {
+  if (orig->GetVisibility() != output->GetVisibility()) {
+    *error_msg = StringPrintf("Mismatched visibility for annotation at offset %x: %u vs %u.",
+                              orig->GetOffset(),
+                              orig->GetVisibility(),
+                              output->GetVisibility());
+    return false;
+  }
+  return VerifyEncodedAnnotation(orig->GetAnnotation(),
+                                 output->GetAnnotation(),
+                                 orig->GetOffset(),
+                                 error_msg);
+}
+
+bool VerifyEncodedAnnotation(dex_ir::EncodedAnnotation* orig,
+                             dex_ir::EncodedAnnotation* output,
+                             uint32_t orig_offset,
+                             std::string* error_msg) {
+  if (orig->GetType()->GetIndex() != output->GetType()->GetIndex()) {
+    *error_msg = StringPrintf(
+        "Mismatched encoded annotation type for annotation at offset %x: %u vs %u.",
+        orig_offset,
+        orig->GetType()->GetIndex(),
+        output->GetType()->GetIndex());
+    return false;
+  }
+  dex_ir::AnnotationElementVector* orig_elements = orig->GetAnnotationElements();
+  dex_ir::AnnotationElementVector* output_elements = output->GetAnnotationElements();
+  if (orig_elements->size() != output_elements->size()) {
+    *error_msg = StringPrintf(
+        "Mismatched encoded annotation size for annotation at offset %x: %zu vs %zu.",
+        orig_offset,
+        orig_elements->size(),
+        output_elements->size());
+    return false;
+  }
+  for (size_t i = 0; i < orig_elements->size(); ++i) {
+    if (!VerifyAnnotationElement((*orig_elements)[i].get(),
+                                 (*output_elements)[i].get(),
+                                 orig_offset,
+                                 error_msg)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool VerifyAnnotationElement(dex_ir::AnnotationElement* orig,
+                             dex_ir::AnnotationElement* output,
+                             uint32_t orig_offset,
+                             std::string* error_msg) {
+  if (orig->GetName()->GetIndex() != output->GetName()->GetIndex()) {
+    *error_msg = StringPrintf(
+        "Mismatched annotation element name for annotation at offset %x: %u vs %u.",
+        orig_offset,
+        orig->GetName()->GetIndex(),
+        output->GetName()->GetIndex());
+    return false;
+  }
+  return VerifyEncodedValue(orig->GetValue(), output->GetValue(), orig_offset, error_msg);
+}
+
+bool VerifyEncodedValue(dex_ir::EncodedValue* orig,
+                        dex_ir::EncodedValue* output,
+                        uint32_t orig_offset,
+                        std::string* error_msg) {
+  if (orig->Type() != output->Type()) {
+    *error_msg = StringPrintf(
+        "Mismatched encoded value type for annotation or encoded array at offset %x: %d vs %d.",
+        orig_offset,
+        orig->Type(),
+        output->Type());
+    return false;
+  }
+  switch (orig->Type()) {
+    case DexFile::kDexAnnotationByte:
+      if (orig->GetByte() != output->GetByte()) {
+        *error_msg = StringPrintf("Mismatched encoded byte for annotation at offset %x: %d vs %d.",
+                                  orig_offset,
+                                  orig->GetByte(),
+                                  output->GetByte());
+        return false;
+      }
+      break;
+    case DexFile::kDexAnnotationShort:
+      if (orig->GetShort() != output->GetShort()) {
+        *error_msg = StringPrintf("Mismatched encoded short for annotation at offset %x: %d vs %d.",
+                                  orig_offset,
+                                  orig->GetShort(),
+                                  output->GetShort());
+        return false;
+      }
+      break;
+    case DexFile::kDexAnnotationChar:
+      if (orig->GetChar() != output->GetChar()) {
+        *error_msg = StringPrintf("Mismatched encoded char for annotation at offset %x: %c vs %c.",
+                                  orig_offset,
+                                  orig->GetChar(),
+                                  output->GetChar());
+        return false;
+      }
+      break;
+    case DexFile::kDexAnnotationInt:
+      if (orig->GetInt() != output->GetInt()) {
+        *error_msg = StringPrintf("Mismatched encoded int for annotation at offset %x: %d vs %d.",
+                                  orig_offset,
+                                  orig->GetInt(),
+                                  output->GetInt());
+        return false;
+      }
+      break;
+    case DexFile::kDexAnnotationLong:
+      if (orig->GetLong() != output->GetLong()) {
+        *error_msg = StringPrintf(
+            "Mismatched encoded long for annotation at offset %x: %" PRId64 " vs %" PRId64 ".",
+            orig_offset,
+            orig->GetLong(),
+            output->GetLong());
+        return false;
+      }
+      break;
+    case DexFile::kDexAnnotationFloat:
+      // The float value is encoded, so compare as if it's an int.
+      if (orig->GetInt() != output->GetInt()) {
+        *error_msg = StringPrintf(
+            "Mismatched encoded float for annotation at offset %x: %x (encoded) vs %x (encoded).",
+                                  orig_offset,
+                                  orig->GetInt(),
+                                  output->GetInt());
+        return false;
+      }
+      break;
+    case DexFile::kDexAnnotationDouble:
+      // The double value is encoded, so compare as if it's a long.
+      if (orig->GetLong() != output->GetLong()) {
+        *error_msg = StringPrintf(
+            "Mismatched encoded double for annotation at offset %x: %" PRIx64
+            " (encoded) vs %" PRIx64 " (encoded).",
+            orig_offset,
+            orig->GetLong(),
+            output->GetLong());
+        return false;
+      }
+      break;
+    case DexFile::kDexAnnotationString:
+      if (orig->GetStringId()->GetIndex() != output->GetStringId()->GetIndex()) {
+        *error_msg = StringPrintf(
+            "Mismatched encoded string for annotation at offset %x: %s vs %s.",
+            orig_offset,
+            orig->GetStringId()->Data(),
+            output->GetStringId()->Data());
+        return false;
+      }
+      break;
+    case DexFile::kDexAnnotationType:
+      if (orig->GetTypeId()->GetIndex() != output->GetTypeId()->GetIndex()) {
+        *error_msg = StringPrintf("Mismatched encoded type for annotation at offset %x: %u vs %u.",
+                                  orig_offset,
+                                  orig->GetTypeId()->GetIndex(),
+                                  output->GetTypeId()->GetIndex());
+        return false;
+      }
+      break;
+    case DexFile::kDexAnnotationField:
+    case DexFile::kDexAnnotationEnum:
+      if (orig->GetFieldId()->GetIndex() != output->GetFieldId()->GetIndex()) {
+        *error_msg = StringPrintf("Mismatched encoded field for annotation at offset %x: %u vs %u.",
+                                  orig_offset,
+                                  orig->GetFieldId()->GetIndex(),
+                                  output->GetFieldId()->GetIndex());
+        return false;
+      }
+      break;
+    case DexFile::kDexAnnotationMethod:
+      if (orig->GetMethodId()->GetIndex() != output->GetMethodId()->GetIndex()) {
+        *error_msg = StringPrintf(
+            "Mismatched encoded method for annotation at offset %x: %u vs %u.",
+            orig_offset,
+            orig->GetMethodId()->GetIndex(),
+            output->GetMethodId()->GetIndex());
+        return false;
+      }
+      break;
+    case DexFile::kDexAnnotationArray:
+      if (!VerifyEncodedArray(orig->GetEncodedArray(), output->GetEncodedArray(), error_msg)) {
+        return false;
+      }
+      break;
+    case DexFile::kDexAnnotationAnnotation:
+      if (!VerifyEncodedAnnotation(orig->GetEncodedAnnotation(),
+                                   output->GetEncodedAnnotation(),
+                                   orig_offset,
+                                   error_msg)) {
+        return false;
+      }
+      break;
+    case DexFile::kDexAnnotationNull:
+      break;
+    case DexFile::kDexAnnotationBoolean:
+      if (orig->GetBoolean() != output->GetBoolean()) {
+        *error_msg = StringPrintf(
+            "Mismatched encoded boolean for annotation at offset %x: %d vs %d.",
+            orig_offset,
+            orig->GetBoolean(),
+            output->GetBoolean());
+        return false;
+      }
+      break;
+    default:
+      break;
+  }
+  return true;
+}
+
+bool VerifyEncodedArray(dex_ir::EncodedArrayItem* orig,
+                        dex_ir::EncodedArrayItem* output,
+                        std::string* error_msg) {
+  if (orig == nullptr || output == nullptr) {
+    if (orig != output) {
+      *error_msg = "Found unexpected empty encoded array.";
+      return false;
+    }
+    return true;
+  }
+  dex_ir::EncodedValueVector* orig_vector = orig->GetEncodedValues();
+  dex_ir::EncodedValueVector* output_vector = output->GetEncodedValues();
+  if (orig_vector->size() != output_vector->size()) {
+    *error_msg = StringPrintf("Mismatched size for encoded array at offset %x: %zu vs %zu.",
+                              orig->GetOffset(),
+                              orig_vector->size(),
+                              output_vector->size());
+    return false;
+  }
+  for (size_t i = 0; i < orig_vector->size(); ++i) {
+    if (!VerifyEncodedValue((*orig_vector)[i].get(),
+                            (*output_vector)[i].get(),
+                            orig->GetOffset(),
+                            error_msg)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool VerifyClassData(dex_ir::ClassData* orig, dex_ir::ClassData* output, std::string* error_msg) {
+  if (orig == nullptr || output == nullptr) {
+    if (orig != output) {
+      *error_msg = "Found unexpected empty class data.";
+      return false;
+    }
+    return true;
+  }
+  if (!VerifyFields(orig->StaticFields(), output->StaticFields(), orig->GetOffset(), error_msg)) {
+    return false;
+  }
+  if (!VerifyFields(orig->InstanceFields(),
+                    output->InstanceFields(),
+                    orig->GetOffset(),
+                    error_msg)) {
+    return false;
+  }
+  if (!VerifyMethods(orig->DirectMethods(),
+                     output->DirectMethods(),
+                     orig->GetOffset(),
+                     error_msg)) {
+    return false;
+  }
+  return VerifyMethods(orig->VirtualMethods(),
+                       output->VirtualMethods(),
+                       orig->GetOffset(),
+                       error_msg);
+}
+
+bool VerifyFields(dex_ir::FieldItemVector* orig,
+                  dex_ir::FieldItemVector* output,
+                  uint32_t orig_offset,
+                  std::string* error_msg) {
+  if (orig->size() != output->size()) {
+    *error_msg = StringPrintf("Mismatched fields size for class data at offset %x: %zu vs %zu.",
+                              orig_offset,
+                              orig->size(),
+                              output->size());
+    return false;
+  }
+  for (size_t i = 0; i < orig->size(); ++i) {
+    dex_ir::FieldItem* orig_field = (*orig)[i].get();
+    dex_ir::FieldItem* output_field = (*output)[i].get();
+    if (orig_field->GetFieldId()->GetIndex() != output_field->GetFieldId()->GetIndex()) {
+      *error_msg = StringPrintf("Mismatched field index for class data at offset %x: %u vs %u.",
+                                orig_offset,
+                                orig_field->GetFieldId()->GetIndex(),
+                                output_field->GetFieldId()->GetIndex());
+      return false;
+    }
+    if (orig_field->GetAccessFlags() != output_field->GetAccessFlags()) {
+      *error_msg = StringPrintf(
+          "Mismatched field access flags for class data at offset %x: %u vs %u.",
+          orig_offset,
+          orig_field->GetAccessFlags(),
+          output_field->GetAccessFlags());
+      return false;
+    }
+  }
+  return true;
+}
+
+bool VerifyMethods(dex_ir::MethodItemVector* orig,
+                   dex_ir::MethodItemVector* output,
+                   uint32_t orig_offset,
+                   std::string* error_msg) {
+  if (orig->size() != output->size()) {
+    *error_msg = StringPrintf("Mismatched methods size for class data at offset %x: %zu vs %zu.",
+                              orig_offset,
+                              orig->size(),
+                              output->size());
+    return false;
+  }
+  for (size_t i = 0; i < orig->size(); ++i) {
+    dex_ir::MethodItem* orig_method = (*orig)[i].get();
+    dex_ir::MethodItem* output_method = (*output)[i].get();
+    if (orig_method->GetMethodId()->GetIndex() != output_method->GetMethodId()->GetIndex()) {
+      *error_msg = StringPrintf("Mismatched method index for class data at offset %x: %u vs %u.",
+                                orig_offset,
+                                orig_method->GetMethodId()->GetIndex(),
+                                output_method->GetMethodId()->GetIndex());
+      return false;
+    }
+    if (orig_method->GetAccessFlags() != output_method->GetAccessFlags()) {
+      *error_msg = StringPrintf(
+          "Mismatched method access flags for class data at offset %x: %u vs %u.",
+          orig_offset,
+          orig_method->GetAccessFlags(),
+          output_method->GetAccessFlags());
+      return false;
+    }
+    if (!VerifyCode(orig_method->GetCodeItem(), output_method->GetCodeItem(), error_msg)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool VerifyCode(dex_ir::CodeItem* orig, dex_ir::CodeItem* output, std::string* error_msg) {
+  if (orig == nullptr || output == nullptr) {
+    if (orig != output) {
+      *error_msg = "Found unexpected empty code item.";
+      return false;
+    }
+    return true;
+  }
+  if (orig->RegistersSize() != output->RegistersSize()) {
+    *error_msg = StringPrintf("Mismatched registers size for code item at offset %x: %u vs %u.",
+                              orig->GetOffset(),
+                              orig->RegistersSize(),
+                              output->RegistersSize());
+    return false;
+  }
+  if (orig->InsSize() != output->InsSize()) {
+    *error_msg = StringPrintf("Mismatched ins size for code item at offset %x: %u vs %u.",
+                              orig->GetOffset(),
+                              orig->InsSize(),
+                              output->InsSize());
+    return false;
+  }
+  if (orig->OutsSize() != output->OutsSize()) {
+    *error_msg = StringPrintf("Mismatched outs size for code item at offset %x: %u vs %u.",
+                              orig->GetOffset(),
+                              orig->OutsSize(),
+                              output->OutsSize());
+    return false;
+  }
+  if (orig->TriesSize() != output->TriesSize()) {
+    *error_msg = StringPrintf("Mismatched tries size for code item at offset %x: %u vs %u.",
+                              orig->GetOffset(),
+                              orig->TriesSize(),
+                              output->TriesSize());
+    return false;
+  }
+  if (!VerifyDebugInfo(orig->DebugInfo(), output->DebugInfo(), error_msg)) {
+    return false;
+  }
+  if (orig->InsnsSize() != output->InsnsSize()) {
+    *error_msg = StringPrintf("Mismatched insns size for code item at offset %x: %u vs %u.",
+                              orig->GetOffset(),
+                              orig->InsnsSize(),
+                              output->InsnsSize());
+    return false;
+  }
+  if (memcmp(orig->Insns(), output->Insns(), orig->InsnsSize()) != 0) {
+    *error_msg = StringPrintf("Mismatched insns for code item at offset %x.",
+                              orig->GetOffset());
+    return false;
+  }
+  if (!VerifyTries(orig->Tries(), output->Tries(), orig->GetOffset(), error_msg)) {
+    return false;
+  }
+  return VerifyHandlers(orig->Handlers(), output->Handlers(), orig->GetOffset(), error_msg);
+}
+
+bool VerifyDebugInfo(dex_ir::DebugInfoItem* orig,
+                     dex_ir::DebugInfoItem* output,
+                     std::string* error_msg) {
+  if (orig == nullptr || output == nullptr) {
+    if (orig != output) {
+      *error_msg = "Found unexpected empty debug info.";
+      return false;
+    }
+    return true;
+  }
+  if (!VerifyPositionInfo(orig->GetPositionInfo(),
+                          output->GetPositionInfo(),
+                          orig->GetOffset(),
+                          error_msg)) {
+    return false;
+  }
+  return VerifyLocalInfo(orig->GetLocalInfo(),
+                         output->GetLocalInfo(),
+                         orig->GetOffset(),
+                         error_msg);
+}
+
+bool VerifyPositionInfo(dex_ir::PositionInfoVector& orig,
+                        dex_ir::PositionInfoVector& output,
+                        uint32_t orig_offset,
+                        std::string* error_msg) {
+  if (orig.size() != output.size()) {
+    *error_msg = StringPrintf(
+        "Mismatched number of positions for debug info at offset %x: %zu vs %zu.",
+        orig_offset,
+        orig.size(),
+        output.size());
+    return false;
+  }
+  for (size_t i = 0; i < orig.size(); ++i) {
+    if (orig[i]->address_ != output[i]->address_) {
+      *error_msg = StringPrintf(
+          "Mismatched position address for debug info at offset %x: %u vs %u.",
+          orig_offset,
+          orig[i]->address_,
+          output[i]->address_);
+      return false;
+    }
+    if (orig[i]->line_ != output[i]->line_) {
+      *error_msg = StringPrintf("Mismatched position line for debug info at offset %x: %u vs %u.",
+                                orig_offset,
+                                orig[i]->line_,
+                                output[i]->line_);
+      return false;
+    }
+  }
+  return true;
+}
+
+bool VerifyLocalInfo(dex_ir::LocalInfoVector& orig,
+                     dex_ir::LocalInfoVector& output,
+                     uint32_t orig_offset,
+                     std::string* error_msg) {
+  if (orig.size() != output.size()) {
+    *error_msg = StringPrintf(
+        "Mismatched number of locals for debug info at offset %x: %zu vs %zu.",
+        orig_offset,
+        orig.size(),
+        output.size());
+    return false;
+  }
+  for (size_t i = 0; i < orig.size(); ++i) {
+    if (orig[i]->name_ != output[i]->name_) {
+      *error_msg = StringPrintf("Mismatched local name for debug info at offset %x: %s vs %s.",
+                                orig_offset,
+                                orig[i]->name_.c_str(),
+                                output[i]->name_.c_str());
+      return false;
+    }
+    if (orig[i]->descriptor_ != output[i]->descriptor_) {
+      *error_msg = StringPrintf(
+          "Mismatched local descriptor for debug info at offset %x: %s vs %s.",
+          orig_offset,
+          orig[i]->descriptor_.c_str(),
+          output[i]->descriptor_.c_str());
+      return false;
+    }
+    if (orig[i]->signature_ != output[i]->signature_) {
+      *error_msg = StringPrintf("Mismatched local signature for debug info at offset %x: %s vs %s.",
+                                orig_offset,
+                                orig[i]->signature_.c_str(),
+                                output[i]->signature_.c_str());
+      return false;
+    }
+    if (orig[i]->start_address_ != output[i]->start_address_) {
+      *error_msg = StringPrintf(
+          "Mismatched local start address for debug info at offset %x: %u vs %u.",
+          orig_offset,
+          orig[i]->start_address_,
+          output[i]->start_address_);
+      return false;
+    }
+    if (orig[i]->end_address_ != output[i]->end_address_) {
+      *error_msg = StringPrintf(
+          "Mismatched local end address for debug info at offset %x: %u vs %u.",
+          orig_offset,
+          orig[i]->end_address_,
+          output[i]->end_address_);
+      return false;
+    }
+    if (orig[i]->reg_ != output[i]->reg_) {
+      *error_msg = StringPrintf("Mismatched local reg for debug info at offset %x: %u vs %u.",
+                                orig_offset,
+                                orig[i]->reg_,
+                                output[i]->reg_);
+      return false;
+    }
+  }
+  return true;
+}
+
+bool VerifyTries(dex_ir::TryItemVector* orig,
+                 dex_ir::TryItemVector* output,
+                 uint32_t orig_offset,
+                 std::string* error_msg) {
+  if (orig == nullptr || output == nullptr) {
+    if (orig != output) {
+      *error_msg = "Found unexpected empty try items.";
+      return false;
+    }
+    return true;
+  }
+  if (orig->size() != output->size()) {
+    *error_msg = StringPrintf("Mismatched tries size for code item at offset %x: %zu vs %zu.",
+                              orig_offset,
+                              orig->size(),
+                              output->size());
+    return false;
+  }
+  for (size_t i = 0; i < orig->size(); ++i) {
+    const dex_ir::TryItem* orig_try = (*orig)[i].get();
+    const dex_ir::TryItem* output_try = (*output)[i].get();
+    if (orig_try->StartAddr() != output_try->StartAddr()) {
+      *error_msg = StringPrintf(
+          "Mismatched try item start addr for code item at offset %x: %u vs %u.",
+          orig_offset,
+          orig_try->StartAddr(),
+          output_try->StartAddr());
+      return false;
+    }
+    if (orig_try->InsnCount() != output_try->InsnCount()) {
+      *error_msg = StringPrintf(
+          "Mismatched try item insn count for code item at offset %x: %u vs %u.",
+          orig_offset,
+          orig_try->InsnCount(),
+                                output_try->InsnCount());
+      return false;
+    }
+    if (!VerifyHandler(orig_try->GetHandlers(),
+                       output_try->GetHandlers(),
+                       orig_offset,
+                       error_msg)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool VerifyHandlers(dex_ir::CatchHandlerVector* orig,
+                    dex_ir::CatchHandlerVector* output,
+                    uint32_t orig_offset,
+                    std::string* error_msg) {
+  if (orig == nullptr || output == nullptr) {
+    if (orig != output) {
+      *error_msg = "Found unexpected empty catch handlers.";
+      return false;
+    }
+    return true;
+  }
+  if (orig->size() != output->size()) {
+    *error_msg = StringPrintf(
+        "Mismatched catch handlers size for code item at offset %x: %zu vs %zu.",
+        orig_offset,
+        orig->size(),
+        output->size());
+    return false;
+  }
+  for (size_t i = 0; i < orig->size(); ++i) {
+    if (!VerifyHandler((*orig)[i].get(), (*output)[i].get(), orig_offset, error_msg)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool VerifyHandler(const dex_ir::CatchHandler* orig,
+                   const dex_ir::CatchHandler* output,
+                   uint32_t orig_offset,
+                   std::string* error_msg) {
+  dex_ir::TypeAddrPairVector* orig_handlers = orig->GetHandlers();
+  dex_ir::TypeAddrPairVector* output_handlers = output->GetHandlers();
+  if (orig_handlers->size() != output_handlers->size()) {
+    *error_msg = StringPrintf(
+        "Mismatched number of catch handlers for code item at offset %x: %zu vs %zu.",
+        orig_offset,
+        orig_handlers->size(),
+        output_handlers->size());
+    return false;
+  }
+  for (size_t i = 0; i < orig_handlers->size(); ++i) {
+    const dex_ir::TypeAddrPair* orig_handler = (*orig_handlers)[i].get();
+    const dex_ir::TypeAddrPair* output_handler = (*output_handlers)[i].get();
+    if (orig_handler->GetTypeId() == nullptr || output_handler->GetTypeId() == nullptr) {
+      if (orig_handler->GetTypeId() != output_handler->GetTypeId()) {
+        *error_msg = StringPrintf(
+            "Found unexpected catch all catch handler for code item at offset %x.",
+            orig_offset);
+        return false;
+      }
+    } else if (orig_handler->GetTypeId()->GetIndex() != output_handler->GetTypeId()->GetIndex()) {
+      *error_msg = StringPrintf(
+          "Mismatched catch handler type for code item at offset %x: %u vs %u.",
+          orig_offset,
+          orig_handler->GetTypeId()->GetIndex(),
+          output_handler->GetTypeId()->GetIndex());
+      return false;
+    }
+    if (orig_handler->GetAddress() != output_handler->GetAddress()) {
+      *error_msg = StringPrintf(
+          "Mismatched catch handler address for code item at offset %x: %u vs %u.",
+          orig_offset,
+          orig_handler->GetAddress(),
+          output_handler->GetAddress());
+      return false;
+    }
+  }
+  return true;
+}
+
 }  // namespace art
diff --git a/dexlayout/dex_verify.h b/dexlayout/dex_verify.h
index a19431c..58c95d6 100644
--- a/dexlayout/dex_verify.h
+++ b/dexlayout/dex_verify.h
@@ -24,12 +24,12 @@
 #include "dex_ir.h"
 
 namespace art {
-
 // Check that the output dex file contains the same data as the original.
 // Compares the dex IR of both dex files. Allows the dex files to have different layouts.
 bool VerifyOutputDexFile(dex_ir::Header* orig_header,
                          dex_ir::Header* output_header,
                          std::string* error_msg);
+
 template<class T> bool VerifyIds(std::vector<std::unique_ptr<T>>& orig,
                                  std::vector<std::unique_ptr<T>>& output,
                                  const char* section_name,
@@ -39,8 +39,87 @@
 bool VerifyId(dex_ir::ProtoId* orig, dex_ir::ProtoId* output, std::string* error_msg);
 bool VerifyId(dex_ir::FieldId* orig, dex_ir::FieldId* output, std::string* error_msg);
 bool VerifyId(dex_ir::MethodId* orig, dex_ir::MethodId* output, std::string* error_msg);
+
+bool VerifyClassDefs(std::vector<std::unique_ptr<dex_ir::ClassDef>>& orig,
+                     std::vector<std::unique_ptr<dex_ir::ClassDef>>& output,
+                     std::string* error_msg);
+bool VerifyClassDef(dex_ir::ClassDef* orig, dex_ir::ClassDef* output, std::string* error_msg);
+
 bool VerifyTypeList(const dex_ir::TypeList* orig, const dex_ir::TypeList* output);
 
+bool VerifyAnnotationsDirectory(dex_ir::AnnotationsDirectoryItem* orig,
+                                dex_ir::AnnotationsDirectoryItem* output,
+                                std::string* error_msg);
+bool VerifyFieldAnnotations(dex_ir::FieldAnnotationVector* orig,
+                            dex_ir::FieldAnnotationVector* output,
+                            uint32_t orig_offset,
+                            std::string* error_msg);
+bool VerifyMethodAnnotations(dex_ir::MethodAnnotationVector* orig,
+                             dex_ir::MethodAnnotationVector* output,
+                             uint32_t orig_offset,
+                             std::string* error_msg);
+bool VerifyParameterAnnotations(dex_ir::ParameterAnnotationVector* orig,
+                                dex_ir::ParameterAnnotationVector* output,
+                                uint32_t orig_offset,
+                                std::string* error_msg);
+bool VerifyAnnotationSetRefList(dex_ir::AnnotationSetRefList* orig,
+                                dex_ir::AnnotationSetRefList* output,
+                                std::string* error_msg);
+bool VerifyAnnotationSet(dex_ir::AnnotationSetItem* orig,
+                         dex_ir::AnnotationSetItem* output,
+                         std::string* error_msg);
+bool VerifyAnnotation(dex_ir::AnnotationItem* orig,
+                      dex_ir::AnnotationItem* output,
+                      std::string* error_msg);
+bool VerifyEncodedAnnotation(dex_ir::EncodedAnnotation* orig,
+                             dex_ir::EncodedAnnotation* output,
+                             uint32_t orig_offset,
+                             std::string* error_msg);
+bool VerifyAnnotationElement(dex_ir::AnnotationElement* orig,
+                             dex_ir::AnnotationElement* output,
+                             uint32_t orig_offset,
+                             std::string* error_msg);
+bool VerifyEncodedValue(dex_ir::EncodedValue* orig,
+                        dex_ir::EncodedValue* output,
+                        uint32_t orig_offset,
+                        std::string* error_msg);
+bool VerifyEncodedArray(dex_ir::EncodedArrayItem* orig,
+                        dex_ir::EncodedArrayItem* output,
+                        std::string* error_msg);
+
+bool VerifyClassData(dex_ir::ClassData* orig, dex_ir::ClassData* output, std::string* error_msg);
+bool VerifyFields(dex_ir::FieldItemVector* orig,
+                  dex_ir::FieldItemVector* output,
+                  uint32_t orig_offset,
+                  std::string* error_msg);
+bool VerifyMethods(dex_ir::MethodItemVector* orig,
+                   dex_ir::MethodItemVector* output,
+                   uint32_t orig_offset,
+                   std::string* error_msg);
+bool VerifyCode(dex_ir::CodeItem* orig, dex_ir::CodeItem* output, std::string* error_msg);
+bool VerifyDebugInfo(dex_ir::DebugInfoItem* orig,
+                     dex_ir::DebugInfoItem* output,
+                     std::string* error_msg);
+bool VerifyPositionInfo(dex_ir::PositionInfoVector& orig,
+                        dex_ir::PositionInfoVector& output,
+                        uint32_t orig_offset,
+                        std::string* error_msg);
+bool VerifyLocalInfo(dex_ir::LocalInfoVector& orig,
+                     dex_ir::LocalInfoVector& output,
+                     uint32_t orig_offset,
+                     std::string* error_msg);
+bool VerifyTries(dex_ir::TryItemVector* orig,
+                 dex_ir::TryItemVector* output,
+                 uint32_t orig_offset,
+                 std::string* error_msg);
+bool VerifyHandlers(dex_ir::CatchHandlerVector* orig,
+                    dex_ir::CatchHandlerVector* output,
+                    uint32_t orig_offset,
+                    std::string* error_msg);
+bool VerifyHandler(const dex_ir::CatchHandler* orig,
+                   const dex_ir::CatchHandler* output,
+                   uint32_t orig_offset,
+                   std::string* error_msg);
 }  // namespace art
 
 #endif  // ART_DEXLAYOUT_DEX_VERIFY_H_
diff --git a/dexlayout/dexlayout.cc b/dexlayout/dexlayout.cc
index a310424..615bcf9 100644
--- a/dexlayout/dexlayout.cc
+++ b/dexlayout/dexlayout.cc
@@ -1369,10 +1369,11 @@
   }
 
   // Interfaces.
-  const dex_ir::TypeIdVector* interfaces = class_def->Interfaces();
+  const dex_ir::TypeList* interfaces = class_def->Interfaces();
   if (interfaces != nullptr) {
-    for (uint32_t i = 0; i < interfaces->size(); i++) {
-      DumpInterface((*interfaces)[i], i);
+    const dex_ir::TypeIdVector* interfaces_vector = interfaces->GetTypeList();
+    for (uint32_t i = 0; i < interfaces_vector->size(); i++) {
+      DumpInterface((*interfaces_vector)[i], i);
     }  // for
   }