//===- NativeFunctionSymbol.cpp - info about function symbols----*- 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 "llvm/DebugInfo/PDB/Native/NativeFunctionSymbol.h"

#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/PDB/Native/NativeEnumSymbols.h"
#include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"

using namespace llvm;
using namespace llvm::codeview;
using namespace llvm::pdb;

NativeFunctionSymbol::NativeFunctionSymbol(NativeSession &Session,
                                           SymIndexId Id,
                                           const codeview::ProcSym &Sym,
                                           uint32_t Offset)
    : NativeRawSymbol(Session, PDB_SymType::Function, Id), Sym(Sym),
      RecordOffset(Offset) {}

NativeFunctionSymbol::~NativeFunctionSymbol() {}

void NativeFunctionSymbol::dump(raw_ostream &OS, int Indent,
                                PdbSymbolIdField ShowIdFields,
                                PdbSymbolIdField RecurseIdFields) const {
  NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
  dumpSymbolField(OS, "name", getName(), Indent);
  dumpSymbolField(OS, "length", getLength(), Indent);
  dumpSymbolField(OS, "offset", getAddressOffset(), Indent);
  dumpSymbolField(OS, "section", getAddressSection(), Indent);
}

uint32_t NativeFunctionSymbol::getAddressOffset() const {
  return Sym.CodeOffset;
}

uint32_t NativeFunctionSymbol::getAddressSection() const { return Sym.Segment; }
std::string NativeFunctionSymbol::getName() const {
  return std::string(Sym.Name);
}

uint64_t NativeFunctionSymbol::getLength() const { return Sym.CodeSize; }

uint32_t NativeFunctionSymbol::getRelativeVirtualAddress() const {
  return Session.getRVAFromSectOffset(Sym.Segment, Sym.CodeOffset);
}

uint64_t NativeFunctionSymbol::getVirtualAddress() const {
  return Session.getVAFromSectOffset(Sym.Segment, Sym.CodeOffset);
}

static bool inlineSiteContainsAddress(InlineSiteSym &IS,
                                      uint32_t OffsetInFunc) {
  // Returns true if inline site contains the offset.
  bool Found = false;
  uint32_t CodeOffset = 0;
  for (auto &Annot : IS.annotations()) {
    switch (Annot.OpCode) {
    case BinaryAnnotationsOpCode::CodeOffset:
    case BinaryAnnotationsOpCode::ChangeCodeOffset:
    case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset:
      CodeOffset += Annot.U1;
      if (OffsetInFunc >= CodeOffset)
        Found = true;
      break;
    case BinaryAnnotationsOpCode::ChangeCodeLength:
      CodeOffset += Annot.U1;
      if (Found && OffsetInFunc < CodeOffset)
        return true;
      Found = false;
      break;
    case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset:
      CodeOffset += Annot.U2;
      if (OffsetInFunc >= CodeOffset && OffsetInFunc < CodeOffset + Annot.U1)
        return true;
      Found = false;
      break;
    default:
      break;
    }
  }
  return false;
}

std::unique_ptr<IPDBEnumSymbols>
NativeFunctionSymbol::findInlineFramesByVA(uint64_t VA) const {
  uint16_t Modi;
  if (!Session.moduleIndexForVA(VA, Modi))
    return nullptr;

  Expected<ModuleDebugStreamRef> ModS = Session.getModuleDebugStream(Modi);
  if (!ModS) {
    consumeError(ModS.takeError());
    return nullptr;
  }
  CVSymbolArray Syms = ModS->getSymbolArray();

  // Search for inline sites. There should be one matching top level inline
  // site. Then search in its nested inline sites.
  std::vector<SymIndexId> Frames;
  uint32_t CodeOffset = VA - getVirtualAddress();
  auto Start = Syms.at(RecordOffset);
  auto End = Syms.at(Sym.End);
  while (Start != End) {
    bool Found = false;
    // Find matching inline site within Start and End.
    for (; Start != End; ++Start) {
      if (Start->kind() != S_INLINESITE)
        continue;

      InlineSiteSym IS =
          cantFail(SymbolDeserializer::deserializeAs<InlineSiteSym>(*Start));
      if (inlineSiteContainsAddress(IS, CodeOffset)) {
        // Insert frames in reverse order.
        SymIndexId Id = Session.getSymbolCache().getOrCreateInlineSymbol(
            IS, getVirtualAddress(), Modi, Start.offset());
        Frames.insert(Frames.begin(), Id);

        // Update offsets to search within this inline site.
        ++Start;
        End = Syms.at(IS.End);
        Found = true;
        break;
      }

      Start = Syms.at(IS.End);
      if (Start == End)
        break;
    }

    if (!Found)
      break;
  }

  return std::make_unique<NativeEnumSymbols>(Session, std::move(Frames));
}
