//===-- FormatterBytecode.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/DataFormatters/FormatterSection.h"

#include "lldb/Core/Module.h"
#include "lldb/DataFormatters/DataVisualization.h"
#include "lldb/Utility/LLDBLog.h"

using namespace lldb;

namespace lldb_private {
static void ForEachFormatterInModule(
    Module &module, SectionType section_type,
    std::function<void(llvm::DataExtractor, llvm::StringRef)> fn) {
  auto *sections = module.GetSectionList();
  if (!sections)
    return;

  auto section_sp = sections->FindSectionByType(section_type, true);
  if (!section_sp)
    return;

  TypeCategoryImplSP category;
  DataVisualization::Categories::GetCategory(ConstString("default"), category);

  // The type summary record is serialized as follows.
  //
  // Each record contains, in order:
  //   * Version number of the record format
  //   * The remaining size of the record
  //   * The size of the type identifier
  //   * The type identifier, either a type name, or a regex
  //   * The size of the entry
  //   * The entry
  //
  // Integers are encoded using ULEB.
  //
  // Strings are encoded with first a length (ULEB), then the string contents,
  // and lastly a null terminator. The length includes the null.

  DataExtractor lldb_extractor;
  auto section_size = section_sp->GetSectionData(lldb_extractor);
  llvm::DataExtractor section = lldb_extractor.GetAsLLVM();
  bool le = section.isLittleEndian();
  uint8_t addr_size = section.getAddressSize();
  llvm::DataExtractor::Cursor cursor(0);
  while (cursor && cursor.tell() < section_size) {
    while (cursor && cursor.tell() < section_size) {
      // Skip over 0 padding.
      if (section.getU8(cursor) == 0)
        continue;
      cursor.seek(cursor.tell() - 1);
      break;
    }
    uint64_t version = section.getULEB128(cursor);
    uint64_t record_size = section.getULEB128(cursor);
    if (version == 1) {
      llvm::DataExtractor record(section.getData().drop_front(cursor.tell()),
                                 le, addr_size);
      llvm::DataExtractor::Cursor cursor(0);
      uint64_t type_size = record.getULEB128(cursor);
      llvm::StringRef type_name = record.getBytes(cursor, type_size);
      llvm::Error error = cursor.takeError();
      if (!error)
        fn(llvm::DataExtractor(record.getData().drop_front(cursor.tell()), le,
                               addr_size),
           type_name);
      else
        LLDB_LOG_ERROR(GetLog(LLDBLog::DataFormatters), std::move(error),
                       "{0}");
    } else {
      // Skip unsupported record.
      LLDB_LOG(
          GetLog(LLDBLog::DataFormatters),
          "Skipping unsupported embedded type summary of version {0} in {1}.",
          version, module.GetFileSpec());
    }
    section.skip(cursor, record_size);
  }
  if (!cursor)
    LLDB_LOG_ERROR(GetLog(LLDBLog::DataFormatters), cursor.takeError(), "{0}");
}

void LoadTypeSummariesForModule(ModuleSP module_sp) {
  ForEachFormatterInModule(
      *module_sp, eSectionTypeLLDBTypeSummaries,
      [&](llvm::DataExtractor extractor, llvm::StringRef type_name) {
        TypeCategoryImplSP category;
        DataVisualization::Categories::GetCategory(ConstString("default"),
                                                   category);
        // The type summary record is serialized as follows.
        //
        //   * The size of the summary string
        //   * The summary string
        //
        // Integers are encoded using ULEB.
        llvm::DataExtractor::Cursor cursor(0);
        uint64_t summary_size = extractor.getULEB128(cursor);
        llvm::StringRef summary_string =
            extractor.getBytes(cursor, summary_size);
        if (!cursor) {
          LLDB_LOG_ERROR(GetLog(LLDBLog::DataFormatters), cursor.takeError(),
                         "{0}");
          return;
        }
        if (type_name.empty() || summary_string.empty()) {
          LLDB_LOG(GetLog(LLDBLog::DataFormatters),
                   "Missing string(s) in embedded type summary in {0}, "
                   "type_name={1}, summary={2}",
                   module_sp->GetFileSpec(), type_name, summary_string);
          return;
        }
        TypeSummaryImpl::Flags flags;
        auto summary_sp = std::make_shared<StringSummaryFormat>(
            flags, summary_string.str().c_str());
        FormatterMatchType match_type = eFormatterMatchExact;
        if (type_name.front() == '^')
          match_type = eFormatterMatchRegex;
        category->AddTypeSummary(type_name, match_type, summary_sp);
        LLDB_LOG(GetLog(LLDBLog::DataFormatters),
                 "Loaded embedded type summary for '{0}' from {1}.", type_name,
                 module_sp->GetFileSpec());
      });
}

void LoadFormattersForModule(ModuleSP module_sp) {
  ForEachFormatterInModule(
      *module_sp, eSectionTypeLLDBFormatters,
      [&](llvm::DataExtractor extractor, llvm::StringRef type_name) {
        // * Function signature (1 byte)
        // * Length of the program (ULEB128)
        // * The program bytecode
        TypeCategoryImplSP category;
        DataVisualization::Categories::GetCategory(ConstString("default"),
                                                   category);
        llvm::DataExtractor::Cursor cursor(0);
        uint64_t flags = extractor.getULEB128(cursor);
        while (cursor && cursor.tell() < extractor.size()) {
          uint8_t signature = extractor.getU8(cursor);
          uint64_t size = extractor.getULEB128(cursor);
          llvm::StringRef bytecode = extractor.getBytes(cursor, size);
          if (!cursor) {
            LLDB_LOG_ERROR(GetLog(LLDBLog::DataFormatters), cursor.takeError(),
                           "{0}");
            return;
          }
          if (signature == 0) {
            auto summary_sp = std::make_shared<BytecodeSummaryFormat>(
                TypeSummaryImpl::Flags(flags),
                llvm::MemoryBuffer::getMemBufferCopy(bytecode));
            FormatterMatchType match_type = eFormatterMatchExact;
            if (type_name.front() == '^')
              match_type = eFormatterMatchRegex;
            category->AddTypeSummary(type_name, match_type, summary_sp);
            LLDB_LOG(GetLog(LLDBLog::DataFormatters),
                     "Loaded embedded type summary for '{0}' from {1}.",
                     type_name, module_sp->GetFileSpec());
          } else
            LLDB_LOG(GetLog(LLDBLog::DataFormatters),
                     "Unsupported formatter signature {0} for '{1}' in {2}",
                     signature, type_name, module_sp->GetFileSpec());
        }
      });
}
} // namespace lldb_private
