//===- DWARFGdbIndex.cpp --------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/DebugInfo/DWARF/DWARFGdbIndex.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Format.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::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);
    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 CuTypesListSize = (AddressAreaOffset - CuTypesOffset) / 24;
  if (CuTypesListSize != 0)
    return false;

  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);
}
