//===- DWARFGdbIndex.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 "llvm/DebugInfo/DWARF/DWARFGdbIndex.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
#include <cinttypes>
#include <cstdint>
#include <utility>

using namespace llvm;

// .gdb_index section format reference:
// https://sourceware.org/gdb/onlinedocs/gdb/Index-Section-Format.html

void DWARFGdbIndex::dumpCUList(raw_ostream &OS) const {
  OS << format("\n  CU list offset = 0x%x, has %" PRId64 " entries:",
               CuListOffset, (uint64_t)CuList.size())
     << '\n';
  uint32_t I = 0;
  for (const CompUnitEntry &CU : CuList)
    OS << format("    %d: Offset = 0x%llx, Length = 0x%llx\n", I++, CU.Offset,
                 CU.Length);
}

void DWARFGdbIndex::dumpTUList(raw_ostream &OS) const {
  OS << formatv("\n  Types CU list offset = {0:x}, has {1} entries:\n",
                TuListOffset, TuList.size());
  uint32_t I = 0;
  for (const TypeUnitEntry &TU : TuList)
    OS << formatv("    {0}: offset = {1:x8}, type_offset = {2:x8}, "
                  "type_signature = {3:x16}\n",
                  I++, TU.Offset, TU.TypeOffset, TU.TypeSignature);
}

void DWARFGdbIndex::dumpAddressArea(raw_ostream &OS) const {
  OS << format("\n  Address area offset = 0x%x, has %" PRId64 " entries:",
               AddressAreaOffset, (uint64_t)AddressArea.size())
     << '\n';
  for (const AddressEntry &Addr : AddressArea)
    OS << format(
        "    Low/High address = [0x%llx, 0x%llx) (Size: 0x%llx), CU id = %d\n",
        Addr.LowAddress, Addr.HighAddress, Addr.HighAddress - Addr.LowAddress,
        Addr.CuIndex);
}

void DWARFGdbIndex::dumpSymbolTable(raw_ostream &OS) const {
  OS << format("\n  Symbol table offset = 0x%x, size = %" PRId64
               ", filled slots:",
               SymbolTableOffset, (uint64_t)SymbolTable.size())
     << '\n';
  uint32_t I = -1;
  for (const SymTableEntry &E : SymbolTable) {
    ++I;
    if (!E.NameOffset && !E.VecOffset)
      continue;

    OS << format("    %d: Name offset = 0x%x, CU vector offset = 0x%x\n", I,
                 E.NameOffset, E.VecOffset);

    StringRef Name = ConstantPoolStrings.substr(
        ConstantPoolOffset - StringPoolOffset + E.NameOffset);

    auto CuVector = std::find_if(
        ConstantPoolVectors.begin(), ConstantPoolVectors.end(),
        [&](const std::pair<uint32_t, SmallVector<uint32_t, 0>> &V) {
          return V.first == E.VecOffset;
        });
    assert(CuVector != ConstantPoolVectors.end() && "Invalid symbol table");
    uint32_t CuVectorId = CuVector - ConstantPoolVectors.begin();
    OS << format("      String name: %s, CU vector index: %d\n", Name.data(),
                 CuVectorId);
  }
}

void DWARFGdbIndex::dumpConstantPool(raw_ostream &OS) const {
  OS << format("\n  Constant pool offset = 0x%x, has %" PRId64 " CU vectors:",
               ConstantPoolOffset, (uint64_t)ConstantPoolVectors.size());
  uint32_t I = 0;
  for (const auto &V : ConstantPoolVectors) {
    OS << format("\n    %d(0x%x): ", I++, V.first);
    for (uint32_t Val : V.second)
      OS << format("0x%x ", Val);
  }
  OS << '\n';
}

void DWARFGdbIndex::dump(raw_ostream &OS) {
  if (HasError) {
    OS << "\n<error parsing>\n";
    return;
  }

  if (HasContent) {
    OS << "  Version = " << Version << '\n';
    dumpCUList(OS);
    dumpTUList(OS);
    dumpAddressArea(OS);
    dumpSymbolTable(OS);
    dumpConstantPool(OS);
  }
}

bool DWARFGdbIndex::parseImpl(DataExtractor Data) {
  uint32_t Offset = 0;

  // Only version 7 is supported at this moment.
  Version = Data.getU32(&Offset);
  if (Version != 7)
    return false;

  CuListOffset = Data.getU32(&Offset);
  uint32_t CuTypesOffset = Data.getU32(&Offset);
  AddressAreaOffset = Data.getU32(&Offset);
  SymbolTableOffset = Data.getU32(&Offset);
  ConstantPoolOffset = Data.getU32(&Offset);

  if (Offset != CuListOffset)
    return false;

  uint32_t CuListSize = (CuTypesOffset - CuListOffset) / 16;
  CuList.reserve(CuListSize);
  for (uint32_t i = 0; i < CuListSize; ++i) {
    uint64_t CuOffset = Data.getU64(&Offset);
    uint64_t CuLength = Data.getU64(&Offset);
    CuList.push_back({CuOffset, CuLength});
  }

  // CU Types are no longer needed as DWARF skeleton type units never made it
  // into the standard.
  uint32_t TuListSize = (AddressAreaOffset - CuTypesOffset) / 24;
  TuList.resize(TuListSize);
  for (uint32_t I = 0; I < TuListSize; ++I) {
    uint64_t CuOffset = Data.getU64(&Offset);
    uint64_t TypeOffset = Data.getU64(&Offset);
    uint64_t Signature = Data.getU64(&Offset);
    TuList[I] = {CuOffset, TypeOffset, Signature};
  }

  uint32_t AddressAreaSize = (SymbolTableOffset - AddressAreaOffset) / 20;
  AddressArea.reserve(AddressAreaSize);
  for (uint32_t i = 0; i < AddressAreaSize; ++i) {
    uint64_t LowAddress = Data.getU64(&Offset);
    uint64_t HighAddress = Data.getU64(&Offset);
    uint32_t CuIndex = Data.getU32(&Offset);
    AddressArea.push_back({LowAddress, HighAddress, CuIndex});
  }

  // The symbol table. This is an open addressed hash table. The size of the
  // hash table is always a power of 2.
  // Each slot in the hash table consists of a pair of offset_type values. The
  // first value is the offset of the symbol's name in the constant pool. The
  // second value is the offset of the CU vector in the constant pool.
  // If both values are 0, then this slot in the hash table is empty. This is ok
  // because while 0 is a valid constant pool index, it cannot be a valid index
  // for both a string and a CU vector.
  uint32_t SymTableSize = (ConstantPoolOffset - SymbolTableOffset) / 8;
  SymbolTable.reserve(SymTableSize);
  uint32_t CuVectorsTotal = 0;
  for (uint32_t i = 0; i < SymTableSize; ++i) {
    uint32_t NameOffset = Data.getU32(&Offset);
    uint32_t CuVecOffset = Data.getU32(&Offset);
    SymbolTable.push_back({NameOffset, CuVecOffset});
    if (NameOffset || CuVecOffset)
      ++CuVectorsTotal;
  }

  // The constant pool. CU vectors are stored first, followed by strings.
  // The first value is the number of CU indices in the vector. Each subsequent
  // value is the index and symbol attributes of a CU in the CU list.
  for (uint32_t i = 0; i < CuVectorsTotal; ++i) {
    ConstantPoolVectors.emplace_back(0, SmallVector<uint32_t, 0>());
    auto &Vec = ConstantPoolVectors.back();
    Vec.first = Offset - ConstantPoolOffset;

    uint32_t Num = Data.getU32(&Offset);
    for (uint32_t j = 0; j < Num; ++j)
      Vec.second.push_back(Data.getU32(&Offset));
  }

  ConstantPoolStrings = Data.getData().drop_front(Offset);
  StringPoolOffset = Offset;
  return true;
}

void DWARFGdbIndex::parse(DataExtractor Data) {
  HasContent = !Data.getData().empty();
  HasError = HasContent && !parseImpl(Data);
}
