/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdio.h>
#include <stdlib.h>

#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <unordered_set>

#include "art_method-inl.h"
#include "base/unix_file/fd_file.h"
#include "base/stringprintf.h"
#include "gc/space/image_space.h"
#include "gc/heap.h"
#include "mirror/class-inl.h"
#include "mirror/object-inl.h"
#include "image.h"
#include "scoped_thread_state_change.h"
#include "os.h"
#include "gc_map.h"

#include "cmdline.h"
#include "backtrace/BacktraceMap.h"

#include <sys/stat.h>
#include <sys/types.h>
#include <signal.h>

namespace art {

class ImgDiagDumper {
 public:
  explicit ImgDiagDumper(std::ostream* os,
                         const ImageHeader& image_header,
                         const std::string& image_location,
                         pid_t image_diff_pid)
      : os_(os),
        image_header_(image_header),
        image_location_(image_location),
        image_diff_pid_(image_diff_pid) {}

  bool Dump() SHARED_REQUIRES(Locks::mutator_lock_) {
    std::ostream& os = *os_;
    os << "IMAGE LOCATION: " << image_location_ << "\n\n";

    os << "MAGIC: " << image_header_.GetMagic() << "\n\n";

    os << "IMAGE BEGIN: " << reinterpret_cast<void*>(image_header_.GetImageBegin()) << "\n\n";

    bool ret = true;
    if (image_diff_pid_ >= 0) {
      os << "IMAGE DIFF PID (" << image_diff_pid_ << "): ";
      ret = DumpImageDiff(image_diff_pid_);
      os << "\n\n";
    } else {
      os << "IMAGE DIFF PID: disabled\n\n";
    }

    os << std::flush;

    return ret;
  }

 private:
  static bool EndsWith(const std::string& str, const std::string& suffix) {
    return str.size() >= suffix.size() &&
           str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
  }

  // Return suffix of the file path after the last /. (e.g. /foo/bar -> bar, bar -> bar)
  static std::string BaseName(const std::string& str) {
    size_t idx = str.rfind("/");
    if (idx == std::string::npos) {
      return str;
    }

    return str.substr(idx + 1);
  }

  bool DumpImageDiff(pid_t image_diff_pid) SHARED_REQUIRES(Locks::mutator_lock_) {
    std::ostream& os = *os_;

    {
      struct stat sts;
      std::string proc_pid_str =
          StringPrintf("/proc/%ld", static_cast<long>(image_diff_pid));  // NOLINT [runtime/int]
      if (stat(proc_pid_str.c_str(), &sts) == -1) {
        os << "Process does not exist";
        return false;
      }
    }

    // Open /proc/$pid/maps to view memory maps
    auto proc_maps = std::unique_ptr<BacktraceMap>(BacktraceMap::Create(image_diff_pid));
    if (proc_maps == nullptr) {
      os << "Could not read backtrace maps";
      return false;
    }

    bool found_boot_map = false;
    backtrace_map_t boot_map = backtrace_map_t();
    // Find the memory map only for boot.art
    for (const backtrace_map_t& map : *proc_maps) {
      if (EndsWith(map.name, GetImageLocationBaseName())) {
        if ((map.flags & PROT_WRITE) != 0) {
          boot_map = map;
          found_boot_map = true;
          break;
        }
        // In actuality there's more than 1 map, but the second one is read-only.
        // The one we care about is the write-able map.
        // The readonly maps are guaranteed to be identical, so its not interesting to compare
        // them.
      }
    }

    if (!found_boot_map) {
      os << "Could not find map for " << GetImageLocationBaseName();
      return false;
    }

    // Future idea: diff against zygote so we can ignore the shared dirty pages.
    return DumpImageDiffMap(image_diff_pid, boot_map);
  }

  static std::string PrettyFieldValue(ArtField* field, mirror::Object* obj)
      SHARED_REQUIRES(Locks::mutator_lock_) {
    std::ostringstream oss;
    switch (field->GetTypeAsPrimitiveType()) {
      case Primitive::kPrimNot: {
        oss << obj->GetFieldObject<mirror::Object, kVerifyNone, kWithoutReadBarrier>(
            field->GetOffset());
        break;
      }
      case Primitive::kPrimBoolean: {
        oss << static_cast<bool>(obj->GetFieldBoolean<kVerifyNone>(field->GetOffset()));
        break;
      }
      case Primitive::kPrimByte: {
        oss << static_cast<int32_t>(obj->GetFieldByte<kVerifyNone>(field->GetOffset()));
        break;
      }
      case Primitive::kPrimChar: {
        oss << obj->GetFieldChar<kVerifyNone>(field->GetOffset());
        break;
      }
      case Primitive::kPrimShort: {
        oss << obj->GetFieldShort<kVerifyNone>(field->GetOffset());
        break;
      }
      case Primitive::kPrimInt: {
        oss << obj->GetField32<kVerifyNone>(field->GetOffset());
        break;
      }
      case Primitive::kPrimLong: {
        oss << obj->GetField64<kVerifyNone>(field->GetOffset());
        break;
      }
      case Primitive::kPrimFloat: {
        oss << obj->GetField32<kVerifyNone>(field->GetOffset());
        break;
      }
      case Primitive::kPrimDouble: {
        oss << obj->GetField64<kVerifyNone>(field->GetOffset());
        break;
      }
      case Primitive::kPrimVoid: {
        oss << "void";
        break;
      }
    }
    return oss.str();
  }

  // Look at /proc/$pid/mem and only diff the things from there
  bool DumpImageDiffMap(pid_t image_diff_pid, const backtrace_map_t& boot_map)
    SHARED_REQUIRES(Locks::mutator_lock_) {
    std::ostream& os = *os_;
    const size_t pointer_size = InstructionSetPointerSize(
        Runtime::Current()->GetInstructionSet());

    std::string file_name =
        StringPrintf("/proc/%ld/mem", static_cast<long>(image_diff_pid));  // NOLINT [runtime/int]

    size_t boot_map_size = boot_map.end - boot_map.start;

    // Open /proc/$pid/mem as a file
    auto map_file = std::unique_ptr<File>(OS::OpenFileForReading(file_name.c_str()));
    if (map_file == nullptr) {
      os << "Failed to open " << file_name << " for reading";
      return false;
    }

    // Memory-map /proc/$pid/mem subset from the boot map
    CHECK(boot_map.end >= boot_map.start);

    std::string error_msg;

    // Walk the bytes and diff against our boot image
    const ImageHeader& boot_image_header = image_header_;

    os << "\nObserving boot image header at address "
       << reinterpret_cast<const void*>(&boot_image_header)
       << "\n\n";

    const uint8_t* image_begin_unaligned = boot_image_header.GetImageBegin();
    const uint8_t* image_mirror_end_unaligned = image_begin_unaligned +
        boot_image_header.GetImageSection(ImageHeader::kSectionObjects).Size();
    const uint8_t* image_end_unaligned = image_begin_unaligned + boot_image_header.GetImageSize();

    // Adjust range to nearest page
    const uint8_t* image_begin = AlignDown(image_begin_unaligned, kPageSize);
    const uint8_t* image_end = AlignUp(image_end_unaligned, kPageSize);

    ptrdiff_t page_off_begin = boot_image_header.GetImageBegin() - image_begin;

    if (reinterpret_cast<uintptr_t>(image_begin) > boot_map.start ||
        reinterpret_cast<uintptr_t>(image_end) < boot_map.end) {
      // Sanity check that we aren't trying to read a completely different boot image
      os << "Remote boot map is out of range of local boot map: " <<
        "local begin " << reinterpret_cast<const void*>(image_begin) <<
        ", local end " << reinterpret_cast<const void*>(image_end) <<
        ", remote begin " << reinterpret_cast<const void*>(boot_map.start) <<
        ", remote end " << reinterpret_cast<const void*>(boot_map.end);
      return false;
      // If we wanted even more validation we could map the ImageHeader from the file
    }

    std::vector<uint8_t> remote_contents(boot_map_size);
    if (!map_file->PreadFully(&remote_contents[0], boot_map_size, boot_map.start)) {
      os << "Could not fully read file " << file_name;
      return false;
    }

    std::string page_map_file_name = StringPrintf(
        "/proc/%ld/pagemap", static_cast<long>(image_diff_pid));  // NOLINT [runtime/int]
    auto page_map_file = std::unique_ptr<File>(OS::OpenFileForReading(page_map_file_name.c_str()));
    if (page_map_file == nullptr) {
      os << "Failed to open " << page_map_file_name << " for reading: " << strerror(errno);
      return false;
    }

    // Not truly clean, mmap-ing boot.art again would be more pristine, but close enough
    const char* clean_page_map_file_name = "/proc/self/pagemap";
    auto clean_page_map_file = std::unique_ptr<File>(
        OS::OpenFileForReading(clean_page_map_file_name));
    if (clean_page_map_file == nullptr) {
      os << "Failed to open " << clean_page_map_file_name << " for reading: " << strerror(errno);
      return false;
    }

    auto kpage_flags_file = std::unique_ptr<File>(OS::OpenFileForReading("/proc/kpageflags"));
    if (kpage_flags_file == nullptr) {
      os << "Failed to open /proc/kpageflags for reading: " << strerror(errno);
      return false;
    }

    auto kpage_count_file = std::unique_ptr<File>(OS::OpenFileForReading("/proc/kpagecount"));
    if (kpage_count_file == nullptr) {
      os << "Failed to open /proc/kpagecount for reading:" << strerror(errno);
      return false;
    }

    // Set of the remote virtual page indices that are dirty
    std::set<size_t> dirty_page_set_remote;
    // Set of the local virtual page indices that are dirty
    std::set<size_t> dirty_page_set_local;

    size_t different_int32s = 0;
    size_t different_bytes = 0;
    size_t different_pages = 0;
    size_t virtual_page_idx = 0;   // Virtual page number (for an absolute memory address)
    size_t page_idx = 0;           // Page index relative to 0
    size_t previous_page_idx = 0;  // Previous page index relative to 0
    size_t dirty_pages = 0;
    size_t private_pages = 0;
    size_t private_dirty_pages = 0;

    // Iterate through one page at a time. Boot map begin/end already implicitly aligned.
    for (uintptr_t begin = boot_map.start; begin != boot_map.end; begin += kPageSize) {
      ptrdiff_t offset = begin - boot_map.start;

      // We treat the image header as part of the memory map for now
      // If we wanted to change this, we could pass base=start+sizeof(ImageHeader)
      // But it might still be interesting to see if any of the ImageHeader data mutated
      const uint8_t* local_ptr = reinterpret_cast<const uint8_t*>(&boot_image_header) + offset;
      uint8_t* remote_ptr = &remote_contents[offset];

      if (memcmp(local_ptr, remote_ptr, kPageSize) != 0) {
        different_pages++;

        // Count the number of 32-bit integers that are different.
        for (size_t i = 0; i < kPageSize / sizeof(uint32_t); ++i) {
          uint32_t* remote_ptr_int32 = reinterpret_cast<uint32_t*>(remote_ptr);
          const uint32_t* local_ptr_int32 = reinterpret_cast<const uint32_t*>(local_ptr);

          if (remote_ptr_int32[i] != local_ptr_int32[i]) {
            different_int32s++;
          }
        }
      }
    }

    // Iterate through one byte at a time.
    for (uintptr_t begin = boot_map.start; begin != boot_map.end; ++begin) {
      previous_page_idx = page_idx;
      ptrdiff_t offset = begin - boot_map.start;

      // We treat the image header as part of the memory map for now
      // If we wanted to change this, we could pass base=start+sizeof(ImageHeader)
      // But it might still be interesting to see if any of the ImageHeader data mutated
      const uint8_t* local_ptr = reinterpret_cast<const uint8_t*>(&boot_image_header) + offset;
      uint8_t* remote_ptr = &remote_contents[offset];

      virtual_page_idx = reinterpret_cast<uintptr_t>(local_ptr) / kPageSize;

      // Calculate the page index, relative to the 0th page where the image begins
      page_idx = (offset + page_off_begin) / kPageSize;
      if (*local_ptr != *remote_ptr) {
        // Track number of bytes that are different
        different_bytes++;
      }

      // Independently count the # of dirty pages on the remote side
      size_t remote_virtual_page_idx = begin / kPageSize;
      if (previous_page_idx != page_idx) {
        uint64_t page_count = 0xC0FFEE;
        // TODO: virtual_page_idx needs to be from the same process
        int dirtiness = (IsPageDirty(page_map_file.get(),        // Image-diff-pid procmap
                                     clean_page_map_file.get(),  // Self procmap
                                     kpage_flags_file.get(),
                                     kpage_count_file.get(),
                                     remote_virtual_page_idx,    // potentially "dirty" page
                                     virtual_page_idx,           // true "clean" page
                                     &page_count,
                                     &error_msg));
        if (dirtiness < 0) {
          os << error_msg;
          return false;
        } else if (dirtiness > 0) {
          dirty_pages++;
          dirty_page_set_remote.insert(dirty_page_set_remote.end(), remote_virtual_page_idx);
          dirty_page_set_local.insert(dirty_page_set_local.end(), virtual_page_idx);
        }

        bool is_dirty = dirtiness > 0;
        bool is_private = page_count == 1;

        if (page_count == 1) {
          private_pages++;
        }

        if (is_dirty && is_private) {
          private_dirty_pages++;
        }
      }
    }

    // Walk each object in the remote image space and compare it against ours
    size_t different_objects = 0;
    std::map<mirror::Class*, int /*count*/> dirty_object_class_map;
    // Track only the byte-per-byte dirtiness (in bytes)
    std::map<mirror::Class*, int /*byte_count*/> dirty_object_byte_count;
    // Track the object-by-object dirtiness (in bytes)
    std::map<mirror::Class*, int /*byte_count*/> dirty_object_size_in_bytes;
    std::map<mirror::Class*, int /*count*/> clean_object_class_map;

    std::map<mirror::Class*, std::string> class_to_descriptor_map;

    std::map<off_t /* field offset */, int /* count */> art_method_field_dirty_count;
    std::vector<ArtMethod*> art_method_dirty_objects;

    std::map<off_t /* field offset */, int /* count */> class_field_dirty_count;
    std::vector<mirror::Class*> class_dirty_objects;

    // List of local objects that are clean, but located on dirty pages.
    std::vector<mirror::Object*> false_dirty_objects;
    std::map<mirror::Class*, int /*byte_count*/> false_dirty_byte_count;
    std::map<mirror::Class*, int /*object_count*/> false_dirty_object_count;
    std::map<mirror::Class*, std::vector<mirror::Object*>> false_dirty_objects_map;
    size_t false_dirty_object_bytes = 0;

    // Remote pointers to dirty objects
    std::map<mirror::Class*, std::vector<mirror::Object*>> dirty_objects_by_class;
    // Look up remote classes by their descriptor
    std::map<std::string, mirror::Class*> remote_class_map;
    // Look up local classes by their descriptor
    std::map<std::string, mirror::Class*> local_class_map;

    std::unordered_set<mirror::Object*> dirty_objects;

    size_t dirty_object_bytes = 0;
    const uint8_t* begin_image_ptr = image_begin_unaligned;
    const uint8_t* end_image_ptr = image_mirror_end_unaligned;

    const uint8_t* current = begin_image_ptr + RoundUp(sizeof(ImageHeader), kObjectAlignment);
    while (reinterpret_cast<uintptr_t>(current) < reinterpret_cast<uintptr_t>(end_image_ptr)) {
      CHECK_ALIGNED(current, kObjectAlignment);
      mirror::Object* obj = reinterpret_cast<mirror::Object*>(const_cast<uint8_t*>(current));

      // Sanity check that we are reading a real object
      CHECK(obj->GetClass() != nullptr) << "Image object at address " << obj << " has null class";
      if (kUseBakerOrBrooksReadBarrier) {
        obj->AssertReadBarrierPointer();
      }

      // Iterate every page this object belongs to
      bool on_dirty_page = false;
      size_t page_off = 0;
      size_t current_page_idx;
      uintptr_t object_address;
      do {
        object_address = reinterpret_cast<uintptr_t>(current);
        current_page_idx = object_address / kPageSize + page_off;

        if (dirty_page_set_local.find(current_page_idx) != dirty_page_set_local.end()) {
          // This object is on a dirty page
          on_dirty_page = true;
        }

        page_off++;
      } while ((current_page_idx * kPageSize) <
               RoundUp(object_address + obj->SizeOf(), kObjectAlignment));

      mirror::Class* klass = obj->GetClass();

      bool different_object = false;

      // Check against the other object and see if they are different
      ptrdiff_t offset = current - begin_image_ptr;
      const uint8_t* current_remote = &remote_contents[offset];
      mirror::Object* remote_obj = reinterpret_cast<mirror::Object*>(
          const_cast<uint8_t*>(current_remote));
      if (memcmp(current, current_remote, obj->SizeOf()) != 0) {
        different_objects++;
        dirty_object_bytes += obj->SizeOf();
        dirty_objects.insert(obj);

        ++dirty_object_class_map[klass];

        // Go byte-by-byte and figure out what exactly got dirtied
        size_t dirty_byte_count_per_object = 0;
        for (size_t i = 0; i < obj->SizeOf(); ++i) {
          if (current[i] != current_remote[i]) {
            dirty_byte_count_per_object++;
          }
        }
        dirty_object_byte_count[klass] += dirty_byte_count_per_object;
        dirty_object_size_in_bytes[klass] += obj->SizeOf();

        different_object = true;

        dirty_objects_by_class[klass].push_back(remote_obj);
      } else {
        ++clean_object_class_map[klass];
      }

      std::string descriptor = GetClassDescriptor(klass);
      if (different_object) {
        if (klass->IsClassClass()) {
          // this is a "Class"
          mirror::Class* obj_as_class  = reinterpret_cast<mirror::Class*>(remote_obj);

          // print the fields that are dirty
          for (size_t i = 0; i < obj->SizeOf(); ++i) {
            if (current[i] != current_remote[i]) {
              class_field_dirty_count[i]++;
            }
          }

          class_dirty_objects.push_back(obj_as_class);
        } else if (strcmp(descriptor.c_str(), "Ljava/lang/reflect/ArtMethod;") == 0) {
          // this is an ArtMethod
          ArtMethod* art_method = reinterpret_cast<ArtMethod*>(remote_obj);

          // print the fields that are dirty
          for (size_t i = 0; i < obj->SizeOf(); ++i) {
            if (current[i] != current_remote[i]) {
              art_method_field_dirty_count[i]++;
            }
          }

          art_method_dirty_objects.push_back(art_method);
        }
      } else if (on_dirty_page) {
        // This object was either never mutated or got mutated back to the same value.
        // TODO: Do I want to distinguish a "different" vs a "dirty" page here?
        false_dirty_objects.push_back(obj);
        false_dirty_objects_map[klass].push_back(obj);
        false_dirty_object_bytes += obj->SizeOf();
        false_dirty_byte_count[obj->GetClass()] += obj->SizeOf();
        false_dirty_object_count[obj->GetClass()] += 1;
      }

      if (strcmp(descriptor.c_str(), "Ljava/lang/Class;") == 0) {
        local_class_map[descriptor] = reinterpret_cast<mirror::Class*>(obj);
        remote_class_map[descriptor] = reinterpret_cast<mirror::Class*>(remote_obj);
      }

      // Unconditionally store the class descriptor in case we need it later
      class_to_descriptor_map[klass] = descriptor;
      current += RoundUp(obj->SizeOf(), kObjectAlignment);
    }

    // Looking at only dirty pages, figure out how many of those bytes belong to dirty objects.
    float true_dirtied_percent = dirty_object_bytes * 1.0f / (dirty_pages * kPageSize);
    size_t false_dirty_pages = dirty_pages - different_pages;

    os << "Mapping at [" << reinterpret_cast<void*>(boot_map.start) << ", "
       << reinterpret_cast<void*>(boot_map.end) << ") had: \n  "
       << different_bytes << " differing bytes, \n  "
       << different_int32s << " differing int32s, \n  "
       << different_objects << " different objects, \n  "
       << dirty_object_bytes << " different object [bytes], \n  "
       << false_dirty_objects.size() << " false dirty objects,\n  "
       << false_dirty_object_bytes << " false dirty object [bytes], \n  "
       << true_dirtied_percent << " different objects-vs-total in a dirty page;\n  "
       << different_pages << " different pages; \n  "
       << dirty_pages << " pages are dirty; \n  "
       << false_dirty_pages << " pages are false dirty; \n  "
       << private_pages << " pages are private; \n  "
       << private_dirty_pages << " pages are Private_Dirty\n  "
       << "";

    // vector of pairs (int count, Class*)
    auto dirty_object_class_values = SortByValueDesc(dirty_object_class_map);
    auto clean_object_class_values = SortByValueDesc(clean_object_class_map);

    os << "\n" << "  Dirty objects: " << dirty_objects.size() << "\n";
    for (mirror::Object* obj : dirty_objects) {
      const char* tabs = "    ";
      // Attempt to find fields for all dirty bytes.
      mirror::Class* klass = obj->GetClass();
      if (obj->IsClass()) {
        os << tabs << "Class " << PrettyClass(obj->AsClass()) << " " << obj << "\n";
      } else {
        os << tabs << "Instance of " << PrettyClass(klass) << " " << obj << "\n";
      }

      std::unordered_set<ArtField*> dirty_instance_fields;
      std::unordered_set<ArtField*> dirty_static_fields;
      const uint8_t* obj_bytes = reinterpret_cast<const uint8_t*>(obj);
      ptrdiff_t offset = obj_bytes - begin_image_ptr;
      uint8_t* remote_bytes = &remote_contents[offset];
      mirror::Object* remote_obj = reinterpret_cast<mirror::Object*>(remote_bytes);
      for (size_t i = 0, count = obj->SizeOf(); i < count; ++i) {
        if (obj_bytes[i] != remote_bytes[i]) {
          ArtField* field = ArtField::FindInstanceFieldWithOffset</*exact*/false>(klass, i);
          if (field != nullptr) {
            dirty_instance_fields.insert(field);
          } else if (obj->IsClass()) {
            field = ArtField::FindStaticFieldWithOffset</*exact*/false>(obj->AsClass(), i);
            if (field != nullptr) {
              dirty_static_fields.insert(field);
            }
          }
          if (field == nullptr) {
            if (klass->IsArrayClass()) {
              mirror::Class* component_type = klass->GetComponentType();
              Primitive::Type primitive_type = component_type->GetPrimitiveType();
              size_t component_size = Primitive::ComponentSize(primitive_type);
              size_t data_offset = mirror::Array::DataOffset(component_size).Uint32Value();
              if (i >= data_offset) {
                os << tabs << "Dirty array element " << (i - data_offset) / component_size << "\n";
                // Skip to next element to prevent spam.
                i += component_size - 1;
                continue;
              }
            }
            os << tabs << "No field for byte offset " << i << "\n";
          }
        }
      }
      // Dump different fields. TODO: Dump field contents.
      if (!dirty_instance_fields.empty()) {
        os << tabs << "Dirty instance fields " << dirty_instance_fields.size() << "\n";
        for (ArtField* field : dirty_instance_fields) {
          os << tabs << PrettyField(field)
             << " original=" << PrettyFieldValue(field, obj)
             << " remote=" << PrettyFieldValue(field, remote_obj) << "\n";
        }
      }
      if (!dirty_static_fields.empty()) {
        os << tabs << "Dirty static fields " << dirty_static_fields.size() << "\n";
        for (ArtField* field : dirty_static_fields) {
          os << tabs << PrettyField(field)
             << " original=" << PrettyFieldValue(field, obj)
             << " remote=" << PrettyFieldValue(field, remote_obj) << "\n";
        }
      }
      os << "\n";
    }

    os << "\n" << "  Dirty object count by class:\n";
    for (const auto& vk_pair : dirty_object_class_values) {
      int dirty_object_count = vk_pair.first;
      mirror::Class* klass = vk_pair.second;
      int object_sizes = dirty_object_size_in_bytes[klass];
      float avg_dirty_bytes_per_class = dirty_object_byte_count[klass] * 1.0f / object_sizes;
      float avg_object_size = object_sizes * 1.0f / dirty_object_count;
      const std::string& descriptor = class_to_descriptor_map[klass];
      os << "    " << PrettyClass(klass) << " ("
         << "objects: " << dirty_object_count << ", "
         << "avg dirty bytes: " << avg_dirty_bytes_per_class << ", "
         << "avg object size: " << avg_object_size << ", "
         << "class descriptor: '" << descriptor << "'"
         << ")\n";

      constexpr size_t kMaxAddressPrint = 5;
      if (strcmp(descriptor.c_str(), "Ljava/lang/reflect/ArtMethod;") == 0) {
        os << "      sample object addresses: ";
        for (size_t i = 0; i < art_method_dirty_objects.size() && i < kMaxAddressPrint; ++i) {
          auto art_method = art_method_dirty_objects[i];

          os << reinterpret_cast<void*>(art_method) << ", ";
        }
        os << "\n";

        os << "      dirty byte +offset:count list = ";
        auto art_method_field_dirty_count_sorted = SortByValueDesc(art_method_field_dirty_count);
        for (auto pair : art_method_field_dirty_count_sorted) {
          off_t offset = pair.second;
          int count = pair.first;

          os << "+" << offset << ":" << count << ", ";
        }

        os << "\n";

        os << "      field contents:\n";
        const auto& dirty_objects_list = dirty_objects_by_class[klass];
        for (mirror::Object* obj : dirty_objects_list) {
          // remote method
          auto art_method = reinterpret_cast<ArtMethod*>(obj);

          // remote class
          mirror::Class* remote_declaring_class =
            FixUpRemotePointer(art_method->GetDeclaringClass(), remote_contents, boot_map);

          // local class
          mirror::Class* declaring_class =
            RemoteContentsPointerToLocal(remote_declaring_class,
                                         remote_contents,
                                         boot_image_header);

          os << "        " << reinterpret_cast<void*>(obj) << " ";
          os << "  entryPointFromJni: "
             << reinterpret_cast<const void*>(
                    art_method->GetEntryPointFromJniPtrSize(pointer_size)) << ", ";
          os << "  entryPointFromQuickCompiledCode: "
             << reinterpret_cast<const void*>(
                    art_method->GetEntryPointFromQuickCompiledCodePtrSize(pointer_size))
             << ", ";
          os << "  isNative? " << (art_method->IsNative() ? "yes" : "no") << ", ";
          os << "  class_status (local): " << declaring_class->GetStatus();
          os << "  class_status (remote): " << remote_declaring_class->GetStatus();
          os << "\n";
        }
      }
      if (strcmp(descriptor.c_str(), "Ljava/lang/Class;") == 0) {
        os << "       sample object addresses: ";
        for (size_t i = 0; i < class_dirty_objects.size() && i < kMaxAddressPrint; ++i) {
          auto class_ptr = class_dirty_objects[i];

          os << reinterpret_cast<void*>(class_ptr) << ", ";
        }
        os << "\n";

        os << "       dirty byte +offset:count list = ";
        auto class_field_dirty_count_sorted = SortByValueDesc(class_field_dirty_count);
        for (auto pair : class_field_dirty_count_sorted) {
          off_t offset = pair.second;
          int count = pair.first;

          os << "+" << offset << ":" << count << ", ";
        }
        os << "\n";

        os << "      field contents:\n";
        const auto& dirty_objects_list = dirty_objects_by_class[klass];
        for (mirror::Object* obj : dirty_objects_list) {
          // remote class object
          auto remote_klass = reinterpret_cast<mirror::Class*>(obj);

          // local class object
          auto local_klass = RemoteContentsPointerToLocal(remote_klass,
                                                          remote_contents,
                                                          boot_image_header);

          os << "        " << reinterpret_cast<void*>(obj) << " ";
          os << "  class_status (remote): " << remote_klass->GetStatus() << ", ";
          os << "  class_status (local): " << local_klass->GetStatus();
          os << "\n";
        }
      }
    }

    auto false_dirty_object_class_values = SortByValueDesc(false_dirty_object_count);

    os << "\n" << "  False-dirty object count by class:\n";
    for (const auto& vk_pair : false_dirty_object_class_values) {
      int object_count = vk_pair.first;
      mirror::Class* klass = vk_pair.second;
      int object_sizes = false_dirty_byte_count[klass];
      float avg_object_size = object_sizes * 1.0f / object_count;
      const std::string& descriptor = class_to_descriptor_map[klass];
      os << "    " << PrettyClass(klass) << " ("
         << "objects: " << object_count << ", "
         << "avg object size: " << avg_object_size << ", "
         << "total bytes: " << object_sizes << ", "
         << "class descriptor: '" << descriptor << "'"
         << ")\n";

      if (strcmp(descriptor.c_str(), "Ljava/lang/reflect/ArtMethod;") == 0) {
        auto& art_method_false_dirty_objects = false_dirty_objects_map[klass];

        os << "      field contents:\n";
        for (mirror::Object* obj : art_method_false_dirty_objects) {
          // local method
          auto art_method = reinterpret_cast<ArtMethod*>(obj);

          // local class
          mirror::Class* declaring_class = art_method->GetDeclaringClass();

          os << "        " << reinterpret_cast<void*>(obj) << " ";
          os << "  entryPointFromJni: "
             << reinterpret_cast<const void*>(
                    art_method->GetEntryPointFromJniPtrSize(pointer_size)) << ", ";
          os << "  entryPointFromQuickCompiledCode: "
             << reinterpret_cast<const void*>(
                    art_method->GetEntryPointFromQuickCompiledCodePtrSize(pointer_size))
             << ", ";
          os << "  isNative? " << (art_method->IsNative() ? "yes" : "no") << ", ";
          os << "  class_status (local): " << declaring_class->GetStatus();
          os << "\n";
        }
      }
    }

    os << "\n" << "  Clean object count by class:\n";
    for (const auto& vk_pair : clean_object_class_values) {
      os << "    " << PrettyClass(vk_pair.second) << " (" << vk_pair.first << ")\n";
    }

    return true;
  }

  // Fixup a remote pointer that we read from a foreign boot.art to point to our own memory.
  // Returned pointer will point to inside of remote_contents.
  template <typename T>
  static T* FixUpRemotePointer(T* remote_ptr,
                               std::vector<uint8_t>& remote_contents,
                               const backtrace_map_t& boot_map) {
    if (remote_ptr == nullptr) {
      return nullptr;
    }

    uintptr_t remote = reinterpret_cast<uintptr_t>(remote_ptr);

    CHECK_LE(boot_map.start, remote);
    CHECK_GT(boot_map.end, remote);

    off_t boot_offset = remote - boot_map.start;

    return reinterpret_cast<T*>(&remote_contents[boot_offset]);
  }

  template <typename T>
  static T* RemoteContentsPointerToLocal(T* remote_ptr,
                                         std::vector<uint8_t>& remote_contents,
                                         const ImageHeader& image_header) {
    if (remote_ptr == nullptr) {
      return nullptr;
    }

    uint8_t* remote = reinterpret_cast<uint8_t*>(remote_ptr);
    ptrdiff_t boot_offset = remote - &remote_contents[0];

    const uint8_t* local_ptr = reinterpret_cast<const uint8_t*>(&image_header) + boot_offset;

    return reinterpret_cast<T*>(const_cast<uint8_t*>(local_ptr));
  }

  static std::string GetClassDescriptor(mirror::Class* klass)
    SHARED_REQUIRES(Locks::mutator_lock_) {
    CHECK(klass != nullptr);

    std::string descriptor;
    const char* descriptor_str = klass->GetDescriptor(&descriptor);

    return std::string(descriptor_str);
  }

  template <typename K, typename V>
  static std::vector<std::pair<V, K>> SortByValueDesc(const std::map<K, V> map) {
    // Store value->key so that we can use the default sort from pair which
    // sorts by value first and then key
    std::vector<std::pair<V, K>> value_key_vector;

    for (const auto& kv_pair : map) {
      value_key_vector.push_back(std::make_pair(kv_pair.second, kv_pair.first));
    }

    // Sort in reverse (descending order)
    std::sort(value_key_vector.rbegin(), value_key_vector.rend());
    return value_key_vector;
  }

  static bool GetPageFrameNumber(File* page_map_file,
                                size_t virtual_page_index,
                                uint64_t* page_frame_number,
                                std::string* error_msg) {
    CHECK(page_map_file != nullptr);
    CHECK(page_frame_number != nullptr);
    CHECK(error_msg != nullptr);

    constexpr size_t kPageMapEntrySize = sizeof(uint64_t);
    constexpr uint64_t kPageFrameNumberMask = (1ULL << 55) - 1;  // bits 0-54 [in /proc/$pid/pagemap]
    constexpr uint64_t kPageSoftDirtyMask = (1ULL << 55);  // bit 55 [in /proc/$pid/pagemap]

    uint64_t page_map_entry = 0;

    // Read 64-bit entry from /proc/$pid/pagemap to get the physical page frame number
    if (!page_map_file->PreadFully(&page_map_entry, kPageMapEntrySize,
                                  virtual_page_index * kPageMapEntrySize)) {
      *error_msg = StringPrintf("Failed to read the virtual page index entry from %s",
                                page_map_file->GetPath().c_str());
      return false;
    }

    // TODO: seems useless, remove this.
    bool soft_dirty = (page_map_entry & kPageSoftDirtyMask) != 0;
    if ((false)) {
      LOG(VERBOSE) << soft_dirty;  // Suppress unused warning
      UNREACHABLE();
    }

    *page_frame_number = page_map_entry & kPageFrameNumberMask;

    return true;
  }

  static int IsPageDirty(File* page_map_file,
                         File* clean_page_map_file,
                         File* kpage_flags_file,
                         File* kpage_count_file,
                         size_t virtual_page_idx,
                         size_t clean_virtual_page_idx,
                         // Out parameters:
                         uint64_t* page_count, std::string* error_msg) {
    CHECK(page_map_file != nullptr);
    CHECK(clean_page_map_file != nullptr);
    CHECK_NE(page_map_file, clean_page_map_file);
    CHECK(kpage_flags_file != nullptr);
    CHECK(kpage_count_file != nullptr);
    CHECK(page_count != nullptr);
    CHECK(error_msg != nullptr);

    // Constants are from https://www.kernel.org/doc/Documentation/vm/pagemap.txt

    constexpr size_t kPageFlagsEntrySize = sizeof(uint64_t);
    constexpr size_t kPageCountEntrySize = sizeof(uint64_t);
    constexpr uint64_t kPageFlagsDirtyMask = (1ULL << 4);  // in /proc/kpageflags
    constexpr uint64_t kPageFlagsNoPageMask = (1ULL << 20);  // in /proc/kpageflags
    constexpr uint64_t kPageFlagsMmapMask = (1ULL << 11);  // in /proc/kpageflags

    uint64_t page_frame_number = 0;
    if (!GetPageFrameNumber(page_map_file, virtual_page_idx, &page_frame_number, error_msg)) {
      return -1;
    }

    uint64_t page_frame_number_clean = 0;
    if (!GetPageFrameNumber(clean_page_map_file, clean_virtual_page_idx, &page_frame_number_clean,
                            error_msg)) {
      return -1;
    }

    // Read 64-bit entry from /proc/kpageflags to get the dirty bit for a page
    uint64_t kpage_flags_entry = 0;
    if (!kpage_flags_file->PreadFully(&kpage_flags_entry,
                                     kPageFlagsEntrySize,
                                     page_frame_number * kPageFlagsEntrySize)) {
      *error_msg = StringPrintf("Failed to read the page flags from %s",
                                kpage_flags_file->GetPath().c_str());
      return -1;
    }

    // Read 64-bit entyry from /proc/kpagecount to get mapping counts for a page
    if (!kpage_count_file->PreadFully(page_count /*out*/,
                                     kPageCountEntrySize,
                                     page_frame_number * kPageCountEntrySize)) {
      *error_msg = StringPrintf("Failed to read the page count from %s",
                                kpage_count_file->GetPath().c_str());
      return -1;
    }

    // There must be a page frame at the requested address.
    CHECK_EQ(kpage_flags_entry & kPageFlagsNoPageMask, 0u);
    // The page frame must be memory mapped
    CHECK_NE(kpage_flags_entry & kPageFlagsMmapMask, 0u);

    // Page is dirty, i.e. has diverged from file, if the 4th bit is set to 1
    bool flags_dirty = (kpage_flags_entry & kPageFlagsDirtyMask) != 0;

    // page_frame_number_clean must come from the *same* process
    // but a *different* mmap than page_frame_number
    if (flags_dirty) {
      CHECK_NE(page_frame_number, page_frame_number_clean);
    }

    return page_frame_number != page_frame_number_clean;
  }

 private:
  // Return the image location, stripped of any directories, e.g. "boot.art" or "core.art"
  std::string GetImageLocationBaseName() const {
    return BaseName(std::string(image_location_));
  }

  std::ostream* os_;
  const ImageHeader& image_header_;
  const std::string image_location_;
  pid_t image_diff_pid_;  // Dump image diff against boot.art if pid is non-negative

  DISALLOW_COPY_AND_ASSIGN(ImgDiagDumper);
};

static int DumpImage(Runtime* runtime, std::ostream* os, pid_t image_diff_pid) {
  ScopedObjectAccess soa(Thread::Current());
  gc::Heap* heap = runtime->GetHeap();
  std::vector<gc::space::ImageSpace*> image_spaces = heap->GetBootImageSpaces();
  CHECK(!image_spaces.empty());
  for (gc::space::ImageSpace* image_space : image_spaces) {
    const ImageHeader& image_header = image_space->GetImageHeader();
    if (!image_header.IsValid()) {
      fprintf(stderr, "Invalid image header %s\n", image_space->GetImageLocation().c_str());
      return EXIT_FAILURE;
    }

    ImgDiagDumper img_diag_dumper(
        os, image_header, image_space->GetImageLocation(), image_diff_pid);
    if (!img_diag_dumper.Dump()) {
      return EXIT_FAILURE;
    }
  }
  return EXIT_SUCCESS;
}

struct ImgDiagArgs : public CmdlineArgs {
 protected:
  using Base = CmdlineArgs;

  virtual ParseStatus ParseCustom(const StringPiece& option,
                                  std::string* error_msg) OVERRIDE {
    {
      ParseStatus base_parse = Base::ParseCustom(option, error_msg);
      if (base_parse != kParseUnknownArgument) {
        return base_parse;
      }
    }

    if (option.starts_with("--image-diff-pid=")) {
      const char* image_diff_pid = option.substr(strlen("--image-diff-pid=")).data();

      if (!ParseInt(image_diff_pid, &image_diff_pid_)) {
        *error_msg = "Image diff pid out of range";
        return kParseError;
      }
    } else {
      return kParseUnknownArgument;
    }

    return kParseOk;
  }

  virtual ParseStatus ParseChecks(std::string* error_msg) OVERRIDE {
    // Perform the parent checks.
    ParseStatus parent_checks = Base::ParseChecks(error_msg);
    if (parent_checks != kParseOk) {
      return parent_checks;
    }

    // Perform our own checks.

    if (kill(image_diff_pid_,
             /*sig*/0) != 0) {  // No signal is sent, perform error-checking only.
      // Check if the pid exists before proceeding.
      if (errno == ESRCH) {
        *error_msg = "Process specified does not exist";
      } else {
        *error_msg = StringPrintf("Failed to check process status: %s", strerror(errno));
      }
      return kParseError;
    } else if (instruction_set_ != kRuntimeISA) {
      // Don't allow different ISAs since the images are ISA-specific.
      // Right now the code assumes both the runtime ISA and the remote ISA are identical.
      *error_msg = "Must use the default runtime ISA; changing ISA is not supported.";
      return kParseError;
    }

    return kParseOk;
  }

  virtual std::string GetUsage() const {
    std::string usage;

    usage +=
        "Usage: imgdiag [options] ...\n"
        "    Example: imgdiag --image-diff-pid=$(pidof dex2oat)\n"
        "    Example: adb shell imgdiag --image-diff-pid=$(pid zygote)\n"
        "\n";

    usage += Base::GetUsage();

    usage +=  // Optional.
        "  --image-diff-pid=<pid>: provide the PID of a process whose boot.art you want to diff.\n"
        "      Example: --image-diff-pid=$(pid zygote)\n"
        "\n";

    return usage;
  }

 public:
  pid_t image_diff_pid_ = -1;
};

struct ImgDiagMain : public CmdlineMain<ImgDiagArgs> {
  virtual bool ExecuteWithRuntime(Runtime* runtime) {
    CHECK(args_ != nullptr);

    return DumpImage(runtime,
                     args_->os_,
                     args_->image_diff_pid_) == EXIT_SUCCESS;
  }
};

}  // namespace art

int main(int argc, char** argv) {
  art::ImgDiagMain main;
  return main.Main(argc, argv);
}
