// 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/symbols/process_symbols.h"

#include "garnet/bin/zxdb/symbols/input_location.h"
#include "garnet/bin/zxdb/symbols/line_details.h"
#include "garnet/bin/zxdb/symbols/loaded_module_symbols.h"
#include "garnet/bin/zxdb/symbols/module_symbols_impl.h"
#include "garnet/bin/zxdb/symbols/resolve_options.h"
#include "garnet/bin/zxdb/symbols/system_symbols.h"
#include "garnet/bin/zxdb/symbols/target_symbols.h"
#include "garnet/lib/debug_ipc/records.h"

namespace zxdb {

namespace {

// The vDSO doesn't have symbols and we don't want to give error messages for
// it. Ignore failures for modules that this returns true for.
bool ExpectSymbolsForName(const std::string& name) { return name != "<vDSO>"; }

}  // namespace

ProcessSymbols::ProcessSymbols(Notifications* notifications,
                               TargetSymbols* target_symbols)
    : notifications_(notifications),
      target_symbols_(target_symbols),
      weak_factory_(this) {}

ProcessSymbols::~ProcessSymbols() = default;

fxl::WeakPtr<const ProcessSymbols> ProcessSymbols::GetWeakPtr() const {
  return weak_factory_.GetWeakPtr();
}

void ProcessSymbols::SetModules(const std::vector<debug_ipc::Module>& modules) {
  // Map from load address to index into |modules| argument.
  std::map<uint64_t, size_t> new_module_address_to_index;

  // Find new modules. These are indices into |modules| of the added ones.
  std::vector<size_t> new_module_indices;
  for (size_t i = 0; i < modules.size(); i++) {
    new_module_address_to_index[modules[i].base] = i;

    auto found_addr = modules_.find(modules[i].base);
    // Even if address is a match, the library could have been swapped.
    if (found_addr == modules_.end() ||
        !RefersToSameModule(modules[i], found_addr->second))
      new_module_indices.push_back(i);
  }

  // Find deleted modules and remove them.
  std::vector<ModuleMap::iterator> deleted_modules;
  for (auto iter = modules_.begin(); iter != modules_.end(); ++iter) {
    auto found_index = new_module_address_to_index.find(iter->second.base);
    if (found_index == new_module_address_to_index.end() ||
        !RefersToSameModule(modules[found_index->second], iter->second))
      deleted_modules.push_back(iter);
  }

  // First update for deleted modules since the addresses may overlap the
  // added ones.
  for (auto& deleted : deleted_modules) {
    notifications_->WillUnloadModuleSymbols(deleted->second.symbols.get());
    modules_.erase(deleted);
  }
  deleted_modules.clear();

  // Process the added ones.
  std::vector<LoadedModuleSymbols*> added_modules;
  std::vector<Err> load_errors;
  for (const auto& added_index : new_module_indices) {
    Err sym_load_err;
    ModuleInfo* info = SaveModuleInfo(modules[added_index], &sym_load_err);
    if (sym_load_err.has_error())
      load_errors.push_back(std::move(sym_load_err));
    else if (info->symbols->module_ref())
      added_modules.push_back(info->symbols.get());
  }

  // Update the TargetSymbols.
  target_symbols_->RemoveAllModules();
  for (auto& [base, mod_info] : modules_) {
    if (mod_info.symbols->module_ref()) {
      target_symbols_->AddModule(fxl::RefPtr<SystemSymbols::ModuleRef>(
          mod_info.symbols->module_ref()));
    }
  }

  // Send notifications last so everything is in a consistent state.
  for (auto& added_module : added_modules)
    notifications_->DidLoadModuleSymbols(added_module);
  for (auto& err : load_errors)
    notifications_->OnSymbolLoadFailure(err);
}

void ProcessSymbols::InjectModuleForTesting(
    const std::string& name, const std::string& build_id,
    std::unique_ptr<LoadedModuleSymbols> mod_sym) {
  LoadedModuleSymbols* loaded_ptr = mod_sym.get();
  FXL_DCHECK(loaded_ptr);

  ModuleInfo info;
  info.name = name;
  info.build_id = build_id;
  info.base = loaded_ptr->load_address();
  info.symbols = std::move(mod_sym);
  modules_[loaded_ptr->load_address()] = std::move(info);

  // Issue notifications.
  target_symbols_->AddModule(
      fxl::RefPtr<SystemSymbols::ModuleRef>(loaded_ptr->module_ref()));
  notifications_->DidLoadModuleSymbols(loaded_ptr);
}

std::vector<ModuleSymbolStatus> ProcessSymbols::GetStatus() const {
  std::vector<ModuleSymbolStatus> result;
  for (const auto& [base, mod_info] : modules_) {
    if (mod_info.symbols->module_ref()) {
      result.push_back(mod_info.symbols->module_symbols()->GetStatus());
      // ModuleSymbols doesn't know the name or base address so fill in now.
      result.back().name = mod_info.name;
      result.back().base = mod_info.base;
      result.back().symbols = mod_info.symbols.get();
    } else {
      // No symbols, make an empty record.
      ModuleSymbolStatus status;
      status.name = mod_info.name;
      status.build_id = mod_info.build_id;
      status.base = mod_info.base;
      status.symbols_loaded = false;
      result.push_back(std::move(status));
    }
  }
  return result;
}

std::vector<const LoadedModuleSymbols*> ProcessSymbols::GetLoadedModuleSymbols()
    const {
  std::vector<const LoadedModuleSymbols*> result;
  result.reserve(modules_.size());
  for (const auto& [base, mod_info] : modules_) {
    if (mod_info.symbols->module_ref())
      result.push_back(mod_info.symbols.get());
  }
  return result;
}

std::vector<Location> ProcessSymbols::ResolveInputLocation(
    const InputLocation& input_location, const ResolveOptions& options) const {
  FXL_DCHECK(input_location.type != InputLocation::Type::kNone);

  // Address resolution.
  if (input_location.type == InputLocation::Type::kAddress) {
    if (options.symbolize) {
      // Symbolize one address.
      const ModuleInfo* info = InfoForAddress(input_location.address);
      if (!info || !info->symbols->module_ref()) {
        // Can't symbolize.
        return std::vector<Location>{
            Location(Location::State::kSymbolized, input_location.address)};
      }
      // Have the module the address.
      return info->symbols->ResolveInputLocation(input_location, options);
    }

    // No-op conversion of address -> address.
    return std::vector<Location>{
        Location(Location::State::kAddress, input_location.address)};
  }

  // Symbol and file/line resolution both requires iterating over all modules.
  std::vector<Location> result;
  for (const auto& [base, mod_info] : modules_) {
    if (mod_info.symbols->module_ref()) {
      const LoadedModuleSymbols* loaded = mod_info.symbols.get();
      for (Location& location :
           loaded->ResolveInputLocation(input_location, options))
        result.push_back(std::move(location));
    }
  }
  return result;
}

LineDetails ProcessSymbols::LineDetailsForAddress(uint64_t address) const {
  const ModuleInfo* info = InfoForAddress(address);
  if (!info || !info->symbols->module_ref())
    return LineDetails();
  return info->symbols->module_symbols()->LineDetailsForAddress(
      info->symbols->symbol_context(), address);
}

bool ProcessSymbols::HaveSymbolsLoadedForModuleAt(uint64_t address) const {
  const ModuleInfo* info = InfoForAddress(address);
  return info && info->symbols->module_ref();
}

ProcessSymbols::ModuleInfo* ProcessSymbols::SaveModuleInfo(
    const debug_ipc::Module& module, Err* symbol_load_err) {
  ModuleInfo info;
  info.name = module.name;
  info.build_id = module.build_id;
  info.base = module.base;

  fxl::RefPtr<SystemSymbols::ModuleRef> module_symbols;
  *symbol_load_err = target_symbols_->system_symbols()->GetModule(
      module.name, module.build_id, &module_symbols);
  if (symbol_load_err->has_error()) {
    // Error, but it may be expected.
    if (!ExpectSymbolsForName(module.name))
      *symbol_load_err = Err();
    info.symbols = std::make_unique<LoadedModuleSymbols>(
        nullptr, module.build_id, module.base);
  } else {
    // Success, make the LoadedModuleSymbols.
    info.symbols = std::make_unique<LoadedModuleSymbols>(
        std::move(module_symbols), module.build_id, module.base);
  }

  auto inserted_iter =
      modules_
          .emplace(std::piecewise_construct, std::forward_as_tuple(module.base),
                   std::forward_as_tuple(std::move(info)))
          .first;
  return &inserted_iter->second;
}

// static
bool ProcessSymbols::RefersToSameModule(const debug_ipc::Module& a,
                                        const ModuleInfo& b) {
  return a.base == b.base && a.build_id == b.build_id;
}

const ProcessSymbols::ModuleInfo* ProcessSymbols::InfoForAddress(
    uint64_t address) const {
  if (modules_.empty())
    return nullptr;
  auto found = modules_.lower_bound(address);
  if (found == modules_.end() || found->first > address) {
    if (found == modules_.begin())
      return nullptr;  // Address below first module.
    // Move to previous item to get the module starting before this address.
    --found;
  }
  return &found->second;
}

}  // namespace zxdb
