//===- DWARF.cpp ----------------------------------------------------------===//
//
//                             The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// The -gdb-index option instructs the linker to emit a .gdb_index section.
// The section contains information to make gdb startup faster.
// The format of the section is described at
// https://sourceware.org/gdb/onlinedocs/gdb/Index-Section-Format.html.
//
//===----------------------------------------------------------------------===//

#include "DWARF.h"
#include "Symbols.h"
#include "Target.h"
#include "lld/Common/Memory.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"
#include "llvm/Object/ELFObjectFile.h"

using namespace llvm;
using namespace llvm::object;
using namespace lld;
using namespace lld::elf;

template <class ELFT> LLDDwarfObj<ELFT>::LLDDwarfObj(ObjFile<ELFT> *Obj) {
  for (InputSectionBase *Sec : Obj->getSections()) {
    if (!Sec)
      continue;
    if (LLDDWARFSection *M = StringSwitch<LLDDWARFSection *>(Sec->Name)
                                 .Case(".debug_info", &InfoSection)
                                 .Case(".debug_ranges", &RangeSection)
                                 .Case(".debug_line", &LineSection)
                                 .Default(nullptr)) {
      Sec->maybeDecompress();
      M->Data = toStringRef(Sec->Data);
      M->Sec = Sec;
      continue;
    }
    if (Sec->Name == ".debug_abbrev")
      AbbrevSection = toStringRef(Sec->Data);
    else if (Sec->Name == ".debug_gnu_pubnames")
      GnuPubNamesSection = toStringRef(Sec->Data);
    else if (Sec->Name == ".debug_gnu_pubtypes")
      GnuPubTypesSection = toStringRef(Sec->Data);
    else if (Sec->Name == ".debug_str")
      StrSection = toStringRef(Sec->Data);
  }
}

// Find if there is a relocation at Pos in Sec.  The code is a bit
// more complicated than usual because we need to pass a section index
// to llvm since it has no idea about InputSection.
template <class ELFT>
template <class RelTy>
Optional<RelocAddrEntry>
LLDDwarfObj<ELFT>::findAux(const InputSectionBase &Sec, uint64_t Pos,
                           ArrayRef<RelTy> Rels) const {
  auto It = std::lower_bound(
      Rels.begin(), Rels.end(), Pos,
      [](const RelTy &A, uint64_t B) { return A.r_offset < B; });
  if (It == Rels.end() || It->r_offset != Pos)
    return None;
  const RelTy &Rel = *It;

  const ObjFile<ELFT> *File = Sec.getFile<ELFT>();
  uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL);
  const typename ELFT::Sym &Sym = File->getELFSyms()[SymIndex];
  uint32_t SecIndex = File->getSectionIndex(Sym);

  // Broken debug info can point to a non-Defined symbol.
  auto *DR = dyn_cast<Defined>(&File->getRelocTargetSym(Rel));
  if (!DR) {
    RelType Type = Rel.getType(Config->IsMips64EL);
    if (Type != Target->NoneRel)
      error(toString(File) + ": relocation " + lld::toString(Type) + " at 0x" +
            llvm::utohexstr(Rel.r_offset) + " has unsupported target");
    return None;
  }
  uint64_t Val = DR->Value + getAddend<ELFT>(Rel);

  // FIXME: We should be consistent about always adding the file
  // offset or not.
  if (DR->Section->Flags & ELF::SHF_ALLOC)
    Val += cast<InputSection>(DR->Section)->getOffsetInFile();

  return RelocAddrEntry{SecIndex, Val};
}

template <class ELFT>
Optional<RelocAddrEntry> LLDDwarfObj<ELFT>::find(const llvm::DWARFSection &S,
                                                 uint64_t Pos) const {
  auto &Sec = static_cast<const LLDDWARFSection &>(S);
  if (Sec.Sec->AreRelocsRela)
    return findAux(*Sec.Sec, Pos, Sec.Sec->template relas<ELFT>());
  return findAux(*Sec.Sec, Pos, Sec.Sec->template rels<ELFT>());
}

template class elf::LLDDwarfObj<ELF32LE>;
template class elf::LLDDwarfObj<ELF32BE>;
template class elf::LLDDwarfObj<ELF64LE>;
template class elf::LLDDwarfObj<ELF64BE>;
