//===-- PDBLocationToDWARFExpression.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 "PDBLocationToDWARFExpression.h"

#include "lldb/Core/Section.h"
#include "lldb/Core/StreamBuffer.h"
#include "lldb/Core/dwarf.h"
#include "lldb/Expression/DWARFExpression.h"
#include "lldb/Symbol/Variable.h"
#include "lldb/Utility/DataBufferHeap.h"

#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/PDB/IPDBSession.h"
#include "llvm/DebugInfo/PDB/PDBSymbolData.h"

#include "Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h"
#include "Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.h"

using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::npdb;
using namespace llvm::pdb;

static std::unique_ptr<IPDBFrameData>
GetCorrespondingFrameData(const IPDBSession &session,
                          const Variable::RangeList &ranges) {
  auto enumFrameData = session.getFrameData();
  if (!enumFrameData)
    return nullptr;

  std::unique_ptr<IPDBFrameData> found;
  while (auto fd = enumFrameData->getNext()) {
    Range<lldb::addr_t, lldb::addr_t> fdRange(fd->getVirtualAddress(),
                                              fd->getLengthBlock());

    for (size_t i = 0; i < ranges.GetSize(); i++) {
      auto range = ranges.GetEntryAtIndex(i);
      if (!range)
        continue;

      if (!range->DoesIntersect(fdRange))
        continue;

      found = std::move(fd);

      break;
    }
  }

  return found;
}

static bool EmitVFrameEvaluationDWARFExpression(
    llvm::StringRef program, llvm::Triple::ArchType arch_type, Stream &stream) {
  // VFrame value always stored in $TO pseudo-register
  return TranslateFPOProgramToDWARFExpression(program, "$T0", arch_type,
                                              stream);
}

DWARFExpression ConvertPDBLocationToDWARFExpression(
    ModuleSP module, const PDBSymbolData &symbol,
    const Variable::RangeList &ranges, bool &is_constant) {
  is_constant = true;

  if (!module)
    return DWARFExpression();

  const ArchSpec &architecture = module->GetArchitecture();
  llvm::Triple::ArchType arch_type = architecture.GetMachine();
  ByteOrder byte_order = architecture.GetByteOrder();
  uint32_t address_size = architecture.GetAddressByteSize();
  uint32_t byte_size = architecture.GetDataByteSize();
  if (byte_order == eByteOrderInvalid || address_size == 0)
    return DWARFExpression();

  RegisterKind register_kind = eRegisterKindDWARF;
  StreamBuffer<32> stream(Stream::eBinary, address_size, byte_order);
  switch (symbol.getLocationType()) {
  case PDB_LocType::Static:
  case PDB_LocType::TLS: {
    stream.PutHex8(DW_OP_addr);

    SectionList *section_list = module->GetSectionList();
    if (!section_list)
      return DWARFExpression();

    uint32_t section_id = symbol.getAddressSection();

    auto section = section_list->FindSectionByID(section_id);
    if (!section)
      return DWARFExpression();

    uint32_t offset = symbol.getAddressOffset();
    stream.PutMaxHex64(section->GetFileAddress() + offset, address_size,
                       byte_order);

    is_constant = false;

    break;
  }
  case PDB_LocType::RegRel: {
    uint32_t reg_num;
    auto reg_id = symbol.getRegisterId();
    if (reg_id == llvm::codeview::RegisterId::VFRAME) {
      if (auto fd = GetCorrespondingFrameData(symbol.getSession(), ranges)) {
        if (EmitVFrameEvaluationDWARFExpression(fd->getProgram(), arch_type,
                                                stream)) {
          int32_t offset = symbol.getOffset();
          stream.PutHex8(DW_OP_consts);
          stream.PutSLEB128(offset);
          stream.PutHex8(DW_OP_plus);

          register_kind = eRegisterKindLLDB;

          is_constant = false;
          break;
        }
      }

      register_kind = eRegisterKindGeneric;
      reg_num = LLDB_REGNUM_GENERIC_FP;
    } else {
      register_kind = eRegisterKindLLDB;
      reg_num = GetLLDBRegisterNumber(arch_type, reg_id);
      if (reg_num == LLDB_INVALID_REGNUM)
        return DWARFExpression();
    }

    if (reg_num > 31) {
      stream.PutHex8(DW_OP_bregx);
      stream.PutULEB128(reg_num);
    } else
      stream.PutHex8(DW_OP_breg0 + reg_num);

    int32_t offset = symbol.getOffset();
    stream.PutSLEB128(offset);

    is_constant = false;

    break;
  }
  case PDB_LocType::Enregistered: {
    register_kind = eRegisterKindLLDB;
    uint32_t reg_num = GetLLDBRegisterNumber(arch_type, symbol.getRegisterId());
    if (reg_num == LLDB_INVALID_REGNUM)
      return DWARFExpression();

    if (reg_num > 31) {
      stream.PutHex8(DW_OP_regx);
      stream.PutULEB128(reg_num);
    } else
      stream.PutHex8(DW_OP_reg0 + reg_num);

    is_constant = false;

    break;
  }
  case PDB_LocType::Constant: {
    Variant value = symbol.getValue();
    stream.PutRawBytes(&value.Value, sizeof(value.Value),
                       endian::InlHostByteOrder());
    break;
  }
  default:
    return DWARFExpression();
  }

  DataBufferSP buffer =
      std::make_shared<DataBufferHeap>(stream.GetData(), stream.GetSize());
  DataExtractor extractor(buffer, byte_order, address_size, byte_size);
  DWARFExpression result(module, extractor, nullptr);
  result.SetRegisterKind(register_kind);

  return result;
}
