//===-- DWARFExpressionList.cpp -------------------------------------------===//
//
// 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/Expression/DWARFExpressionList.h"
#include "lldb/Core/AddressRange.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StackFrame.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"

using namespace lldb;
using namespace lldb_private;

bool DWARFExpressionList::IsAlwaysValidSingleExpr() const {
  return GetAlwaysValidExpr() != nullptr;
}

const DWARFExpression *DWARFExpressionList::GetAlwaysValidExpr() const {
  if (m_exprs.GetSize() != 1)
    return nullptr;
  const auto *expr = m_exprs.GetEntryAtIndex(0);
  if (expr->base == 0 && expr->size == LLDB_INVALID_ADDRESS)
    return &expr->data;
  return nullptr;
}

bool DWARFExpressionList::AddExpression(addr_t base, addr_t end,
                                        DWARFExpression expr) {
  if (IsAlwaysValidSingleExpr() || base >= end)
    return false;
  m_exprs.Append({base, end - base, expr});
  return true;
}

bool DWARFExpressionList::GetExpressionData(DataExtractor &data,
                                            lldb::addr_t func_load_addr,
                                            lldb::addr_t file_addr) const {
  if (const DWARFExpression *expr =
          GetExpressionAtAddress(func_load_addr, file_addr))
    return expr->GetExpressionData(data);
  return false;
}

bool DWARFExpressionList::ContainsAddress(lldb::addr_t func_load_addr,
                                          lldb::addr_t addr) const {
  if (IsAlwaysValidSingleExpr())
    return true;
  return GetExpressionAtAddress(func_load_addr, addr) != nullptr;
}

std::optional<DWARFExpressionList::DWARFExpressionEntry>
DWARFExpressionList::GetExpressionEntryAtAddress(lldb::addr_t func_load_addr,
                                                 lldb::addr_t load_addr) const {
  if (const DWARFExpression *always = GetAlwaysValidExpr()) {
    return DWARFExpressionEntry{std::nullopt, always};
  }

  if (func_load_addr == LLDB_INVALID_ADDRESS)
    func_load_addr = m_func_file_addr;

  // Guard against underflow when translating a load address back into file
  // space.
  if (load_addr < func_load_addr)
    return std::nullopt;

  // Guard against overflow.
  lldb::addr_t delta = load_addr - func_load_addr;
  if (delta > std::numeric_limits<lldb::addr_t>::max() - m_func_file_addr)
    return std::nullopt;

  lldb::addr_t file_pc = (load_addr - func_load_addr) + m_func_file_addr;

  if (const auto *entry = m_exprs.FindEntryThatContains(file_pc)) {
    AddressRange range_in_file(entry->GetRangeBase(),
                               entry->GetRangeEnd() - entry->GetRangeBase());
    return DWARFExpressionEntry{range_in_file, &entry->data};
  }

  // No entry covers this PC:
  return std::nullopt;
}

const DWARFExpression *
DWARFExpressionList::GetExpressionAtAddress(lldb::addr_t func_load_addr,
                                            lldb::addr_t load_addr) const {
  if (const DWARFExpression *expr = GetAlwaysValidExpr())
    return expr;
  if (func_load_addr == LLDB_INVALID_ADDRESS)
    func_load_addr = m_func_file_addr;
  addr_t addr = load_addr - func_load_addr + m_func_file_addr;
  uint32_t index = m_exprs.FindEntryIndexThatContains(addr);
  if (index == UINT32_MAX)
    return nullptr;
  return &m_exprs.GetEntryAtIndex(index)->data;
}

DWARFExpression *
DWARFExpressionList::GetMutableExpressionAtAddress(lldb::addr_t func_load_addr,
                                                   lldb::addr_t load_addr) {
  if (IsAlwaysValidSingleExpr())
    return &m_exprs.GetMutableEntryAtIndex(0)->data;
  if (func_load_addr == LLDB_INVALID_ADDRESS)
    func_load_addr = m_func_file_addr;
  addr_t addr = load_addr - func_load_addr + m_func_file_addr;
  uint32_t index = m_exprs.FindEntryIndexThatContains(addr);
  if (index == UINT32_MAX)
    return nullptr;
  return &m_exprs.GetMutableEntryAtIndex(index)->data;
}

bool DWARFExpressionList::ContainsThreadLocalStorage() const {
  // We are assuming for now that any thread local variable will not have a
  // location list. This has been true for all thread local variables we have
  // seen so far produced by any compiler.
  if (!IsAlwaysValidSingleExpr())
    return false;

  const DWARFExpression &expr = m_exprs.GetEntryRef(0).data;
  return expr.ContainsThreadLocalStorage(m_dwarf_cu);
}

bool DWARFExpressionList::LinkThreadLocalStorage(
    lldb::ModuleSP new_module_sp,
    std::function<lldb::addr_t(lldb::addr_t file_addr)> const
        &link_address_callback) {
  // We are assuming for now that any thread local variable will not have a
  // location list. This has been true for all thread local variables we have
  // seen so far produced by any compiler.
  if (!IsAlwaysValidSingleExpr())
    return false;

  DWARFExpression &expr = m_exprs.GetEntryRef(0).data;
  // If we linked the TLS address correctly, update the module so that when the
  // expression is evaluated it can resolve the file address to a load address
  // and read the TLS data
  if (expr.LinkThreadLocalStorage(m_dwarf_cu, link_address_callback))
    m_module_wp = new_module_sp;
  return true;
}

bool DWARFExpressionList::MatchesOperand(
    StackFrame &frame, const Instruction::Operand &operand) const {
  RegisterContextSP reg_ctx_sp = frame.GetRegisterContext();
  if (!reg_ctx_sp) {
    return false;
  }
  const DWARFExpression *expr = nullptr;
  if (IsAlwaysValidSingleExpr())
    expr = &m_exprs.GetEntryAtIndex(0)->data;
  else {
    SymbolContext sc = frame.GetSymbolContext(eSymbolContextFunction);
    if (!sc.function)
      return false;

    addr_t load_function_start = sc.function->GetAddress().GetFileAddress();
    if (load_function_start == LLDB_INVALID_ADDRESS)
      return false;

    addr_t pc = frame.GetFrameCodeAddressForSymbolication().GetFileAddress();
    expr = GetExpressionAtAddress(LLDB_INVALID_ADDRESS, pc);
  }
  if (!expr)
    return false;
  return expr->MatchesOperand(frame, operand);
}

bool DWARFExpressionList::DumpLocations(Stream *s, lldb::DescriptionLevel level,
                                        lldb::addr_t func_load_addr,
                                        lldb::addr_t file_addr,
                                        ABI *abi) const {
  llvm::raw_ostream &os = s->AsRawOstream();
  llvm::ListSeparator separator;
  if (const DWARFExpression *expr = GetAlwaysValidExpr()) {
    expr->DumpLocation(s, level, abi);
    return true;
  }
  for (const Entry &entry : *this) {
    addr_t load_base = entry.GetRangeBase() + func_load_addr - m_func_file_addr;
    addr_t load_end = entry.GetRangeEnd() + func_load_addr - m_func_file_addr;
    if (file_addr != LLDB_INVALID_ADDRESS &&
        (file_addr < load_base || file_addr >= load_end))
      continue;
    const auto &expr = entry.data;
    DataExtractor data;
    expr.GetExpressionData(data);
    uint32_t addr_size = data.GetAddressByteSize();

    os << separator;
    os << "[";
    os << llvm::format_hex(load_base, 2 + 2 * addr_size);
    os << ", ";
    os << llvm::format_hex(load_end, 2 + 2 * addr_size);
    os << ") -> ";
    expr.DumpLocation(s, level, abi);
    if (file_addr != LLDB_INVALID_ADDRESS)
      break;
  }
  return true;
}

void DWARFExpressionList::GetDescription(Stream *s,
                                         lldb::DescriptionLevel level,
                                         ABI *abi) const {
  llvm::raw_ostream &os = s->AsRawOstream();
  if (IsAlwaysValidSingleExpr()) {
    m_exprs.Back()->data.DumpLocation(s, level, abi);
    return;
  }
  os << llvm::format("0x%8.8" PRIx64 ": ", 0);
  for (const Entry &entry : *this) {
    const auto &expr = entry.data;
    DataExtractor data;
    expr.GetExpressionData(data);
    uint32_t addr_size = data.GetAddressByteSize();
    os << "\n";
    os.indent(s->GetIndentLevel() + 2);
    os << "[";
    llvm::DWARFFormValue::dumpAddress(os, addr_size, entry.GetRangeBase());
    os << ", ";
    llvm::DWARFFormValue::dumpAddress(os, addr_size, entry.GetRangeEnd());
    os << "): ";
    expr.DumpLocation(s, level, abi);
  }
}

llvm::Expected<const DWARFExpression *>
DWARFExpressionList::GetExpressionAtPC(ExecutionContext *exe_ctx,
                                       RegisterContext *reg_ctx,
                                       lldb::addr_t func_load_addr) const {
  if (const DWARFExpression *always = GetAlwaysValidExpr())
    return always;

  Address pc;
  StackFrame *frame = nullptr;
  if (!reg_ctx || !reg_ctx->GetPCForSymbolication(pc)) {
    if (exe_ctx)
      frame = exe_ctx->GetFramePtr();
    if (!frame)
      return llvm::createStringError("no frame");
    RegisterContextSP reg_ctx_sp = frame->GetRegisterContext();
    if (!reg_ctx_sp)
      return llvm::createStringError("no register context");
    reg_ctx_sp->GetPCForSymbolication(pc);
  }

  if (!pc.IsValid())
    return llvm::createStringError("invalid PC in frame");

  addr_t pc_load_addr = pc.GetLoadAddress(exe_ctx->GetTargetPtr());
  const DWARFExpression *entry =
      GetExpressionAtAddress(func_load_addr, pc_load_addr);
  if (!entry)
    return llvm::createStringError("variable not available");
  return entry;
}

llvm::Expected<Value> DWARFExpressionList::Evaluate(
    ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
    lldb::addr_t func_load_addr, const Value *initial_value_ptr,
    const Value *object_address_ptr) const {
  llvm::Expected<const DWARFExpression *> expr =
      GetExpressionAtPC(exe_ctx, reg_ctx, func_load_addr);
  if (!expr)
    return expr.takeError();

  ModuleSP module_sp = m_module_wp.lock();
  DataExtractor data;
  (*expr)->GetExpressionData(data);
  RegisterKind reg_kind = (*expr)->GetRegisterKind();
  return DWARFExpression::Evaluate(exe_ctx, reg_ctx, module_sp, data,
                                   m_dwarf_cu, reg_kind, initial_value_ptr,
                                   object_address_ptr);
}

bool DWARFExpressionList::IsImplicit(ExecutionContext *exe_ctx,
                                     RegisterContext *reg_ctx,
                                     lldb::addr_t func_load_addr) const {
  llvm::Expected<const DWARFExpression *> expr =
      GetExpressionAtPC(exe_ctx, reg_ctx, func_load_addr);
  if (!expr) {
    // No location in scope, so nothing to write back to.
    llvm::consumeError(expr.takeError());
    return true;
  }
  return (*expr)->IsImplicit(m_dwarf_cu);
}
