//===-- AddressResolverName.cpp ---------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/Core/AddressResolverName.h"

#include "lldb/Core/Address.h"
#include "lldb/Core/AddressRange.h"
#include "lldb/Core/Module.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Logging.h"
#include "lldb/Utility/Stream.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-forward.h"
#include "lldb/lldb-types.h"
#include "llvm/ADT/StringRef.h"

#include <memory>
#include <string>
#include <vector>

#include <stdint.h>

using namespace lldb;
using namespace lldb_private;

AddressResolverName::AddressResolverName(const char *func_name,
                                         AddressResolver::MatchType type)
    : AddressResolver(), m_func_name(func_name), m_class_name(nullptr),
      m_regex(), m_match_type(type) {
  if (m_match_type == AddressResolver::Regexp) {
    m_regex = RegularExpression(m_func_name.GetStringRef());
    if (!m_regex.IsValid()) {
      Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));

      if (log)
        log->Warning("function name regexp: \"%s\" did not compile.",
                     m_func_name.AsCString());
    }
  }
}

AddressResolverName::AddressResolverName(RegularExpression func_regex)
    : AddressResolver(), m_func_name(nullptr), m_class_name(nullptr),
      m_regex(std::move(func_regex)), m_match_type(AddressResolver::Regexp) {}

AddressResolverName::AddressResolverName(const char *class_name,
                                         const char *method,
                                         AddressResolver::MatchType type)
    : AddressResolver(), m_func_name(method), m_class_name(class_name),
      m_regex(), m_match_type(type) {}

AddressResolverName::~AddressResolverName() = default;

// FIXME: Right now we look at the module level, and call the module's
// "FindFunctions".
// Greg says he will add function tables, maybe at the CompileUnit level to
// accelerate function lookup.  At that point, we should switch the depth to
// CompileUnit, and look in these tables.

Searcher::CallbackReturn
AddressResolverName::SearchCallback(SearchFilter &filter,
                                    SymbolContext &context, Address *addr) {
  SymbolContextList func_list;
  SymbolContextList sym_list;

  bool skip_prologue = true;
  uint32_t i;
  SymbolContext sc;
  Address func_addr;

  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));

  if (m_class_name) {
    if (log)
      log->Warning("Class/method function specification not supported yet.\n");
    return Searcher::eCallbackReturnStop;
  }

  const bool include_symbols = false;
  const bool include_inlines = true;
  switch (m_match_type) {
  case AddressResolver::Exact:
    if (context.module_sp) {
      context.module_sp->FindSymbolsWithNameAndType(m_func_name,
                                                    eSymbolTypeCode, sym_list);
      context.module_sp->FindFunctions(m_func_name, nullptr,
                                       eFunctionNameTypeAuto, include_symbols,
                                       include_inlines, func_list);
    }
    break;

  case AddressResolver::Regexp:
    if (context.module_sp) {
      context.module_sp->FindSymbolsMatchingRegExAndType(
          m_regex, eSymbolTypeCode, sym_list);
      context.module_sp->FindFunctions(m_regex, include_symbols,
                                       include_inlines, func_list);
    }
    break;

  case AddressResolver::Glob:
    if (log)
      log->Warning("glob is not supported yet.");
    break;
  }

  // Remove any duplicates between the function list and the symbol list
  if (func_list.GetSize()) {
    for (i = 0; i < func_list.GetSize(); i++) {
      if (!func_list.GetContextAtIndex(i, sc))
        continue;

      if (sc.function == nullptr)
        continue;
      uint32_t j = 0;
      while (j < sym_list.GetSize()) {
        SymbolContext symbol_sc;
        if (sym_list.GetContextAtIndex(j, symbol_sc)) {
          if (symbol_sc.symbol && symbol_sc.symbol->ValueIsAddress()) {
            if (sc.function->GetAddressRange().GetBaseAddress() ==
                symbol_sc.symbol->GetAddressRef()) {
              sym_list.RemoveContextAtIndex(j);
              continue; // Don't increment j
            }
          }
        }

        j++;
      }
    }

    for (i = 0; i < func_list.GetSize(); i++) {
      if (func_list.GetContextAtIndex(i, sc)) {
        if (sc.function) {
          func_addr = sc.function->GetAddressRange().GetBaseAddress();
          addr_t byte_size = sc.function->GetAddressRange().GetByteSize();
          if (skip_prologue) {
            const uint32_t prologue_byte_size =
                sc.function->GetPrologueByteSize();
            if (prologue_byte_size) {
              func_addr.SetOffset(func_addr.GetOffset() + prologue_byte_size);
              byte_size -= prologue_byte_size;
            }
          }

          if (filter.AddressPasses(func_addr)) {
            AddressRange new_range(func_addr, byte_size);
            m_address_ranges.push_back(new_range);
          }
        }
      }
    }
  }

  for (i = 0; i < sym_list.GetSize(); i++) {
    if (sym_list.GetContextAtIndex(i, sc)) {
      if (sc.symbol && sc.symbol->ValueIsAddress()) {
        func_addr = sc.symbol->GetAddressRef();
        addr_t byte_size = sc.symbol->GetByteSize();

        if (skip_prologue) {
          const uint32_t prologue_byte_size = sc.symbol->GetPrologueByteSize();
          if (prologue_byte_size) {
            func_addr.SetOffset(func_addr.GetOffset() + prologue_byte_size);
            byte_size -= prologue_byte_size;
          }
        }

        if (filter.AddressPasses(func_addr)) {
          AddressRange new_range(func_addr, byte_size);
          m_address_ranges.push_back(new_range);
        }
      }
    }
  }
  return Searcher::eCallbackReturnContinue;
}

lldb::SearchDepth AddressResolverName::GetDepth() {
  return lldb::eSearchDepthModule;
}

void AddressResolverName::GetDescription(Stream *s) {
  s->PutCString("Address by function name: ");

  if (m_match_type == AddressResolver::Regexp)
    s->Printf("'%s' (regular expression)", m_regex.GetText().str().c_str());
  else
    s->Printf("'%s'", m_func_name.AsCString());
}
