// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "garnet/bin/zxdb/console/analyze_memory.h"

#include <inttypes.h>

#include <map>

#include "garnet/bin/zxdb/client/frame.h"
#include "garnet/bin/zxdb/client/memory_dump.h"
#include "garnet/bin/zxdb/client/process.h"
#include "garnet/bin/zxdb/client/register.h"
#include "garnet/bin/zxdb/client/thread.h"
#include "garnet/bin/zxdb/common/err.h"
#include "garnet/bin/zxdb/console/format_register.h"
#include "garnet/bin/zxdb/console/format_table.h"
#include "garnet/bin/zxdb/console/output_buffer.h"
#include "garnet/bin/zxdb/symbols/input_location.h"
#include "garnet/bin/zxdb/symbols/process_symbols.h"
#include "garnet/bin/zxdb/symbols/symbol_utils.h"
#include "garnet/lib/debug_ipc/helper/message_loop.h"
#include "garnet/lib/debug_ipc/records.h"
#include "lib/fxl/logging.h"
#include "lib/fxl/strings/string_printf.h"

namespace zxdb {

namespace {

// Rounds the beginning and size to sizeof(uint64_t) which we assume all
// pointers are on the debugged platform. This may need to be configurable in
// the future.
constexpr uint64_t kAlign = sizeof(uint64_t);

// Aspace entries this size or larger will be ignored for annotation purposes.
// These large regions generally represent the process's available address
// space rather than actually used memory.
constexpr uint64_t kMaxAspaceRegion = 128000000000;  // 128GB

}  // namespace

namespace internal {

MemoryAnalysis::MemoryAnalysis(const AnalyzeMemoryOptions& opts, Callback cb)
    : callback_(std::move(cb)) {
  process_ = opts.process->GetWeakPtr();

  // This doesn't store the Thread because it may go out-of-scope during the
  // asynchronous requests. We'd need a weak pointer but its better avoided.
  begin_address_ = opts.begin_address / kAlign * kAlign;

  uint64_t end = opts.begin_address + opts.bytes_to_read;
  end += kAlign - 1;
  end = end / kAlign * kAlign;
  bytes_to_read_ = static_cast<uint32_t>(end - begin_address_);
}

void MemoryAnalysis::Schedule(const AnalyzeMemoryOptions& opts) {
  // Copies are passed to the callbacks to keep this object in scope until
  // all are complete.
  fxl::RefPtr<MemoryAnalysis> this_ref(this);

  if (opts.thread) {
    // Request registers. Only need the general registers.
    if (!have_registers_) {
      opts.thread->ReadRegisters(
          {debug_ipc::RegisterCategory::Type::kGeneral},
          [this_ref](const Err& err, const RegisterSet& registers) {
            this_ref->OnRegisters(err, registers);
          });
    }

    // Request stack dump.
    if (!have_frames_) {
      if (opts.thread->GetStack().has_all_frames()) {
        OnFrames(opts.thread->GetWeakPtr());
      } else {
        opts.thread->GetStack().SyncFrames([
          this_ref, weak_thread = opts.thread->GetWeakPtr()
        ](const Err&) {
          // Can ignore the error, the frames will be re-queried from the
          // thread and we'll check the weak pointer in case its destroyed.
          this_ref->OnFrames(weak_thread);
        });
      }
    }
  } else {
    // Mark these as complete so we can continue when everything else is done.
    have_registers_ = true;
    have_frames_ = true;
  }

  // Request memory dump.
  if (!have_memory_) {
    opts.process->ReadMemory(begin_address_, bytes_to_read_,
                             [this_ref](const Err& err, MemoryDump dump) {
                               this_ref->OnMemory(err, std::move(dump));
                             });
  }

  // Request address space dump.
  if (!have_aspace_) {
    opts.process->GetAspace(
        0, [this_ref](const Err& err,
                      std::vector<debug_ipc::AddressRegion> aspace) {
          this_ref->OnAspace(err, std::move(aspace));
        });
  }

  // Test code could have set everything, in which case trigger a run.
  if (HasEverything()) {
    debug_ipc::MessageLoop::Current()->PostTask(
        FROM_HERE, [this_ref]() { this_ref->DoAnalysis(); });
  }
}

void MemoryAnalysis::SetAspace(std::vector<debug_ipc::AddressRegion> aspace) {
  FXL_DCHECK(!have_aspace_);
  have_aspace_ = true;
  aspace_ = std::move(aspace);
}

void MemoryAnalysis::SetStack(const Stack& stack) {
  FXL_DCHECK(!have_frames_);
  have_frames_ = true;

  // This loop avoids adding frame 0's information because that should be
  // covered by the CPU registers.
  for (int i = 1; i < static_cast<int>(stack.size()); i++) {
    AddAnnotation(stack[i]->GetAddress(), fxl::StringPrintf("frame %d IP", i));
    // TODO(brettw) make this work when the BP is asynchronous.
    if (auto bp = stack[i]->GetBasePointer())
      AddAnnotation(*bp, fxl::StringPrintf("frame %d BP", i));
    AddAnnotation(stack[i]->GetStackPointer(),
                  fxl::StringPrintf("frame %d SP", i));
  }
}

void MemoryAnalysis::SetMemory(MemoryDump dump) {
  FXL_DCHECK(!have_memory_);
  have_memory_ = true;
  memory_ = std::move(dump);
}

void MemoryAnalysis::SetRegisters(const RegisterSet& registers) {
  FXL_DCHECK(!have_registers_);
  have_registers_ = true;
  for (const auto& kv : registers.category_map()) {
    // We look for the general section registers
    if (kv.first == debug_ipc::RegisterCategory::Type::kGeneral) {
      for (const auto& reg : kv.second)
        AddAnnotation(reg.GetValue(), RegisterIDToString(reg.id()));
    }
  }
}

void MemoryAnalysis::DoAnalysis() {
  std::vector<std::vector<OutputBuffer>> rows;
  rows.reserve(bytes_to_read_ / kAlign);
  for (uint64_t offset = 0; offset < bytes_to_read_; offset += kAlign) {
    rows.emplace_back();
    auto& row = rows.back();

    uint64_t address = begin_address_ + offset;

    // Address.
    row.emplace_back(Syntax::kComment,
                     fxl::StringPrintf("0x%" PRIx64, address));

    // Data
    uint64_t data_value = 0;
    bool has_data = GetData(address, &data_value);
    if (has_data) {
      row.emplace_back(fxl::StringPrintf("0x%016" PRIx64, data_value));
    } else {
      row.emplace_back("<invalid memory>");
    }

    std::string annotation = GetAnnotationsBetween(address, address + kAlign);
    std::string pointed_to;
    if (has_data)
      pointed_to = GetPointedToAnnotation(data_value);

    OutputBuffer comments;
    if (!annotation.empty()) {
      // Mark things pointing into the stack as special since they're important
      // and can get drowned out by the "pointed to" annotations.
      comments.Append(Syntax::kSpecial, std::move(annotation));
      if (!pointed_to.empty())
        comments.Append(". ");  // Separator between sections.
    }
    if (!pointed_to.empty())
      comments.Append(std::move(pointed_to));
    row.push_back(comments);
  }

  OutputBuffer out;
  FormatTable({ColSpec(Align::kRight, 0, "Address"),
               ColSpec(Align::kRight, 0, "Data"), ColSpec()},
              rows, &out);
  callback_(Err(), std::move(out), begin_address_ + bytes_to_read_);
}

void MemoryAnalysis::OnAspace(const Err& err,
                              std::vector<debug_ipc::AddressRegion> aspace) {
  if (aborted_)
    return;

  // This function can continue without address space annotations so ignore
  // errors.
  SetAspace(std::move(aspace));

  if (HasEverything())
    DoAnalysis();
}

void MemoryAnalysis::OnRegisters(const Err& err, const RegisterSet& registers) {
  if (aborted_)
    return;

  // This function can continue without registers (say, if the thread has been
  // resumed by the time the request got executed). So just ignore failures.
  SetRegisters(registers);

  if (HasEverything())
    DoAnalysis();
}

void MemoryAnalysis::OnMemory(const Err& err, MemoryDump dump) {
  if (aborted_)
    return;
  if (err.has_error()) {
    IssueError(err);
    return;
  }

  SetMemory(std::move(dump));

  if (HasEverything())
    DoAnalysis();
}

void MemoryAnalysis::OnFrames(fxl::WeakPtr<Thread> thread) {
  if (aborted_)
    return;

  // This function can continue even if the thread is gone, it just won't get
  // the frame annotations.
  if (thread)
    SetStack(thread->GetStack());
  else
    have_frames_ = true;  // Mark fetching is complete.

  if (HasEverything())
    DoAnalysis();
}

bool MemoryAnalysis::HasEverything() const {
  return have_registers_ && have_memory_ && have_frames_ && have_aspace_;
}

void MemoryAnalysis::IssueError(const Err& err) {
  aborted_ = true;
  callback_(err, OutputBuffer(), 0);

  // Reset so we notice if there's an accidental double-call.
  callback_ = Callback();
}

void MemoryAnalysis::AddAnnotation(uint64_t address, const std::string& str) {
  auto found = annotations_.find(address);
  if (found == annotations_.end()) {
    annotations_[address] = str;
  } else {
    found->second.append(", ");
    found->second.append(str);
  }
}

bool MemoryAnalysis::GetData(uint64_t address, uint64_t* out_value) const {
  // Need to handle invalid memory. The easiest thing is to read a byte at a
  // time. This doesn't handle invalid regions spanning a pointer; that
  // shouldn't happen because valid memory regions should always be aligned
  // more coarsly than the size of a pointer.
  uint64_t data = 0;
  for (uint64_t i = 0; i < kAlign; i++) {
    uint8_t byte;
    if (!memory_.GetByte(address + i, &byte))
      return false;
    data |= static_cast<uint64_t>(byte) << (i * 8);
  }

  *out_value = data;
  return true;
}

std::string MemoryAnalysis::GetAnnotationsBetween(uint64_t address_begin,
                                                  uint64_t address_end) const {
  auto lower = annotations_.lower_bound(address_begin);
  auto upper = annotations_.upper_bound(address_end - 1);
  if (lower == upper)
    return std::string();  // No annotations in this range.

  std::string result = ("◁ ");
  for (auto cur = lower; cur != upper; ++cur) {
    if (cur != lower) {
      // Not the first annotation, needs a separator.
      result += "; ";
    }
    if (cur->first != address_begin) {
      // Not at the address but inside of the range. Annotate that carefully.
      result += fxl::StringPrintf("@ 0x%" PRIx64 ": ", cur->first);
    }
    result += cur->second;
  }
  return result;
}

std::string MemoryAnalysis::GetPointedToAnnotation(uint64_t data) const {
  if (!process_)
    return std::string();
  auto locations =
      process_->GetSymbols()->ResolveInputLocation(InputLocation(data));
  FXL_DCHECK(locations.size() == 1);

  if (!locations[0].symbol()) {
    // Check if this points into any relevant aspace entries. Want the deepest
    // one smaller than the max size threshold.
    int max_depth = -1;
    size_t found_entry = aspace_.size();  // Indicates not found.
    for (size_t i = 0; i < aspace_.size(); i++) {
      const auto& region = aspace_[i];
      if (region.size < kMaxAspaceRegion && data >= region.base &&
          data < region.base + region.size &&
          max_depth < static_cast<int>(region.depth)) {
        max_depth = static_cast<int>(region.depth);
        found_entry = i;
      }
    }

    if (found_entry == aspace_.size())
      return std::string();  // Not found.
    return fxl::StringPrintf("▷ inside map \"%s\"",
                             aspace_[found_entry].name.c_str());
  }
  // TODO(brettw) this should indicate the byte offset from the beginning of
  // the function, or maybe the file/line number.
  return "▷ inside " + locations[0].symbol().Get()->GetFullName();
}

}  // namespace internal

void AnalyzeMemory(const AnalyzeMemoryOptions& opts,
                   std::function<void(const Err& err, OutputBuffer analysis,
                                      uint64_t next_addr)>
                       cb) {
  auto analysis =
      fxl::MakeRefCounted<zxdb::internal::MemoryAnalysis>(opts, std::move(cb));
  analysis->Schedule(opts);
}

}  // namespace zxdb
