/*
 * Copyright (C) 2016 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.
 *
 * Implementation file of the dexlayout utility.
 *
 * This is a tool to read dex files into an internal representation,
 * reorganize the representation, and emit dex files with a better
 * file layout.
 */

#include "dexlayout.h"

#include <inttypes.h>
#include <stdio.h>

#include <cstdint>
#include <iostream>
#include <iterator>
#include <memory>
#include <sstream>
#include <unordered_set>
#include <vector>

#include "android-base/stringprintf.h"
#include "base/hiddenapi_flags.h"
#include "base/logging.h"  // For VLOG_IS_ON.
#include "base/mem_map.h"
#include "base/mman.h"  // For the PROT_* and MAP_* constants.
#include "base/os.h"
#include "base/utils.h"
#include "dex/art_dex_file_loader.h"
#include "dex/descriptors_names.h"
#include "dex/dex_file-inl.h"
#include "dex/dex_file_layout.h"
#include "dex/dex_file_loader.h"
#include "dex/dex_file_types.h"
#include "dex/dex_file_verifier.h"
#include "dex/dex_instruction-inl.h"
#include "dex_ir.h"
#include "dex_ir_builder.h"
#include "dex_verify.h"
#include "dex_visualize.h"
#include "dex_writer.h"
#include "profile/profile_compilation_info.h"

namespace art {

using android::base::StringPrintf;

/*
 * Flags for use with createAccessFlagStr().
 */
enum AccessFor {
  kAccessForClass = 0, kAccessForMethod = 1, kAccessForField = 2, kAccessForMAX
};
const int kNumFlags = 18;

/*
 * Gets 2 little-endian bytes.
 */
static inline uint16_t Get2LE(unsigned char const* src) {
  return src[0] | (src[1] << 8);
}

/*
 * Converts the class name portion of a type descriptor to human-readable
 * "dotted" form. For example, "Ljava/lang/String;" becomes "String".
 */
static std::string DescriptorClassToName(const char* str) {
  std::string descriptor(str);
  // Reduce to just the class name prefix.
  size_t last_slash = descriptor.rfind('/');
  if (last_slash == std::string::npos) {
    last_slash = 0;
  }
  // Start past the '/' or 'L'.
  last_slash++;

  // Copy class name over, trimming trailing ';'.
  size_t size = descriptor.size() - 1 - last_slash;
  std::string result(descriptor.substr(last_slash, size));

  return result;
}

/*
 * Returns string representing the boolean value.
 */
static const char* StrBool(bool val) {
  return val ? "true" : "false";
}

/*
 * Returns a quoted string representing the boolean value.
 */
static const char* QuotedBool(bool val) {
  return val ? "\"true\"" : "\"false\"";
}

/*
 * Returns a quoted string representing the access flags.
 */
static const char* QuotedVisibility(uint32_t access_flags) {
  if (access_flags & kAccPublic) {
    return "\"public\"";
  } else if (access_flags & kAccProtected) {
    return "\"protected\"";
  } else if (access_flags & kAccPrivate) {
    return "\"private\"";
  } else {
    return "\"package\"";
  }
}

/*
 * Counts the number of '1' bits in a word.
 */
static int CountOnes(uint32_t val) {
  val = val - ((val >> 1) & 0x55555555);
  val = (val & 0x33333333) + ((val >> 2) & 0x33333333);
  return (((val + (val >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
}

/*
 * Creates a new string with human-readable access flags.
 *
 * In the base language the access_flags fields are type uint16_t; in Dalvik they're uint32_t.
 */
static char* CreateAccessFlagStr(uint32_t flags, AccessFor for_what) {
  static const char* kAccessStrings[kAccessForMAX][kNumFlags] = {
    {
      "PUBLIC",                /* 0x00001 */
      "PRIVATE",               /* 0x00002 */
      "PROTECTED",             /* 0x00004 */
      "STATIC",                /* 0x00008 */
      "FINAL",                 /* 0x00010 */
      "?",                     /* 0x00020 */
      "?",                     /* 0x00040 */
      "?",                     /* 0x00080 */
      "?",                     /* 0x00100 */
      "INTERFACE",             /* 0x00200 */
      "ABSTRACT",              /* 0x00400 */
      "?",                     /* 0x00800 */
      "SYNTHETIC",             /* 0x01000 */
      "ANNOTATION",            /* 0x02000 */
      "ENUM",                  /* 0x04000 */
      "?",                     /* 0x08000 */
      "VERIFIED",              /* 0x10000 */
      "OPTIMIZED",             /* 0x20000 */
    }, {
      "PUBLIC",                /* 0x00001 */
      "PRIVATE",               /* 0x00002 */
      "PROTECTED",             /* 0x00004 */
      "STATIC",                /* 0x00008 */
      "FINAL",                 /* 0x00010 */
      "SYNCHRONIZED",          /* 0x00020 */
      "BRIDGE",                /* 0x00040 */
      "VARARGS",               /* 0x00080 */
      "NATIVE",                /* 0x00100 */
      "?",                     /* 0x00200 */
      "ABSTRACT",              /* 0x00400 */
      "STRICT",                /* 0x00800 */
      "SYNTHETIC",             /* 0x01000 */
      "?",                     /* 0x02000 */
      "?",                     /* 0x04000 */
      "MIRANDA",               /* 0x08000 */
      "CONSTRUCTOR",           /* 0x10000 */
      "DECLARED_SYNCHRONIZED", /* 0x20000 */
    }, {
      "PUBLIC",                /* 0x00001 */
      "PRIVATE",               /* 0x00002 */
      "PROTECTED",             /* 0x00004 */
      "STATIC",                /* 0x00008 */
      "FINAL",                 /* 0x00010 */
      "?",                     /* 0x00020 */
      "VOLATILE",              /* 0x00040 */
      "TRANSIENT",             /* 0x00080 */
      "?",                     /* 0x00100 */
      "?",                     /* 0x00200 */
      "?",                     /* 0x00400 */
      "?",                     /* 0x00800 */
      "SYNTHETIC",             /* 0x01000 */
      "?",                     /* 0x02000 */
      "ENUM",                  /* 0x04000 */
      "?",                     /* 0x08000 */
      "?",                     /* 0x10000 */
      "?",                     /* 0x20000 */
    },
  };

  // Allocate enough storage to hold the expected number of strings,
  // plus a space between each.  We over-allocate, using the longest
  // string above as the base metric.
  const int kLongest = 21;  // The strlen of longest string above.
  const int count = CountOnes(flags);
  char* str;
  char* cp;
  cp = str = reinterpret_cast<char*>(malloc(count * (kLongest + 1) + 1));

  for (int i = 0; i < kNumFlags; i++) {
    if (flags & 0x01) {
      const char* accessStr = kAccessStrings[for_what][i];
      const int len = strlen(accessStr);
      if (cp != str) {
        *cp++ = ' ';
      }
      memcpy(cp, accessStr, len);
      cp += len;
    }
    flags >>= 1;
  }  // for

  *cp = '\0';
  return str;
}

static std::string GetHiddenapiFlagStr(uint32_t hiddenapi_flags) {
  std::stringstream ss;
  hiddenapi::ApiList(hiddenapi_flags).Dump(ss);
  std::string api_list = ss.str();
  std::transform(api_list.begin(), api_list.end(), api_list.begin(), ::toupper);
  return api_list;
}

static std::string GetSignatureForProtoId(const dex_ir::ProtoId* proto) {
  if (proto == nullptr) {
    return "<no signature>";
  }

  std::string result("(");
  const dex_ir::TypeList* type_list = proto->Parameters();
  if (type_list != nullptr) {
    for (const dex_ir::TypeId* type_id : *type_list->GetTypeList()) {
      result += type_id->GetStringId()->Data();
    }
  }
  result += ")";
  result += proto->ReturnType()->GetStringId()->Data();
  return result;
}

/*
 * Copies character data from "data" to "out", converting non-ASCII values
 * to fprintf format chars or an ASCII filler ('.' or '?').
 *
 * The output buffer must be able to hold (2*len)+1 bytes.  The result is
 * NULL-terminated.
 */
static void Asciify(char* out, const unsigned char* data, size_t len) {
  for (; len != 0u; --len) {
    if (*data < 0x20) {
      // Could do more here, but we don't need them yet.
      switch (*data) {
        case '\0':
          *out++ = '\\';
          *out++ = '0';
          break;
        case '\n':
          *out++ = '\\';
          *out++ = 'n';
          break;
        default:
          *out++ = '.';
          break;
      }  // switch
    } else if (*data >= 0x80) {
      *out++ = '?';
    } else {
      *out++ = *data;
    }
    data++;
  }  // while
  *out = '\0';
}
/* clang-format off */
constexpr char kEscapedLength[256] = {
    4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 4, 2, 2, 4, 4,  // \a, \b, \t, \n, \r
    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
    1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // ",
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // '0'..'9'
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 'A'..'O'
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1,  // 'P'..'Z', '\'
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 'a'..'o'
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4,  // 'p'..'z', DEL
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // Unicode range, keep
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
};
/* clang-format on */

/*
 * Check if a UTF8 string contains characters we should quote.
 */
static bool needsEscape(std::string_view s) {
  for (unsigned char c : s) {
    if (kEscapedLength[c] != 1) {
      return true;
    }
  }
  return false;
}

std::string escapeString(std::string_view s) {
  std::ostringstream oss;
  for (unsigned char c : s) {
    switch (kEscapedLength[c]) {
      case 1:
        oss << static_cast<char>(c);
        break;
      case 2:
        switch (c) {
          case '\b':
            oss << '\\' << 'b';
            break;
          case '\f':
            oss << '\\' << 'f';
            break;
          case '\n':
            oss << '\\' << 'n';
            break;
          case '\r':
            oss << '\\' << 'r';
            break;
          case '\t':
            oss << '\\' << 't';
            break;
          case '\"':
            oss << '\\' << '"';
            break;
          case '\\':
            oss << '\\' << '\\';
            break;
        }
        break;
      case 4:
        oss << '\\' << '0' + (c / 64) << '0' + ((c % 64) / 8) << '0' + (c % 8);
        break;
    }
  }
  return oss.str();
}

/*
 * Dumps a string value with some escape characters.
 */
static void DumpEscapedString(std::string_view s, FILE* out_file) {
  fputs("\"", out_file);
  if (needsEscape(s)) {
    std::string e = escapeString(s);
    fputs(e.c_str(), out_file);
  } else {
    for (char c : s) {
      fputc(c, out_file);
    }
  }
  fputs("\"", out_file);
}

/*
 * Dumps a string as an XML attribute value.
 */
static void DumpXmlAttribute(const char* p, FILE* out_file) {
  for (; *p; p++) {
    switch (*p) {
      case '&':
        fputs("&amp;", out_file);
        break;
      case '<':
        fputs("&lt;", out_file);
        break;
      case '>':
        fputs("&gt;", out_file);
        break;
      case '"':
        fputs("&quot;", out_file);
        break;
      case '\t':
        fputs("&#x9;", out_file);
        break;
      case '\n':
        fputs("&#xA;", out_file);
        break;
      case '\r':
        fputs("&#xD;", out_file);
        break;
      default:
        putc(*p, out_file);
    }  // switch
  }  // for
}

/*
 * Helper for dumpInstruction(), which builds the string
 * representation for the index in the given instruction.
 * Returns a pointer to a buffer of sufficient size.
 */
static std::unique_ptr<char[]> IndexString(dex_ir::Header* header,
                                           const Instruction* dec_insn,
                                           size_t buf_size) {
  std::unique_ptr<char[]> buf(new char[buf_size]);
  // Determine index and width of the string.
  uint32_t index = 0;
  uint32_t secondary_index = dex::kDexNoIndex;
  uint32_t width = 4;
  switch (Instruction::FormatOf(dec_insn->Opcode())) {
    // SOME NOT SUPPORTED:
    // case Instruction::k20bc:
    case Instruction::k21c:
    case Instruction::k35c:
    // case Instruction::k35ms:
    case Instruction::k3rc:
    // case Instruction::k3rms:
    // case Instruction::k35mi:
    // case Instruction::k3rmi:
      index = dec_insn->VRegB();
      width = 4;
      break;
    case Instruction::k31c:
      index = dec_insn->VRegB();
      width = 8;
      break;
    case Instruction::k22c:
    // case Instruction::k22cs:
      index = dec_insn->VRegC();
      width = 4;
      break;
    case Instruction::k45cc:
    case Instruction::k4rcc:
      index = dec_insn->VRegB();
      secondary_index = dec_insn->VRegH();
      width = 4;
      break;
    default:
      break;
  }  // switch

  // Determine index type.
  size_t outSize = 0;
  switch (Instruction::IndexTypeOf(dec_insn->Opcode())) {
    case Instruction::kIndexUnknown:
      // This function should never get called for this type, but do
      // something sensible here, just to help with debugging.
      outSize = snprintf(buf.get(), buf_size, "<unknown-index>");
      break;
    case Instruction::kIndexNone:
      // This function should never get called for this type, but do
      // something sensible here, just to help with debugging.
      outSize = snprintf(buf.get(), buf_size, "<no-index>");
      break;
    case Instruction::kIndexTypeRef:
      if (index < header->TypeIds().Size()) {
        const char* tp = header->TypeIds()[index]->GetStringId()->Data();
        outSize = snprintf(buf.get(), buf_size, "%s // type@%0*x", tp, width, index);
      } else {
        outSize = snprintf(buf.get(), buf_size, "<type?> // type@%0*x", width, index);
      }
      break;
    case Instruction::kIndexStringRef:
      if (index < header->StringIds().Size()) {
        const char* st = header->StringIds()[index]->Data();
        if (needsEscape(std::string_view(st))) {
          std::string escaped = escapeString(st);
          outSize =
              snprintf(buf.get(), buf_size, "\"%s\" // string@%0*x", escaped.c_str(), width, index);
        } else {
          outSize = snprintf(buf.get(), buf_size, "\"%s\" // string@%0*x", st, width, index);
        }
      } else {
        outSize = snprintf(buf.get(), buf_size, "<string?> // string@%0*x", width, index);
      }
      break;
    case Instruction::kIndexMethodRef:
      if (index < header->MethodIds().Size()) {
        dex_ir::MethodId* method_id = header->MethodIds()[index];
        const char* name = method_id->Name()->Data();
        std::string type_descriptor = GetSignatureForProtoId(method_id->Proto());
        const char* back_descriptor = method_id->Class()->GetStringId()->Data();
        outSize = snprintf(buf.get(), buf_size, "%s.%s:%s // method@%0*x",
                           back_descriptor, name, type_descriptor.c_str(), width, index);
      } else {
        outSize = snprintf(buf.get(), buf_size, "<method?> // method@%0*x", width, index);
      }
      break;
    case Instruction::kIndexFieldRef:
      if (index < header->FieldIds().Size()) {
        dex_ir::FieldId* field_id = header->FieldIds()[index];
        const char* name = field_id->Name()->Data();
        const char* type_descriptor = field_id->Type()->GetStringId()->Data();
        const char* back_descriptor = field_id->Class()->GetStringId()->Data();
        outSize = snprintf(buf.get(), buf_size, "%s.%s:%s // field@%0*x",
                           back_descriptor, name, type_descriptor, width, index);
      } else {
        outSize = snprintf(buf.get(), buf_size, "<field?> // field@%0*x", width, index);
      }
      break;
    case Instruction::kIndexVtableOffset:
      outSize = snprintf(buf.get(), buf_size, "[%0*x] // vtable #%0*x",
                         width, index, width, index);
      break;
    case Instruction::kIndexFieldOffset:
      outSize = snprintf(buf.get(), buf_size, "[obj+%0*x]", width, index);
      break;
    case Instruction::kIndexMethodAndProtoRef: {
      std::string method("<method?>");
      std::string proto("<proto?>");
      if (index < header->MethodIds().Size()) {
        dex_ir::MethodId* method_id = header->MethodIds()[index];
        const char* name = method_id->Name()->Data();
        std::string type_descriptor = GetSignatureForProtoId(method_id->Proto());
        const char* back_descriptor = method_id->Class()->GetStringId()->Data();
        method = StringPrintf("%s.%s:%s", back_descriptor, name, type_descriptor.c_str());
      }
      if (secondary_index < header->ProtoIds().Size()) {
        dex_ir::ProtoId* proto_id = header->ProtoIds()[secondary_index];
        proto = GetSignatureForProtoId(proto_id);
      }
      outSize = snprintf(buf.get(), buf_size, "%s, %s // method@%0*x, proto@%0*x",
                         method.c_str(), proto.c_str(), width, index, width, secondary_index);
    }
    break;
    case Instruction::kIndexCallSiteRef:
      outSize = snprintf(buf.get(), buf_size, "call_site@%0*x", width, index);
      break;
    // SOME NOT SUPPORTED:
    // case Instruction::kIndexVaries:
    // case Instruction::kIndexInlineMethod:
    default:
      outSize = snprintf(buf.get(), buf_size, "<?>");
      break;
  }  // switch

  // Determine success of string construction.
  if (outSize >= buf_size) {
    // The buffer wasn't big enough; retry with computed size. Note: snprintf()
    // doesn't count/ the '\0' as part of its returned size, so we add explicit
    // space for it here.
    return IndexString(header, dec_insn, outSize + 1);
  }
  return buf;
}

/*
 * Dumps encoded annotation.
 */
void DexLayout::DumpEncodedAnnotation(dex_ir::EncodedAnnotation* annotation) {
  fputs(annotation->GetType()->GetStringId()->Data(), out_file_);
  // Display all name=value pairs.
  for (auto& subannotation : *annotation->GetAnnotationElements()) {
    fputc(' ', out_file_);
    fputs(subannotation->GetName()->Data(), out_file_);
    fputc('=', out_file_);
    DumpEncodedValue(subannotation->GetValue());
  }
}
/*
 * Dumps encoded value.
 */
void DexLayout::DumpEncodedValue(const dex_ir::EncodedValue* data) {
  switch (data->Type()) {
    case DexFile::kDexAnnotationByte:
      fprintf(out_file_, "%" PRId8, data->GetByte());
      break;
    case DexFile::kDexAnnotationShort:
      fprintf(out_file_, "%" PRId16, data->GetShort());
      break;
    case DexFile::kDexAnnotationChar:
      fprintf(out_file_, "%" PRIu16, data->GetChar());
      break;
    case DexFile::kDexAnnotationInt:
      fprintf(out_file_, "%" PRId32, data->GetInt());
      break;
    case DexFile::kDexAnnotationLong:
      fprintf(out_file_, "%" PRId64, data->GetLong());
      break;
    case DexFile::kDexAnnotationFloat: {
      fprintf(out_file_, "%g", data->GetFloat());
      break;
    }
    case DexFile::kDexAnnotationDouble: {
      fprintf(out_file_, "%g", data->GetDouble());
      break;
    }
    case DexFile::kDexAnnotationString: {
      dex_ir::StringId* string_id = data->GetStringId();
      if (options_.output_format_ == kOutputPlain) {
        DumpEscapedString(string_id->Data(), out_file_);
      } else {
        DumpXmlAttribute(string_id->Data(), out_file_);
      }
      break;
    }
    case DexFile::kDexAnnotationType: {
      dex_ir::TypeId* type_id = data->GetTypeId();
      fputs(type_id->GetStringId()->Data(), out_file_);
      break;
    }
    case DexFile::kDexAnnotationField:
    case DexFile::kDexAnnotationEnum: {
      dex_ir::FieldId* field_id = data->GetFieldId();
      fputs(field_id->Name()->Data(), out_file_);
      break;
    }
    case DexFile::kDexAnnotationMethod: {
      dex_ir::MethodId* method_id = data->GetMethodId();
      fputs(method_id->Name()->Data(), out_file_);
      break;
    }
    case DexFile::kDexAnnotationArray: {
      fputc('{', out_file_);
      // Display all elements.
      for (auto& value : *data->GetEncodedArray()->GetEncodedValues()) {
        fputc(' ', out_file_);
        DumpEncodedValue(value.get());
      }
      fputs(" }", out_file_);
      break;
    }
    case DexFile::kDexAnnotationAnnotation: {
      DumpEncodedAnnotation(data->GetEncodedAnnotation());
      break;
    }
    case DexFile::kDexAnnotationNull:
      fputs("null", out_file_);
      break;
    case DexFile::kDexAnnotationBoolean:
      fputs(StrBool(data->GetBoolean()), out_file_);
      break;
    default:
      fputs("????", out_file_);
      break;
  }  // switch
}

/*
 * Dumps the file header.
 */
void DexLayout::DumpFileHeader() {
  char sanitized[8 * 2 + 1];
  fprintf(out_file_, "DEX file header:\n");
  Asciify(sanitized, header_->Magic().data(), header_->Magic().size());
  fprintf(out_file_, "magic               : '%s'\n", sanitized);
  fprintf(out_file_, "checksum            : %08x\n", header_->Checksum());
  fprintf(out_file_, "signature           : %02x%02x...%02x%02x\n",
          header_->Signature()[0], header_->Signature()[1],
          header_->Signature()[DexFile::kSha1DigestSize - 2],
          header_->Signature()[DexFile::kSha1DigestSize - 1]);
  fprintf(out_file_, "file_size           : %d\n", header_->FileSize());
  fprintf(out_file_, "header_size         : %d\n", header_->HeaderSize());
  fprintf(out_file_, "link_size           : %d\n", header_->LinkSize());
  fprintf(out_file_, "link_off            : %d (0x%06x)\n",
          header_->LinkOffset(), header_->LinkOffset());
  fprintf(out_file_, "string_ids_size     : %d\n", header_->StringIds().Size());
  fprintf(out_file_, "string_ids_off      : %d (0x%06x)\n",
          header_->StringIds().GetOffset(), header_->StringIds().GetOffset());
  fprintf(out_file_, "type_ids_size       : %d\n", header_->TypeIds().Size());
  fprintf(out_file_, "type_ids_off        : %d (0x%06x)\n",
          header_->TypeIds().GetOffset(), header_->TypeIds().GetOffset());
  fprintf(out_file_, "proto_ids_size      : %d\n", header_->ProtoIds().Size());
  fprintf(out_file_, "proto_ids_off       : %d (0x%06x)\n",
          header_->ProtoIds().GetOffset(), header_->ProtoIds().GetOffset());
  fprintf(out_file_, "field_ids_size      : %d\n", header_->FieldIds().Size());
  fprintf(out_file_, "field_ids_off       : %d (0x%06x)\n",
          header_->FieldIds().GetOffset(), header_->FieldIds().GetOffset());
  fprintf(out_file_, "method_ids_size     : %d\n", header_->MethodIds().Size());
  fprintf(out_file_, "method_ids_off      : %d (0x%06x)\n",
          header_->MethodIds().GetOffset(), header_->MethodIds().GetOffset());
  fprintf(out_file_, "class_defs_size     : %d\n", header_->ClassDefs().Size());
  fprintf(out_file_, "class_defs_off      : %d (0x%06x)\n",
          header_->ClassDefs().GetOffset(), header_->ClassDefs().GetOffset());
  fprintf(out_file_, "data_size           : %d\n", header_->DataSize());
  fprintf(out_file_, "data_off            : %d (0x%06x)\n\n",
          header_->DataOffset(), header_->DataOffset());
}

/*
 * Dumps a class_def_item.
 */
void DexLayout::DumpClassDef(int idx) {
  // General class information.
  dex_ir::ClassDef* class_def = header_->ClassDefs()[idx];
  fprintf(out_file_, "Class #%d header:\n", idx);
  fprintf(out_file_, "class_idx           : %d\n", class_def->ClassType()->GetIndex());
  fprintf(out_file_, "access_flags        : %d (0x%04x)\n",
          class_def->GetAccessFlags(), class_def->GetAccessFlags());
  uint32_t superclass_idx =  class_def->Superclass() == nullptr ?
      DexFile::kDexNoIndex16 : class_def->Superclass()->GetIndex();
  fprintf(out_file_, "superclass_idx      : %d\n", superclass_idx);
  fprintf(out_file_, "interfaces_off      : %d (0x%06x)\n",
          class_def->InterfacesOffset(), class_def->InterfacesOffset());
  uint32_t source_file_offset = 0xffffffffU;
  if (class_def->SourceFile() != nullptr) {
    source_file_offset = class_def->SourceFile()->GetIndex();
  }
  fprintf(out_file_, "source_file_idx     : %d\n", source_file_offset);
  uint32_t annotations_offset = 0;
  if (class_def->Annotations() != nullptr) {
    annotations_offset = class_def->Annotations()->GetOffset();
  }
  fprintf(out_file_, "annotations_off     : %d (0x%06x)\n",
          annotations_offset, annotations_offset);
  if (class_def->GetClassData() == nullptr) {
    fprintf(out_file_, "class_data_off      : %d (0x%06x)\n", 0, 0);
  } else {
    fprintf(out_file_, "class_data_off      : %d (0x%06x)\n",
            class_def->GetClassData()->GetOffset(), class_def->GetClassData()->GetOffset());
  }

  // Fields and methods.
  dex_ir::ClassData* class_data = class_def->GetClassData();
  if (class_data != nullptr && class_data->StaticFields() != nullptr) {
    fprintf(out_file_, "static_fields_size  : %zu\n", class_data->StaticFields()->size());
  } else {
    fprintf(out_file_, "static_fields_size  : 0\n");
  }
  if (class_data != nullptr && class_data->InstanceFields() != nullptr) {
    fprintf(out_file_, "instance_fields_size: %zu\n", class_data->InstanceFields()->size());
  } else {
    fprintf(out_file_, "instance_fields_size: 0\n");
  }
  if (class_data != nullptr && class_data->DirectMethods() != nullptr) {
    fprintf(out_file_, "direct_methods_size : %zu\n", class_data->DirectMethods()->size());
  } else {
    fprintf(out_file_, "direct_methods_size : 0\n");
  }
  if (class_data != nullptr && class_data->VirtualMethods() != nullptr) {
    fprintf(out_file_, "virtual_methods_size: %zu\n", class_data->VirtualMethods()->size());
  } else {
    fprintf(out_file_, "virtual_methods_size: 0\n");
  }
  fprintf(out_file_, "\n");
}

/**
 * Dumps an annotation set item.
 */
void DexLayout::DumpAnnotationSetItem(dex_ir::AnnotationSetItem* set_item) {
  if (set_item == nullptr || set_item->GetItems()->size() == 0) {
    fputs("  empty-annotation-set\n", out_file_);
    return;
  }
  for (dex_ir::AnnotationItem* annotation : *set_item->GetItems()) {
    if (annotation == nullptr) {
      continue;
    }
    fputs("  ", out_file_);
    switch (annotation->GetVisibility()) {
      case DexFile::kDexVisibilityBuild:   fputs("VISIBILITY_BUILD ",   out_file_); break;
      case DexFile::kDexVisibilityRuntime: fputs("VISIBILITY_RUNTIME ", out_file_); break;
      case DexFile::kDexVisibilitySystem:  fputs("VISIBILITY_SYSTEM ",  out_file_); break;
      default:                             fputs("VISIBILITY_UNKNOWN ", out_file_); break;
    }  // switch
    DumpEncodedAnnotation(annotation->GetAnnotation());
    fputc('\n', out_file_);
  }
}

/*
 * Dumps class annotations.
 */
void DexLayout::DumpClassAnnotations(int idx) {
  dex_ir::ClassDef* class_def = header_->ClassDefs()[idx];
  dex_ir::AnnotationsDirectoryItem* annotations_directory = class_def->Annotations();
  if (annotations_directory == nullptr) {
    return;  // none
  }

  fprintf(out_file_, "Class #%d annotations:\n", idx);

  dex_ir::AnnotationSetItem* class_set_item = annotations_directory->GetClassAnnotation();
  dex_ir::FieldAnnotationVector* fields = annotations_directory->GetFieldAnnotations();
  dex_ir::MethodAnnotationVector* methods = annotations_directory->GetMethodAnnotations();
  dex_ir::ParameterAnnotationVector* parameters = annotations_directory->GetParameterAnnotations();

  // Annotations on the class itself.
  if (class_set_item != nullptr) {
    fprintf(out_file_, "Annotations on class\n");
    DumpAnnotationSetItem(class_set_item);
  }

  // Annotations on fields.
  if (fields != nullptr) {
    for (auto& field : *fields) {
      const dex_ir::FieldId* field_id = field->GetFieldId();
      const uint32_t field_idx = field_id->GetIndex();
      const char* field_name = field_id->Name()->Data();
      fprintf(out_file_, "Annotations on field #%u '%s'\n", field_idx, field_name);
      DumpAnnotationSetItem(field->GetAnnotationSetItem());
    }
  }

  // Annotations on methods.
  if (methods != nullptr) {
    for (auto& method : *methods) {
      const dex_ir::MethodId* method_id = method->GetMethodId();
      const uint32_t method_idx = method_id->GetIndex();
      const char* method_name = method_id->Name()->Data();
      fprintf(out_file_, "Annotations on method #%u '%s'\n", method_idx, method_name);
      DumpAnnotationSetItem(method->GetAnnotationSetItem());
    }
  }

  // Annotations on method parameters.
  if (parameters != nullptr) {
    for (auto& parameter : *parameters) {
      const dex_ir::MethodId* method_id = parameter->GetMethodId();
      const uint32_t method_idx = method_id->GetIndex();
      const char* method_name = method_id->Name()->Data();
      fprintf(out_file_, "Annotations on method #%u '%s' parameters\n", method_idx, method_name);
      uint32_t j = 0;
      for (dex_ir::AnnotationSetItem* annotation : *parameter->GetAnnotations()->GetItems()) {
        fprintf(out_file_, "#%u\n", j);
        DumpAnnotationSetItem(annotation);
        ++j;
      }
    }
  }

  fputc('\n', out_file_);
}

/*
 * Dumps an interface that a class declares to implement.
 */
void DexLayout::DumpInterface(const dex_ir::TypeId* type_item, int i) {
  const char* interface_name = type_item->GetStringId()->Data();
  if (options_.output_format_ == kOutputPlain) {
    fprintf(out_file_, "    #%d              : '%s'\n", i, interface_name);
  } else {
    std::string dot(DescriptorToDot(interface_name));
    fprintf(out_file_, "<implements name=\"%s\">\n</implements>\n", dot.c_str());
  }
}

/*
 * Dumps the catches table associated with the code.
 */
void DexLayout::DumpCatches(const dex_ir::CodeItem* code) {
  const uint16_t tries_size = code->TriesSize();

  // No catch table.
  if (tries_size == 0) {
    fprintf(out_file_, "      catches       : (none)\n");
    return;
  }

  // Dump all table entries.
  fprintf(out_file_, "      catches       : %d\n", tries_size);
  std::vector<std::unique_ptr<const dex_ir::TryItem>>* tries = code->Tries();
  for (uint32_t i = 0; i < tries_size; i++) {
    const dex_ir::TryItem* try_item = (*tries)[i].get();
    const uint32_t start = try_item->StartAddr();
    const uint32_t end = start + try_item->InsnCount();
    fprintf(out_file_, "        0x%04x - 0x%04x\n", start, end);
    for (auto& handler : *try_item->GetHandlers()->GetHandlers()) {
      const dex_ir::TypeId* type_id = handler->GetTypeId();
      const char* descriptor = (type_id == nullptr) ? "<any>" : type_id->GetStringId()->Data();
      fprintf(out_file_, "          %s -> 0x%04x\n", descriptor, handler->GetAddress());
    }  // for
  }  // for
}

/*
 * Dumps a single instruction.
 */
void DexLayout::DumpInstruction(const dex_ir::CodeItem* code,
                                uint32_t code_offset,
                                uint32_t insn_idx,
                                uint32_t insn_width,
                                const Instruction* dec_insn) {
  // Address of instruction (expressed as byte offset).
  fprintf(out_file_, "%06x:", code_offset + 0x10 + insn_idx * 2);

  // Dump (part of) raw bytes.
  const uint16_t* insns = code->Insns();
  for (uint32_t i = 0; i < 8; i++) {
    if (i < insn_width) {
      if (i == 7) {
        fprintf(out_file_, " ... ");
      } else {
        // Print 16-bit value in little-endian order.
        const uint8_t* bytePtr = (const uint8_t*) &insns[insn_idx + i];
        fprintf(out_file_, " %02x%02x", bytePtr[0], bytePtr[1]);
      }
    } else {
      fputs("     ", out_file_);
    }
  }  // for

  // Dump pseudo-instruction or opcode.
  if (dec_insn->Opcode() == Instruction::NOP) {
    const uint16_t instr = Get2LE((const uint8_t*) &insns[insn_idx]);
    if (instr == Instruction::kPackedSwitchSignature) {
      fprintf(out_file_, "|%04x: packed-switch-data (%d units)", insn_idx, insn_width);
    } else if (instr == Instruction::kSparseSwitchSignature) {
      fprintf(out_file_, "|%04x: sparse-switch-data (%d units)", insn_idx, insn_width);
    } else if (instr == Instruction::kArrayDataSignature) {
      fprintf(out_file_, "|%04x: array-data (%d units)", insn_idx, insn_width);
    } else {
      fprintf(out_file_, "|%04x: nop // spacer", insn_idx);
    }
  } else {
    fprintf(out_file_, "|%04x: %s", insn_idx, dec_insn->Name());
  }

  // Set up additional argument.
  std::unique_ptr<char[]> index_buf;
  if (Instruction::IndexTypeOf(dec_insn->Opcode()) != Instruction::kIndexNone) {
    index_buf = IndexString(header_, dec_insn, 200);
  }

  // Dump the instruction.
  //
  // NOTE: pDecInsn->DumpString(pDexFile) differs too much from original.
  //
  switch (Instruction::FormatOf(dec_insn->Opcode())) {
    case Instruction::k10x:        // op
      break;
    case Instruction::k12x:        // op vA, vB
      fprintf(out_file_, " v%d, v%d", dec_insn->VRegA(), dec_insn->VRegB());
      break;
    case Instruction::k11n:        // op vA, #+B
      fprintf(out_file_, " v%d, #int %d // #%x",
              dec_insn->VRegA(), (int32_t) dec_insn->VRegB(), (uint8_t)dec_insn->VRegB());
      break;
    case Instruction::k11x:        // op vAA
      fprintf(out_file_, " v%d", dec_insn->VRegA());
      break;
    case Instruction::k10t:        // op +AA
    case Instruction::k20t: {      // op +AAAA
      const int32_t targ = (int32_t) dec_insn->VRegA();
      fprintf(out_file_, " %04x // %c%04x",
              insn_idx + targ,
              (targ < 0) ? '-' : '+',
              (targ < 0) ? -targ : targ);
      break;
    }
    case Instruction::k22x:        // op vAA, vBBBB
      fprintf(out_file_, " v%d, v%d", dec_insn->VRegA(), dec_insn->VRegB());
      break;
    case Instruction::k21t: {     // op vAA, +BBBB
      const int32_t targ = (int32_t) dec_insn->VRegB();
      fprintf(out_file_, " v%d, %04x // %c%04x", dec_insn->VRegA(),
              insn_idx + targ,
              (targ < 0) ? '-' : '+',
              (targ < 0) ? -targ : targ);
      break;
    }
    case Instruction::k21s:        // op vAA, #+BBBB
      fprintf(out_file_, " v%d, #int %d // #%x",
              dec_insn->VRegA(), (int32_t) dec_insn->VRegB(), (uint16_t)dec_insn->VRegB());
      break;
    case Instruction::k21h:        // op vAA, #+BBBB0000[00000000]
      // The printed format varies a bit based on the actual opcode.
      if (dec_insn->Opcode() == Instruction::CONST_HIGH16) {
        const int32_t value = dec_insn->VRegB() << 16;
        fprintf(out_file_, " v%d, #int %d // #%x",
                dec_insn->VRegA(), value, (uint16_t) dec_insn->VRegB());
      } else {
        const int64_t value = ((int64_t) dec_insn->VRegB()) << 48;
        fprintf(out_file_, " v%d, #long %" PRId64 " // #%x",
                dec_insn->VRegA(), value, (uint16_t) dec_insn->VRegB());
      }
      break;
    case Instruction::k21c:        // op vAA, thing@BBBB
    case Instruction::k31c:        // op vAA, thing@BBBBBBBB
      fprintf(out_file_, " v%d, %s", dec_insn->VRegA(), index_buf.get());
      break;
    case Instruction::k23x:        // op vAA, vBB, vCC
      fprintf(out_file_, " v%d, v%d, v%d",
              dec_insn->VRegA(), dec_insn->VRegB(), dec_insn->VRegC());
      break;
    case Instruction::k22b:        // op vAA, vBB, #+CC
      fprintf(out_file_, " v%d, v%d, #int %d // #%02x",
              dec_insn->VRegA(), dec_insn->VRegB(),
              (int32_t) dec_insn->VRegC(), (uint8_t) dec_insn->VRegC());
      break;
    case Instruction::k22t: {      // op vA, vB, +CCCC
      const int32_t targ = (int32_t) dec_insn->VRegC();
      fprintf(out_file_, " v%d, v%d, %04x // %c%04x",
              dec_insn->VRegA(), dec_insn->VRegB(),
              insn_idx + targ,
              (targ < 0) ? '-' : '+',
              (targ < 0) ? -targ : targ);
      break;
    }
    case Instruction::k22s:        // op vA, vB, #+CCCC
      fprintf(out_file_, " v%d, v%d, #int %d // #%04x",
              dec_insn->VRegA(), dec_insn->VRegB(),
              (int32_t) dec_insn->VRegC(), (uint16_t) dec_insn->VRegC());
      break;
    case Instruction::k22c:        // op vA, vB, thing@CCCC
    // NOT SUPPORTED:
    // case Instruction::k22cs:    // [opt] op vA, vB, field offset CCCC
      fprintf(out_file_, " v%d, v%d, %s",
              dec_insn->VRegA(), dec_insn->VRegB(), index_buf.get());
      break;
    case Instruction::k30t:
      fprintf(out_file_, " #%08x", dec_insn->VRegA());
      break;
    case Instruction::k31i: {     // op vAA, #+BBBBBBBB
      // This is often, but not always, a float.
      union {
        float f;
        uint32_t i;
      } conv;
      conv.i = dec_insn->VRegB();
      fprintf(out_file_, " v%d, #float %g // #%08x",
              dec_insn->VRegA(), conv.f, dec_insn->VRegB());
      break;
    }
    case Instruction::k31t:       // op vAA, offset +BBBBBBBB
      fprintf(out_file_, " v%d, %08x // +%08x",
              dec_insn->VRegA(), insn_idx + dec_insn->VRegB(), dec_insn->VRegB());
      break;
    case Instruction::k32x:        // op vAAAA, vBBBB
      fprintf(out_file_, " v%d, v%d", dec_insn->VRegA(), dec_insn->VRegB());
      break;
    case Instruction::k35c:           // op {vC, vD, vE, vF, vG}, thing@BBBB
    case Instruction::k45cc: {        // op {vC, vD, vE, vF, vG}, meth@BBBB, proto@HHHH
    // NOT SUPPORTED:
    // case Instruction::k35ms:       // [opt] invoke-virtual+super
    // case Instruction::k35mi:       // [opt] inline invoke
      uint32_t arg[Instruction::kMaxVarArgRegs];
      dec_insn->GetVarArgs(arg);
      fputs(" {", out_file_);
      for (int i = 0, n = dec_insn->VRegA(); i < n; i++) {
        if (i == 0) {
          fprintf(out_file_, "v%d", arg[i]);
        } else {
          fprintf(out_file_, ", v%d", arg[i]);
        }
      }  // for
      fprintf(out_file_, "}, %s", index_buf.get());
      break;
    }
    case Instruction::k3rc:           // op {vCCCC .. v(CCCC+AA-1)}, thing@BBBB
    case Instruction::k4rcc:          // op {vCCCC .. v(CCCC+AA-1)}, meth@BBBB, proto@HHHH
    // NOT SUPPORTED:
    // case Instruction::k3rms:       // [opt] invoke-virtual+super/range
    // case Instruction::k3rmi:       // [opt] execute-inline/range
      {
        // This doesn't match the "dx" output when some of the args are
        // 64-bit values -- dx only shows the first register.
        fputs(" {", out_file_);
        for (int i = 0, n = dec_insn->VRegA(); i < n; i++) {
          if (i == 0) {
            fprintf(out_file_, "v%d", dec_insn->VRegC() + i);
          } else {
            fprintf(out_file_, ", v%d", dec_insn->VRegC() + i);
          }
        }  // for
        fprintf(out_file_, "}, %s", index_buf.get());
      }
      break;
    case Instruction::k51l: {      // op vAA, #+BBBBBBBBBBBBBBBB
      // This is often, but not always, a double.
      union {
        double d;
        uint64_t j;
      } conv;
      conv.j = dec_insn->WideVRegB();
      fprintf(out_file_, " v%d, #double %g // #%016" PRIx64,
              dec_insn->VRegA(), conv.d, dec_insn->WideVRegB());
      break;
    }
    // NOT SUPPORTED:
    // case Instruction::k00x:        // unknown op or breakpoint
    //    break;
    default:
      fprintf(out_file_, " ???");
      break;
  }  // switch

  fputc('\n', out_file_);
}

/*
 * Dumps a bytecode disassembly.
 */
void DexLayout::DumpBytecodes(uint32_t idx, const dex_ir::CodeItem* code, uint32_t code_offset) {
  dex_ir::MethodId* method_id = header_->MethodIds()[idx];
  const char* name = method_id->Name()->Data();
  std::string type_descriptor = GetSignatureForProtoId(method_id->Proto());
  const char* back_descriptor = method_id->Class()->GetStringId()->Data();

  // Generate header.
  std::string dot(DescriptorToDot(back_descriptor));
  fprintf(out_file_, "%06x:                                        |[%06x] %s.%s:%s\n",
          code_offset, code_offset, dot.c_str(), name, type_descriptor.c_str());

  // Iterate over all instructions.
  for (const DexInstructionPcPair& inst : code->Instructions()) {
    const uint32_t insn_width = inst->SizeInCodeUnits();
    if (insn_width == 0) {
      LOG(WARNING) << "GLITCH: zero-width instruction at idx=0x" << std::hex << inst.DexPc();
      break;
    }
    DumpInstruction(code, code_offset, inst.DexPc(), insn_width, &inst.Inst());
  }  // for
}

/*
 * Lookup functions.
 */
static const char* StringDataByIdx(uint32_t idx, dex_ir::Header* header) {
  dex_ir::StringId* string_id = header->GetStringIdOrNullPtr(idx);
  if (string_id == nullptr) {
    return nullptr;
  }
  return string_id->Data();
}

static const char* StringDataByTypeIdx(uint16_t idx, dex_ir::Header* header) {
  dex_ir::TypeId* type_id = header->GetTypeIdOrNullPtr(idx);
  if (type_id == nullptr) {
    return nullptr;
  }
  dex_ir::StringId* string_id = type_id->GetStringId();
  if (string_id == nullptr) {
    return nullptr;
  }
  return string_id->Data();
}


/*
 * Dumps code of a method.
 */
void DexLayout::DumpCode(uint32_t idx,
                         const dex_ir::CodeItem* code,
                         uint32_t code_offset,
                         const char* declaring_class_descriptor,
                         const char* method_name,
                         bool is_static,
                         const dex_ir::ProtoId* proto) {
  fprintf(out_file_, "      registers     : %d\n", code->RegistersSize());
  fprintf(out_file_, "      ins           : %d\n", code->InsSize());
  fprintf(out_file_, "      outs          : %d\n", code->OutsSize());
  fprintf(out_file_, "      insns size    : %d 16-bit code units\n",
          code->InsnsSize());

  // Bytecode disassembly, if requested.
  if (options_.disassemble_) {
    DumpBytecodes(idx, code, code_offset);
  }

  // Try-catch blocks.
  DumpCatches(code);

  // Positions and locals table in the debug info.
  dex_ir::DebugInfoItem* debug_info = code->DebugInfo();
  fprintf(out_file_, "      positions     :\n");
  if (debug_info != nullptr) {
    DexFile::DecodeDebugPositionInfo(debug_info->GetDebugInfo(),
                                     [this](uint32_t idx) {
                                       return StringDataByIdx(idx, this->header_);
                                     },
                                     [&](const DexFile::PositionInfo& entry) {
                                       fprintf(out_file_,
                                               "        0x%04x line=%d\n",
                                               entry.address_,
                                               entry.line_);
                                        return false;
                                     });
  }
  fprintf(out_file_, "      locals        :\n");
  if (debug_info != nullptr) {
    std::vector<const char*> arg_descriptors;
    const dex_ir::TypeList* parameters = proto->Parameters();
    if (parameters != nullptr) {
      const dex_ir::TypeIdVector* parameter_type_vector = parameters->GetTypeList();
      if (parameter_type_vector != nullptr) {
        for (const dex_ir::TypeId* type_id : *parameter_type_vector) {
          arg_descriptors.push_back(type_id->GetStringId()->Data());
        }
      }
    }
    DexFile::DecodeDebugLocalInfo(debug_info->GetDebugInfo(),
                                  "DexLayout in-memory",
                                  declaring_class_descriptor,
                                  arg_descriptors,
                                  method_name,
                                  is_static,
                                  code->RegistersSize(),
                                  code->InsSize(),
                                  code->InsnsSize(),
                                  [this](uint32_t idx) {
                                    return StringDataByIdx(idx, this->header_);
                                  },
                                  [this](uint32_t idx) {
                                    return
                                        StringDataByTypeIdx(dchecked_integral_cast<uint16_t>(idx),
                                                            this->header_);
                                  },
                                  [&](const DexFile::LocalInfo& entry) {
                                    fprintf(out_file_,
                                            "        0x%04x - 0x%04x reg=%d %s %s",
                                            entry.start_address_,
                                            entry.end_address_,
                                            entry.reg_,
                                            entry.name_,
                                            entry.descriptor_);
                                    if (entry.signature_) {
                                      fputc(' ', out_file_);
                                      fputs(entry.signature_, out_file_);
                                    }
                                    fputc('\n', out_file_);
                                  });
  }
}

/*
 * Dumps a method.
 */
void DexLayout::DumpMethod(uint32_t idx,
                           uint32_t flags,
                           uint32_t hiddenapi_flags,
                           const dex_ir::CodeItem* code,
                           int i) {
  // Bail for anything private if export only requested.
  if (options_.exports_only_ && (flags & (kAccPublic | kAccProtected)) == 0) {
    return;
  }

  dex_ir::MethodId* method_id = header_->MethodIds()[idx];
  const char* name = method_id->Name()->Data();
  char* type_descriptor = strdup(GetSignatureForProtoId(method_id->Proto()).c_str());
  const char* back_descriptor = method_id->Class()->GetStringId()->Data();
  char* access_str = CreateAccessFlagStr(flags, kAccessForMethod);

  if (options_.output_format_ == kOutputPlain) {
    fprintf(out_file_, "    #%d              : (in %s)\n", i, back_descriptor);
    fprintf(out_file_, "      name          : '%s'\n", name);
    fprintf(out_file_, "      type          : '%s'\n", type_descriptor);
    fprintf(out_file_, "      access        : 0x%04x (%s)\n", flags, access_str);
    if (options_.show_section_headers_) {
      fprintf(out_file_, "      method_idx    : %d\n", method_id->GetIndex());
    }
    if (hiddenapi_flags != 0u) {
      fprintf(out_file_,
              "      hiddenapi     : 0x%04x (%s)\n",
              hiddenapi_flags,
              GetHiddenapiFlagStr(hiddenapi_flags).c_str());
    }
    if (code == nullptr) {
      fprintf(out_file_, "      code          : (none)\n");
    } else {
      fprintf(out_file_, "      code          -\n");
      DumpCode(idx,
               code,
               code->GetOffset(),
               back_descriptor,
               name,
               (flags & kAccStatic) != 0,
               method_id->Proto());
    }
    if (options_.disassemble_) {
      fputc('\n', out_file_);
    }
  } else if (options_.output_format_ == kOutputXml) {
    const bool constructor = (name[0] == '<');

    // Method name and prototype.
    if (constructor) {
      std::string dot(DescriptorClassToName(back_descriptor));
      fprintf(out_file_, "<constructor name=\"%s\"\n", dot.c_str());
      dot = DescriptorToDot(back_descriptor);
      fprintf(out_file_, " type=\"%s\"\n", dot.c_str());
    } else {
      fprintf(out_file_, "<method name=\"%s\"\n", name);
      const char* return_type = strrchr(type_descriptor, ')');
      if (return_type == nullptr) {
        LOG(ERROR) << "bad method type descriptor '" << type_descriptor << "'";
        goto bail;
      }
      std::string dot(DescriptorToDot(return_type + 1));
      fprintf(out_file_, " return=\"%s\"\n", dot.c_str());
      fprintf(out_file_, " abstract=%s\n", QuotedBool((flags & kAccAbstract) != 0));
      fprintf(out_file_, " native=%s\n", QuotedBool((flags & kAccNative) != 0));
      fprintf(out_file_, " synchronized=%s\n", QuotedBool(
          (flags & (kAccSynchronized | kAccDeclaredSynchronized)) != 0));
    }

    // Additional method flags.
    fprintf(out_file_, " static=%s\n", QuotedBool((flags & kAccStatic) != 0));
    fprintf(out_file_, " final=%s\n", QuotedBool((flags & kAccFinal) != 0));
    // The "deprecated=" not knowable w/o parsing annotations.
    fprintf(out_file_, " visibility=%s\n>\n", QuotedVisibility(flags));

    // Parameters.
    if (type_descriptor[0] != '(') {
      LOG(ERROR) << "ERROR: bad descriptor '" << type_descriptor << "'";
      goto bail;
    }
    char* tmp_buf = reinterpret_cast<char*>(malloc(strlen(type_descriptor) + 1));
    const char* base = type_descriptor + 1;
    int arg_num = 0;
    while (*base != ')') {
      char* cp = tmp_buf;
      while (*base == '[') {
        *cp++ = *base++;
      }
      if (*base == 'L') {
        // Copy through ';'.
        do {
          *cp = *base++;
        } while (*cp++ != ';');
      } else {
        // Primitive char, copy it.
        if (strchr("ZBCSIFJD", *base) == nullptr) {
          LOG(ERROR) << "ERROR: bad method signature '" << base << "'";
          break;  // while
        }
        *cp++ = *base++;
      }
      // Null terminate and display.
      *cp++ = '\0';
      std::string dot(DescriptorToDot(tmp_buf));
      fprintf(out_file_, "<parameter name=\"arg%d\" type=\"%s\">\n"
                        "</parameter>\n", arg_num++, dot.c_str());
    }  // while
    free(tmp_buf);
    if (constructor) {
      fprintf(out_file_, "</constructor>\n");
    } else {
      fprintf(out_file_, "</method>\n");
    }
  }

bail:
  free(type_descriptor);
  free(access_str);
}

/*
 * Dumps a static (class) field.
 */
void DexLayout::DumpSField(uint32_t idx,
                           uint32_t flags,
                           uint32_t hiddenapi_flags,
                           int i,
                           dex_ir::EncodedValue* init) {
  // Bail for anything private if export only requested.
  if (options_.exports_only_ && (flags & (kAccPublic | kAccProtected)) == 0) {
    return;
  }

  dex_ir::FieldId* field_id = header_->FieldIds()[idx];
  const char* name = field_id->Name()->Data();
  const char* type_descriptor = field_id->Type()->GetStringId()->Data();
  const char* back_descriptor = field_id->Class()->GetStringId()->Data();
  char* access_str = CreateAccessFlagStr(flags, kAccessForField);

  if (options_.output_format_ == kOutputPlain) {
    fprintf(out_file_, "    #%d              : (in %s)\n", i, back_descriptor);
    fprintf(out_file_, "      name          : '%s'\n", name);
    fprintf(out_file_, "      type          : '%s'\n", type_descriptor);
    fprintf(out_file_, "      access        : 0x%04x (%s)\n", flags, access_str);
    if (hiddenapi_flags != 0u) {
      fprintf(out_file_,
              "      hiddenapi     : 0x%04x (%s)\n",
              hiddenapi_flags,
              GetHiddenapiFlagStr(hiddenapi_flags).c_str());
    }
    if (init != nullptr) {
      fputs("      value         : ", out_file_);
      DumpEncodedValue(init);
      fputs("\n", out_file_);
    }
  } else if (options_.output_format_ == kOutputXml) {
    fprintf(out_file_, "<field name=\"%s\"\n", name);
    std::string dot(DescriptorToDot(type_descriptor));
    fprintf(out_file_, " type=\"%s\"\n", dot.c_str());
    fprintf(out_file_, " transient=%s\n", QuotedBool((flags & kAccTransient) != 0));
    fprintf(out_file_, " volatile=%s\n", QuotedBool((flags & kAccVolatile) != 0));
    // The "value=" is not knowable w/o parsing annotations.
    fprintf(out_file_, " static=%s\n", QuotedBool((flags & kAccStatic) != 0));
    fprintf(out_file_, " final=%s\n", QuotedBool((flags & kAccFinal) != 0));
    // The "deprecated=" is not knowable w/o parsing annotations.
    fprintf(out_file_, " visibility=%s\n", QuotedVisibility(flags));
    if (init != nullptr) {
      fputs(" value=\"", out_file_);
      DumpEncodedValue(init);
      fputs("\"\n", out_file_);
    }
    fputs(">\n</field>\n", out_file_);
  }

  free(access_str);
}

/*
 * Dumps an instance field.
 */
void DexLayout::DumpIField(uint32_t idx,
                           uint32_t flags,
                           uint32_t hiddenapi_flags,
                           int i) {
  DumpSField(idx, flags, hiddenapi_flags, i, nullptr);
}

/*
 * Dumps the class.
 *
 * Note "idx" is a DexClassDef index, not a DexTypeId index.
 *
 * If "*last_package" is nullptr or does not match the current class' package,
 * the value will be replaced with a newly-allocated string.
 */
void DexLayout::DumpClass(int idx, char** last_package) {
  dex_ir::ClassDef* class_def = header_->ClassDefs()[idx];
  // Omitting non-public class.
  if (options_.exports_only_ && (class_def->GetAccessFlags() & kAccPublic) == 0) {
    return;
  }

  if (options_.show_section_headers_) {
    DumpClassDef(idx);
  }

  if (options_.show_annotations_) {
    DumpClassAnnotations(idx);
  }

  // For the XML output, show the package name.  Ideally we'd gather
  // up the classes, sort them, and dump them alphabetically so the
  // package name wouldn't jump around, but that's not a great plan
  // for something that needs to run on the device.
  const char* class_descriptor = header_->ClassDefs()[idx]->ClassType()->GetStringId()->Data();
  if (!(class_descriptor[0] == 'L' &&
        class_descriptor[strlen(class_descriptor)-1] == ';')) {
    // Arrays and primitives should not be defined explicitly. Keep going?
    LOG(ERROR) << "Malformed class name '" << class_descriptor << "'";
  } else if (options_.output_format_ == kOutputXml) {
    char* mangle = strdup(class_descriptor + 1);
    mangle[strlen(mangle)-1] = '\0';

    // Reduce to just the package name.
    char* last_slash = strrchr(mangle, '/');
    if (last_slash != nullptr) {
      *last_slash = '\0';
    } else {
      *mangle = '\0';
    }

    for (char* cp = mangle; *cp != '\0'; cp++) {
      if (*cp == '/') {
        *cp = '.';
      }
    }  // for

    if (*last_package == nullptr || strcmp(mangle, *last_package) != 0) {
      // Start of a new package.
      if (*last_package != nullptr) {
        fprintf(out_file_, "</package>\n");
      }
      fprintf(out_file_, "<package name=\"%s\"\n>\n", mangle);
      free(*last_package);
      *last_package = mangle;
    } else {
      free(mangle);
    }
  }

  // General class information.
  char* access_str = CreateAccessFlagStr(class_def->GetAccessFlags(), kAccessForClass);
  const char* superclass_descriptor = nullptr;
  if (class_def->Superclass() != nullptr) {
    superclass_descriptor = class_def->Superclass()->GetStringId()->Data();
  }
  if (options_.output_format_ == kOutputPlain) {
    fprintf(out_file_, "Class #%d            -\n", idx);
    fprintf(out_file_, "  Class descriptor  : '%s'\n", class_descriptor);
    fprintf(out_file_, "  Access flags      : 0x%04x (%s)\n",
            class_def->GetAccessFlags(), access_str);
    if (superclass_descriptor != nullptr) {
      fprintf(out_file_, "  Superclass        : '%s'\n", superclass_descriptor);
    }
    fprintf(out_file_, "  Interfaces        -\n");
  } else {
    std::string dot(DescriptorClassToName(class_descriptor));
    fprintf(out_file_, "<class name=\"%s\"\n", dot.c_str());
    if (superclass_descriptor != nullptr) {
      dot = DescriptorToDot(superclass_descriptor);
      fprintf(out_file_, " extends=\"%s\"\n", dot.c_str());
    }
    fprintf(out_file_, " interface=%s\n",
            QuotedBool((class_def->GetAccessFlags() & kAccInterface) != 0));
    fprintf(out_file_, " abstract=%s\n",
            QuotedBool((class_def->GetAccessFlags() & kAccAbstract) != 0));
    fprintf(out_file_, " static=%s\n", QuotedBool((class_def->GetAccessFlags() & kAccStatic) != 0));
    fprintf(out_file_, " final=%s\n", QuotedBool((class_def->GetAccessFlags() & kAccFinal) != 0));
    // The "deprecated=" not knowable w/o parsing annotations.
    fprintf(out_file_, " visibility=%s\n", QuotedVisibility(class_def->GetAccessFlags()));
    fprintf(out_file_, ">\n");
  }

  // Interfaces.
  const dex_ir::TypeList* interfaces = class_def->Interfaces();
  if (interfaces != nullptr) {
    const dex_ir::TypeIdVector* interfaces_vector = interfaces->GetTypeList();
    for (uint32_t i = 0; i < interfaces_vector->size(); i++) {
      DumpInterface((*interfaces_vector)[i], i);
    }  // for
  }

  // Fields and methods.
  dex_ir::ClassData* class_data = class_def->GetClassData();
  // Prepare data for static fields.
  dex_ir::EncodedArrayItem* static_values = class_def->StaticValues();
  dex_ir::EncodedValueVector* encoded_values =
      static_values == nullptr ? nullptr : static_values->GetEncodedValues();
  const uint32_t encoded_values_size = (encoded_values == nullptr) ? 0 : encoded_values->size();

  // Static fields.
  if (options_.output_format_ == kOutputPlain) {
    fprintf(out_file_, "  Static fields     -\n");
  }
  if (class_data != nullptr) {
    dex_ir::FieldItemVector* static_fields = class_data->StaticFields();
    if (static_fields != nullptr) {
      for (uint32_t i = 0; i < static_fields->size(); i++) {
        DumpSField((*static_fields)[i].GetFieldId()->GetIndex(),
                   (*static_fields)[i].GetAccessFlags(),
                   dex_ir::HiddenapiClassData::GetFlags(header_, class_def, &(*static_fields)[i]),
                   i,
                   i < encoded_values_size ? (*encoded_values)[i].get() : nullptr);
      }  // for
    }
  }

  // Instance fields.
  if (options_.output_format_ == kOutputPlain) {
    fprintf(out_file_, "  Instance fields   -\n");
  }
  if (class_data != nullptr) {
    dex_ir::FieldItemVector* instance_fields = class_data->InstanceFields();
    if (instance_fields != nullptr) {
      for (uint32_t i = 0; i < instance_fields->size(); i++) {
        DumpIField((*instance_fields)[i].GetFieldId()->GetIndex(),
                   (*instance_fields)[i].GetAccessFlags(),
                   dex_ir::HiddenapiClassData::GetFlags(header_, class_def, &(*instance_fields)[i]),
                   i);
      }  // for
    }
  }

  // Direct methods.
  if (options_.output_format_ == kOutputPlain) {
    fprintf(out_file_, "  Direct methods    -\n");
  }
  if (class_data != nullptr) {
    dex_ir::MethodItemVector* direct_methods = class_data->DirectMethods();
    if (direct_methods != nullptr) {
      for (uint32_t i = 0; i < direct_methods->size(); i++) {
        DumpMethod((*direct_methods)[i].GetMethodId()->GetIndex(),
                   (*direct_methods)[i].GetAccessFlags(),
                   dex_ir::HiddenapiClassData::GetFlags(header_, class_def, &(*direct_methods)[i]),
                   (*direct_methods)[i].GetCodeItem(),
                   i);
      }  // for
    }
  }

  // Virtual methods.
  if (options_.output_format_ == kOutputPlain) {
    fprintf(out_file_, "  Virtual methods   -\n");
  }
  if (class_data != nullptr) {
    dex_ir::MethodItemVector* virtual_methods = class_data->VirtualMethods();
    if (virtual_methods != nullptr) {
      for (uint32_t i = 0; i < virtual_methods->size(); i++) {
        DumpMethod((*virtual_methods)[i].GetMethodId()->GetIndex(),
                   (*virtual_methods)[i].GetAccessFlags(),
                   dex_ir::HiddenapiClassData::GetFlags(header_, class_def, &(*virtual_methods)[i]),
                   (*virtual_methods)[i].GetCodeItem(),
                   i);
      }  // for
    }
  }

  // End of class.
  if (options_.output_format_ == kOutputPlain) {
    const char* file_name = "unknown";
    if (class_def->SourceFile() != nullptr) {
      file_name = class_def->SourceFile()->Data();
    }
    const dex_ir::StringId* source_file = class_def->SourceFile();
    fprintf(out_file_, "  source_file_idx   : %d (%s)\n\n",
            source_file == nullptr ? 0xffffffffU : source_file->GetIndex(), file_name);
  } else if (options_.output_format_ == kOutputXml) {
    fprintf(out_file_, "</class>\n");
  }

  free(access_str);
}

void DexLayout::DumpMethodHandle(int idx) {
  const dex_ir::MethodHandleItem* mh = header_->MethodHandleItems()[idx];
  const char* type = nullptr;
  bool is_instance = false;
  bool is_invoke = false;

  switch (mh->GetMethodHandleType()) {
    case DexFile::MethodHandleType::kStaticPut:
      type = "put-static";
      is_instance = false;
      is_invoke = false;
      break;
    case DexFile::MethodHandleType::kStaticGet:
      type = "get-static";
      is_instance = false;
      is_invoke = false;
      break;
    case DexFile::MethodHandleType::kInstancePut:
      type = "put-instance";
      is_instance = true;
      is_invoke = false;
      break;
    case DexFile::MethodHandleType::kInstanceGet:
      type = "get-instance";
      is_instance = true;
      is_invoke = false;
      break;
    case DexFile::MethodHandleType::kInvokeStatic:
      type = "invoke-static";
      is_instance = false;
      is_invoke = true;
      break;
    case DexFile::MethodHandleType::kInvokeInstance:
      type = "invoke-instance";
      is_instance = true;
      is_invoke = true;
      break;
    case DexFile::MethodHandleType::kInvokeConstructor:
      type = "invoke-constructor";
      is_instance = true;
      is_invoke = true;
      break;
    case DexFile::MethodHandleType::kInvokeDirect:
      type = "invoke-direct";
      is_instance = true;
      is_invoke = true;
      break;
    case DexFile::MethodHandleType::kInvokeInterface:
      type = "invoke-interface";
      is_instance = true;
      is_invoke = true;
      break;
    default:
      type = "????";
      break;
  }  // switch

  const char* declaring_class;
  const char* member;
  std::string member_type;
  if (type != nullptr) {
    if (is_invoke) {
      auto method_id = static_cast<dex_ir::MethodId*>(mh->GetFieldOrMethodId());
      declaring_class = method_id->Class()->GetStringId()->Data();
      member = method_id->Name()->Data();
      auto proto_id = method_id->Proto();
      member_type = GetSignatureForProtoId(proto_id);
    } else {
      auto field_id = static_cast<dex_ir::FieldId*>(mh->GetFieldOrMethodId());
      declaring_class = field_id->Class()->GetStringId()->Data();
      member = field_id->Name()->Data();
      member_type = field_id->Type()->GetStringId()->Data();
    }
    if (is_instance) {
      member_type = android::base::StringPrintf("(%s%s", declaring_class, member_type.c_str() + 1);
    }
  } else {
    type = "?";
    declaring_class = "?";
    member = "?";
    member_type = "?";
  }

  if (options_.output_format_ == kOutputPlain) {
    fprintf(out_file_, "Method handle #%u:\n", idx);
    fprintf(out_file_, "  type        : %s\n", type);
    fprintf(out_file_, "  target      : %s %s\n", declaring_class, member);
    fprintf(out_file_, "  target_type : %s\n", member_type.c_str());
  }
}

void DexLayout::DumpCallSite(int idx) {
  const dex_ir::CallSiteId* call_site_id = header_->CallSiteIds()[idx];
  auto call_site_items = call_site_id->CallSiteItem()->GetEncodedValues();
  if (call_site_items->size() < 3) {
    LOG(ERROR) << "ERROR: Call site " << idx << " has too few values.";
    return;
  }
  uint32_t offset = call_site_id->CallSiteItem()->GetOffset();

  auto it = call_site_items->begin();
  if ((*it)->Type() != EncodedArrayValueIterator::ValueType::kMethodHandle) {
    LOG(ERROR) << "ERROR: Call site " << idx << " needs to have a MethodHandle as its first item."
               << " Found " << (*it)->Type();
    return;
  }
  auto method_handle = (*it)->GetMethodHandle();
  uint32_t method_handle_idx = method_handle->GetIndex();

  it++;
  if ((*it)->Type() != EncodedArrayValueIterator::ValueType::kString) {
    LOG(ERROR) << "ERROR: Call site " << idx << " needs to have a String for method name "
               << "as its second item."
               << " Found " << (*it)->Type();
    return;
  }
  const char* method_name = (*it)->GetStringId()->Data();

  it++;
  if ((*it)->Type() != EncodedArrayValueIterator::ValueType::kMethodType) {
    LOG(ERROR) << "ERROR: Call site " << idx << " needs to have a Prototype as its third item."
               << " Found " << (*it)->Type();
    return;
  }
  auto proto_id = (*it)->GetProtoId();
  std::string method_type = GetSignatureForProtoId(proto_id);

  it++;
  if (options_.output_format_ == kOutputPlain) {
    fprintf(out_file_, "Call site #%u: // offset %u\n", idx, offset);
    fprintf(out_file_, "  link_argument[0] : %u (MethodHandle)\n", method_handle_idx);
    fprintf(out_file_, "  link_argument[1] : %s (String)\n", method_name);
    fprintf(out_file_, "  link_argument[2] : %s (MethodType)\n", method_type.c_str());
  }

  size_t argument = 3;

  while (it != call_site_items->end()) {
    const char* type;
    std::string value;
    switch ((*it)->Type()) {
      case EncodedArrayValueIterator::ValueType::kByte:
        type = "byte";
        value = android::base::StringPrintf("%u", (*it)->GetByte());
        break;
      case EncodedArrayValueIterator::ValueType::kShort:
        type = "short";
        value = android::base::StringPrintf("%d", (*it)->GetShort());
        break;
      case EncodedArrayValueIterator::ValueType::kChar:
        type = "char";
        value = android::base::StringPrintf("%u", (*it)->GetChar());
        break;
      case EncodedArrayValueIterator::ValueType::kInt:
        type = "int";
        value = android::base::StringPrintf("%d", (*it)->GetInt());
        break;
      case EncodedArrayValueIterator::ValueType::kLong:
        type = "long";
        value = android::base::StringPrintf("%" PRId64, (*it)->GetLong());
        break;
      case EncodedArrayValueIterator::ValueType::kFloat:
        type = "float";
        value = android::base::StringPrintf("%g", (*it)->GetFloat());
        break;
      case EncodedArrayValueIterator::ValueType::kDouble:
        type = "double";
        value = android::base::StringPrintf("%g", (*it)->GetDouble());
        break;
      case EncodedArrayValueIterator::ValueType::kMethodType: {
        type = "MethodType";
        auto proto_id_item = (*it)->GetProtoId();
        value = GetSignatureForProtoId(proto_id_item);
        break;
      }
      case EncodedArrayValueIterator::ValueType::kMethodHandle: {
        type = "MethodHandle";
        auto method_handle_item = (*it)->GetMethodHandle();
        value = android::base::StringPrintf("%d", method_handle_item->GetIndex());
        break;
      }
      case EncodedArrayValueIterator::ValueType::kString: {
        type = "String";
        auto string_id = (*it)->GetStringId();
        value = string_id->Data();
        break;
      }
      case EncodedArrayValueIterator::ValueType::kType: {
        type = "Class";
        auto type_id = (*it)->GetTypeId();
        value = type_id->GetStringId()->Data();
        break;
      }
      case EncodedArrayValueIterator::ValueType::kField:
      case EncodedArrayValueIterator::ValueType::kMethod:
      case EncodedArrayValueIterator::ValueType::kEnum:
      case EncodedArrayValueIterator::ValueType::kArray:
      case EncodedArrayValueIterator::ValueType::kAnnotation:
        // Unreachable based on current EncodedArrayValueIterator::Next().
        UNIMPLEMENTED(FATAL) << " type " << (*it)->Type();
        UNREACHABLE();
      case EncodedArrayValueIterator::ValueType::kNull:
        type = "Null";
        value = "null";
        break;
      case EncodedArrayValueIterator::ValueType::kBoolean:
        type = "boolean";
        value = (*it)->GetBoolean() ? "true" : "false";
        break;
    }

    if (options_.output_format_ == kOutputPlain) {
      fprintf(out_file_, "  link_argument[%zu] : %s (%s)\n", argument, value.c_str(), type);
    }

    it++;
    argument++;
  }
}

void DexLayout::DumpDexFile() {
  // Headers.
  if (options_.show_file_headers_) {
    DumpFileHeader();
  }

  // Open XML context.
  if (options_.output_format_ == kOutputXml) {
    fprintf(out_file_, "<api>\n");
  }

  // Iterate over all classes.
  char* package = nullptr;
  const uint32_t class_defs_size = header_->ClassDefs().Size();
  for (uint32_t i = 0; i < class_defs_size; i++) {
    DumpClass(i, &package);
  }  // for

  const uint32_t mh_items_size = header_->MethodHandleItems().Size();
  for (uint32_t i = 0; i < mh_items_size; i++) {
    DumpMethodHandle(i);
  }

  const uint32_t call_sites_size = header_->CallSiteIds().Size();
  for (uint32_t i = 0; i < call_sites_size; i++) {
    DumpCallSite(i);
  }

  // Free the last package allocated.
  if (package != nullptr) {
    fprintf(out_file_, "</package>\n");
    free(package);
  }

  // Close XML context.
  if (options_.output_format_ == kOutputXml) {
    fprintf(out_file_, "</api>\n");
  }
}

void DexLayout::LayoutClassDefsAndClassData(const DexFile* dex_file) {
  std::vector<dex_ir::ClassDef*> new_class_def_order;
  for (auto& class_def : header_->ClassDefs()) {
    dex::TypeIndex type_idx(class_def->ClassType()->GetIndex());
    if (info_->ContainsClass(*dex_file, type_idx)) {
      new_class_def_order.push_back(class_def.get());
    }
  }
  for (auto& class_def : header_->ClassDefs()) {
    dex::TypeIndex type_idx(class_def->ClassType()->GetIndex());
    if (!info_->ContainsClass(*dex_file, type_idx)) {
      new_class_def_order.push_back(class_def.get());
    }
  }
  std::unordered_set<dex_ir::ClassData*> visited_class_data;
  size_t class_data_index = 0;
  auto& class_datas = header_->ClassDatas();
  for (dex_ir::ClassDef* class_def : new_class_def_order) {
    dex_ir::ClassData* class_data = class_def->GetClassData();
    if (class_data != nullptr && visited_class_data.find(class_data) == visited_class_data.end()) {
      visited_class_data.insert(class_data);
      // Overwrite the existing vector with the new ordering, note that the sets of objects are
      // equivalent, but the order changes. This is why this is not a memory leak.
      // TODO: Consider cleaning this up with a shared_ptr.
      class_datas[class_data_index].release();  // NOLINT b/117926937
      class_datas[class_data_index].reset(class_data);
      ++class_data_index;
    }
  }
  CHECK_EQ(class_data_index, class_datas.Size());

  if (DexLayout::kChangeClassDefOrder) {
    // This currently produces dex files that violate the spec since the super class class_def is
    // supposed to occur before any subclasses.
    dex_ir::CollectionVector<dex_ir::ClassDef>& class_defs = header_->ClassDefs();
    CHECK_EQ(new_class_def_order.size(), class_defs.Size());
    for (size_t i = 0; i < class_defs.Size(); ++i) {
      // Overwrite the existing vector with the new ordering, note that the sets of objects are
      // equivalent, but the order changes. This is why this is not a memory leak.
      // TODO: Consider cleaning this up with a shared_ptr.
      class_defs[i].release();  // NOLINT b/117926937
      class_defs[i].reset(new_class_def_order[i]);
    }
  }
}

void DexLayout::LayoutStringData(const DexFile* dex_file) {
  const size_t num_strings = header_->StringIds().Size();
  std::vector<bool> is_shorty(num_strings, false);
  std::vector<bool> from_hot_method(num_strings, false);
  for (auto& class_def : header_->ClassDefs()) {
    // A name of a profile class is probably going to get looked up by ClassTable::Lookup, mark it
    // as hot. Add its super class and interfaces as well, which can be used during initialization.
    const bool is_profile_class =
        info_->ContainsClass(*dex_file, dex::TypeIndex(class_def->ClassType()->GetIndex()));
    if (is_profile_class) {
      from_hot_method[class_def->ClassType()->GetStringId()->GetIndex()] = true;
      const dex_ir::TypeId* superclass = class_def->Superclass();
      if (superclass != nullptr) {
        from_hot_method[superclass->GetStringId()->GetIndex()] = true;
      }
      const dex_ir::TypeList* interfaces = class_def->Interfaces();
      if (interfaces != nullptr) {
        for (const dex_ir::TypeId* interface_type : *interfaces->GetTypeList()) {
          from_hot_method[interface_type->GetStringId()->GetIndex()] = true;
        }
      }
    }
    dex_ir::ClassData* data = class_def->GetClassData();
    if (data == nullptr) {
      continue;
    }
    for (size_t i = 0; i < 2; ++i) {
      for (auto& method : *(i == 0 ? data->DirectMethods() : data->VirtualMethods())) {
        const dex_ir::MethodId* method_id = method.GetMethodId();
        dex_ir::CodeItem* code_item = method.GetCodeItem();
        if (code_item == nullptr) {
          continue;
        }
        const bool is_clinit = is_profile_class &&
            (method.GetAccessFlags() & kAccConstructor) != 0 &&
            (method.GetAccessFlags() & kAccStatic) != 0;
        const bool method_executed = is_clinit ||
            info_->GetMethodHotness(MethodReference(dex_file, method_id->GetIndex())).IsInProfile();
        if (!method_executed) {
          continue;
        }
        is_shorty[method_id->Proto()->Shorty()->GetIndex()] = true;
        dex_ir::CodeFixups* fixups = code_item->GetCodeFixups();
        if (fixups == nullptr) {
          continue;
        }
        // Add const-strings.
        for (dex_ir::StringId* id : fixups->StringIds()) {
          from_hot_method[id->GetIndex()] = true;
        }
        // Add field classes, names, and types.
        for (dex_ir::FieldId* id : fixups->FieldIds()) {
          // TODO: Only visit field ids from static getters and setters.
          from_hot_method[id->Class()->GetStringId()->GetIndex()] = true;
          from_hot_method[id->Name()->GetIndex()] = true;
          from_hot_method[id->Type()->GetStringId()->GetIndex()] = true;
        }
        // For clinits, add referenced method classes, names, and protos.
        if (is_clinit) {
          for (dex_ir::MethodId* id : fixups->MethodIds()) {
            from_hot_method[id->Class()->GetStringId()->GetIndex()] = true;
            from_hot_method[id->Name()->GetIndex()] = true;
            is_shorty[id->Proto()->Shorty()->GetIndex()] = true;
          }
        }
      }
    }
  }
  // Sort string data by specified order.
  std::vector<dex_ir::StringId*> string_ids;
  for (auto& string_id : header_->StringIds()) {
    string_ids.push_back(string_id.get());
  }
  std::sort(string_ids.begin(),
            string_ids.end(),
            [&is_shorty, &from_hot_method](const dex_ir::StringId* a,
                                           const dex_ir::StringId* b) {
    const bool a_is_hot = from_hot_method[a->GetIndex()];
    const bool b_is_hot = from_hot_method[b->GetIndex()];
    if (a_is_hot != b_is_hot) {
      return a_is_hot < b_is_hot;
    }
    // After hot methods are partitioned, subpartition shorties.
    const bool a_is_shorty = is_shorty[a->GetIndex()];
    const bool b_is_shorty = is_shorty[b->GetIndex()];
    if (a_is_shorty != b_is_shorty) {
      return a_is_shorty < b_is_shorty;
    }
    // Order by index by default.
    return a->GetIndex() < b->GetIndex();
  });
  auto& string_datas = header_->StringDatas();
  // Now we know what order we want the string data, reorder them.
  size_t data_index = 0;
  for (dex_ir::StringId* string_id : string_ids) {
    string_datas[data_index].release();  // NOLINT b/117926937
    string_datas[data_index].reset(string_id->DataItem());
    ++data_index;
  }
  if (kIsDebugBuild) {
    std::unordered_set<dex_ir::StringData*> visited;
    for (const std::unique_ptr<dex_ir::StringData>& data : string_datas) {
      visited.insert(data.get());
    }
    for (auto& string_id : header_->StringIds()) {
      CHECK(visited.find(string_id->DataItem()) != visited.end());
    }
  }
  CHECK_EQ(data_index, string_datas.Size());
}

// Orders code items according to specified class data ordering.
void DexLayout::LayoutCodeItems(const DexFile* dex_file) {
  static constexpr InvokeType invoke_types[] = {
    kDirect,
    kVirtual
  };

  std::unordered_map<dex_ir::CodeItem*, LayoutType>& code_item_layout =
      layout_hotness_info_.code_item_layout_;

  // Assign hotness flags to all code items.
  for (InvokeType invoke_type : invoke_types) {
    for (auto& class_def : header_->ClassDefs()) {
      const bool is_profile_class =
          info_->ContainsClass(*dex_file, dex::TypeIndex(class_def->ClassType()->GetIndex()));

      // Skip classes that are not defined in this dex file.
      dex_ir::ClassData* class_data = class_def->GetClassData();
      if (class_data == nullptr) {
        continue;
      }
      for (auto& method : *(invoke_type == InvokeType::kDirect
                                ? class_data->DirectMethods()
                                : class_data->VirtualMethods())) {
        const dex_ir::MethodId *method_id = method.GetMethodId();
        dex_ir::CodeItem *code_item = method.GetCodeItem();
        if (code_item == nullptr) {
          continue;
        }
        // Separate executed methods (clinits and profiled methods) from unexecuted methods.
        const bool is_clinit = (method.GetAccessFlags() & kAccConstructor) != 0 &&
            (method.GetAccessFlags() & kAccStatic) != 0;
        const bool is_startup_clinit = is_profile_class && is_clinit;
        using Hotness = ProfileCompilationInfo::MethodHotness;
        Hotness hotness = info_->GetMethodHotness(MethodReference(dex_file, method_id->GetIndex()));
        LayoutType state = LayoutType::kLayoutTypeUnused;
        if (hotness.IsHot()) {
          // Hot code is compiled, maybe one day it won't be accessed. So lay it out together for
          // now.
          state = LayoutType::kLayoutTypeHot;
        } else if (is_startup_clinit || hotness.GetFlags() == Hotness::kFlagStartup) {
          // Startup clinit or a method that only has the startup flag.
          state = LayoutType::kLayoutTypeStartupOnly;
        } else if (is_clinit) {
          state = LayoutType::kLayoutTypeUsedOnce;
        } else if (hotness.IsInProfile()) {
          state = LayoutType::kLayoutTypeSometimesUsed;
        }
        auto it = code_item_layout.emplace(code_item, state);
        if (!it.second) {
          LayoutType& layout_type = it.first->second;
          // Already exists, merge the hotness.
          layout_type = MergeLayoutType(layout_type, state);
        }
      }
    }
  }

  const auto& code_items = header_->CodeItems();
  if (VLOG_IS_ON(dex)) {
    size_t layout_count[static_cast<size_t>(LayoutType::kLayoutTypeCount)] = {};
    for (const std::unique_ptr<dex_ir::CodeItem>& code_item : code_items) {
      auto it = code_item_layout.find(code_item.get());
      DCHECK(it != code_item_layout.end());
      ++layout_count[static_cast<size_t>(it->second)];
    }
    for (size_t i = 0; i < static_cast<size_t>(LayoutType::kLayoutTypeCount); ++i) {
      LOG(INFO) << "Code items in category " << i << " count=" << layout_count[i];
    }
  }

  // Sort the code items vector by new layout. The writing process will take care of calculating
  // all the offsets. Stable sort to preserve any existing locality that might be there.
  std::stable_sort(code_items.begin(),
                   code_items.end(),
                   [&](const std::unique_ptr<dex_ir::CodeItem>& a,
                       const std::unique_ptr<dex_ir::CodeItem>& b) {
    auto it_a = code_item_layout.find(a.get());
    auto it_b = code_item_layout.find(b.get());
    DCHECK(it_a != code_item_layout.end());
    DCHECK(it_b != code_item_layout.end());
    const LayoutType layout_type_a = it_a->second;
    const LayoutType layout_type_b = it_b->second;
    return layout_type_a < layout_type_b;
  });
}

void DexLayout::LayoutOutputFile(const DexFile* dex_file) {
  LayoutStringData(dex_file);
  LayoutClassDefsAndClassData(dex_file);
  LayoutCodeItems(dex_file);
}

bool DexLayout::OutputDexFile(const DexFile* input_dex_file,
                              bool compute_offsets,
                              std::unique_ptr<DexContainer>* dex_container,
                              std::string* error_msg) {
  const std::string& dex_file_location = input_dex_file->GetLocation();
  std::unique_ptr<File> new_file;
  // If options_.output_dex_directory_ is non null, we are outputting to a file.
  if (options_.output_dex_directory_ != nullptr) {
    std::string output_location(options_.output_dex_directory_);
    const size_t last_slash = dex_file_location.rfind('/');
    std::string dex_file_directory = dex_file_location.substr(0, last_slash + 1);
    if (output_location == dex_file_directory) {
      output_location = dex_file_location + ".new";
    } else {
      if (!output_location.empty() && output_location.back() != '/') {
        output_location += "/";
      }
      const size_t separator = dex_file_location.rfind('!');
      if (separator != std::string::npos) {
        output_location += dex_file_location.substr(separator + 1);
      } else {
        output_location += "classes.dex";
      }
    }
    new_file.reset(OS::CreateEmptyFile(output_location.c_str()));
    if (new_file == nullptr) {
      LOG(ERROR) << "Could not create dex writer output file: " << output_location;
      return false;
    }
  }
  if (!DexWriter::Output(this, dex_container, compute_offsets, error_msg)) {
    return false;
  }
  if (new_file != nullptr) {
    DexContainer* const container = dex_container->get();
    DexContainer::Section* const main_section = container->GetMainSection();
    if (!new_file->WriteFully(main_section->Begin(), main_section->Size())) {
      LOG(ERROR) << "Failed to write main section for dex file " << dex_file_location;
      new_file->Erase();
      return false;
    }
    DexContainer::Section* const data_section = container->GetDataSection();
    if (!new_file->WriteFully(data_section->Begin(), data_section->Size())) {
      LOG(ERROR) << "Failed to write data section for dex file " << dex_file_location;
      new_file->Erase();
      return false;
    }
    UNUSED(new_file->FlushCloseOrErase());
  }
  return true;
}

/*
 * Dumps the requested sections of the file.
 */
bool DexLayout::ProcessDexFile(const char* file_name,
                               const DexFile* dex_file,
                               size_t dex_file_index,
                               std::unique_ptr<DexContainer>* dex_container,
                               std::string* error_msg) {
  const bool has_output_container = dex_container != nullptr;
  const bool output = options_.output_dex_directory_ != nullptr || has_output_container;

  // Try to avoid eagerly assigning offsets to find bugs since Offset will abort if the offset
  // is unassigned.
  bool eagerly_assign_offsets = false;
  if (options_.visualize_pattern_ || options_.show_section_statistics_ || options_.dump_) {
    // These options required the offsets for dumping purposes.
    eagerly_assign_offsets = true;
  }
  std::unique_ptr<dex_ir::Header> header(dex_ir::DexIrBuilder(*dex_file,
                                                               eagerly_assign_offsets,
                                                               GetOptions()));
  SetHeader(header.get());

  // Dexlayout does not support containers, but allow it if it has just single dex file.
  const DexFile::Header& hdr = dex_file->GetHeader();
  if (hdr.HeaderOffset() != 0u || hdr.ContainerSize() != hdr.file_size_) {
    *error_msg = "DEX containers are not supported in dexlayout";
    DCHECK(false) << *error_msg;
    return false;
  }

  if (options_.verbose_) {
    fprintf(out_file_,
            "Opened '%s', DEX version '%.3s'\n",
            file_name,
            dex_file->GetHeader().magic_.data() + 4);
  }

  if (options_.visualize_pattern_) {
    VisualizeDexLayout(header_, dex_file, dex_file_index, info_);
    return true;
  }

  if (options_.show_section_statistics_) {
    ShowDexSectionStatistics(header_, dex_file_index, page_size_);
    return true;
  }

  // Dump dex file.
  if (options_.dump_) {
    DumpDexFile();
  }

  // In case we are outputting to a file, keep it open so we can verify.
  if (output) {
    // Layout information about what strings and code items are hot. Used by the writing process
    // to generate the sections that are stored in the oat file.
    bool do_layout = info_ != nullptr && !info_->IsEmpty();
    if (do_layout) {
      LayoutOutputFile(dex_file);
    }
    // The output needs a dex container, use a temporary one.
    std::unique_ptr<DexContainer> temp_container;
    if (dex_container == nullptr) {
      dex_container = &temp_container;
    }
    // If we didn't set the offsets eagerly, we definitely need to compute them here.
    if (!OutputDexFile(dex_file, do_layout || !eagerly_assign_offsets, dex_container, error_msg)) {
      return false;
    }

    // Clear header before verifying to reduce peak RAM usage.
    const size_t file_size = header_->FileSize();
    header.reset();

    // Verify the output dex file's structure, only enabled by default for debug builds.
    if (options_.verify_output_ && has_output_container) {
      std::string location = "memory mapped file for " + std::string(file_name);
      // Dex file verifier cannot handle compact dex.
      bool verify = options_.compact_dex_level_ == CompactDexLevel::kCompactDexLevelNone;
      DexContainer::Section* const main_section = (*dex_container)->GetMainSection();
      DexContainer::Section* const data_section = (*dex_container)->GetDataSection();
      DCHECK_EQ(file_size, main_section->Size())
          << main_section->Size() << " " << data_section->Size();
      auto container = std::make_unique<DexLoaderContainer>(
          main_section->Begin(), main_section->End(), data_section->Begin(), data_section->End());
      ArtDexFileLoader dex_file_loader(std::move(container), location);
      std::unique_ptr<const DexFile> output_dex_file(
          dex_file_loader.Open(/* location_checksum= */ 0,
                               /*oat_dex_file=*/nullptr,
                               verify,
                               /*verify_checksum=*/false,
                               error_msg));
      CHECK(output_dex_file != nullptr) << "Failed to re-open output file:" << *error_msg;

      // Do IR-level comparison between input and output. This check ignores potential differences
      // due to layout, so offsets are not checked. Instead, it checks the data contents of each
      // item.
      //
      // Regenerate output IR to catch any bugs that might happen during writing.
      std::unique_ptr<dex_ir::Header> output_header(
          dex_ir::DexIrBuilder(*output_dex_file,
                               /*eagerly_assign_offsets=*/ true,
                               GetOptions()));
      std::unique_ptr<dex_ir::Header> orig_header(
          dex_ir::DexIrBuilder(*dex_file,
                               /*eagerly_assign_offsets=*/ true,
                               GetOptions()));
      CHECK(VerifyOutputDexFile(output_header.get(), orig_header.get(), error_msg)) << *error_msg;
    }
  }
  return true;
}

/*
 * Processes a single file (either direct .dex or indirect .zip/.jar/.apk).
 */
int DexLayout::ProcessFile(const char* file_name) {
  if (options_.verbose_) {
    fprintf(out_file_, "Processing '%s'...\n", file_name);
  }

  // If the file is not a .dex file, the function tries .zip/.jar/.apk files,
  // all of which are Zip archives with "classes.dex" inside.
  const bool verify_checksum = !options_.ignore_bad_checksum_;
  std::string error_msg;
  ArtDexFileLoader dex_file_loader(file_name);
  std::vector<std::unique_ptr<const DexFile>> dex_files;
  if (!dex_file_loader.Open(
          /* verify= */ true, verify_checksum, &error_msg, &dex_files)) {
    // Display returned error message to user. Note that this error behavior
    // differs from the error messages shown by the original Dalvik dexdump.
    LOG(ERROR) << error_msg;
    return -1;
  }

  // Success. Either report checksum verification or process
  // all dex files found in given file.
  if (options_.checksum_only_) {
    fprintf(out_file_, "Checksum verified\n");
  } else {
    for (size_t i = 0; i < dex_files.size(); i++) {
      // Pass in a null container to avoid output by default.
      if (!ProcessDexFile(file_name,
                          dex_files[i].get(),
                          i,
                          /*dex_container=*/ nullptr,
                          &error_msg)) {
        LOG(WARNING) << "Failed to run dex file " << i << " in " << file_name << " : " << error_msg;
      }
    }
  }
  return 0;
}

}  // namespace art
