//===- MapFile.cpp --------------------------------------------------------===//
//
//                             The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the /lldmap option. It shows lists in order and
// hierarchically the output sections, input sections, input files and
// symbol:
//
//   Address  Size     Align Out     File    Symbol
//   00201000 00000015     4 .text
//   00201000 0000000e     4         test.o:(.text)
//   0020100e 00000000     0                 local
//   00201005 00000000     0                 f(int)
//
//===----------------------------------------------------------------------===//

#include "MapFile.h"
#include "SymbolTable.h"
#include "Symbols.h"
#include "Writer.h"
#include "lld/Common/ErrorHandler.h"
#include "llvm/Support/Parallel.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;
using namespace llvm::object;

using namespace lld;
using namespace lld::coff;

typedef DenseMap<const SectionChunk *, SmallVector<DefinedRegular *, 4>>
    SymbolMapTy;

static const std::string Indent8 = "        ";          // 8 spaces
static const std::string Indent16 = "                "; // 16 spaces

// Print out the first three columns of a line.
static void writeHeader(raw_ostream &OS, uint64_t Addr, uint64_t Size,
                        uint64_t Align) {
  OS << format("%08llx %08llx %5lld ", Addr, Size, Align);
}

// Returns a list of all symbols that we want to print out.
static std::vector<DefinedRegular *> getSymbols() {
  std::vector<DefinedRegular *> V;
  for (ObjFile *File : ObjFile::Instances)
    for (Symbol *B : File->getSymbols())
      if (auto *Sym = dyn_cast_or_null<DefinedRegular>(B))
        if (Sym && !Sym->getCOFFSymbol().isSectionDefinition())
          V.push_back(Sym);
  return V;
}

// Returns a map from sections to their symbols.
static SymbolMapTy getSectionSyms(ArrayRef<DefinedRegular *> Syms) {
  SymbolMapTy Ret;
  for (DefinedRegular *S : Syms)
    Ret[S->getChunk()].push_back(S);

  // Sort symbols by address.
  for (auto &It : Ret) {
    SmallVectorImpl<DefinedRegular *> &V = It.second;
    std::sort(V.begin(), V.end(), [](DefinedRegular *A, DefinedRegular *B) {
      return A->getRVA() < B->getRVA();
    });
  }
  return Ret;
}

// Construct a map from symbols to their stringified representations.
static DenseMap<DefinedRegular *, std::string>
getSymbolStrings(ArrayRef<DefinedRegular *> Syms) {
  std::vector<std::string> Str(Syms.size());
  for_each_n(parallel::par, (size_t)0, Syms.size(), [&](size_t I) {
    raw_string_ostream OS(Str[I]);
    writeHeader(OS, Syms[I]->getRVA(), 0, 0);
    OS << Indent16 << toString(*Syms[I]);
  });

  DenseMap<DefinedRegular *, std::string> Ret;
  for (size_t I = 0, E = Syms.size(); I < E; ++I)
    Ret[Syms[I]] = std::move(Str[I]);
  return Ret;
}

void coff::writeMapFile(ArrayRef<OutputSection *> OutputSections) {
  if (Config->MapFile.empty())
    return;

  std::error_code EC;
  raw_fd_ostream OS(Config->MapFile, EC, sys::fs::F_None);
  if (EC)
    fatal("cannot open " + Config->MapFile + ": " + EC.message());

  // Collect symbol info that we want to print out.
  std::vector<DefinedRegular *> Syms = getSymbols();
  SymbolMapTy SectionSyms = getSectionSyms(Syms);
  DenseMap<DefinedRegular *, std::string> SymStr = getSymbolStrings(Syms);

  // Print out the header line.
  OS << "Address  Size     Align Out     In      Symbol\n";

  // Print out file contents.
  for (OutputSection *Sec : OutputSections) {
    writeHeader(OS, Sec->getRVA(), Sec->getVirtualSize(), /*Align=*/PageSize);
    OS << Sec->Name << '\n';

    for (Chunk *C : Sec->getChunks()) {
      auto *SC = dyn_cast<SectionChunk>(C);
      if (!SC)
        continue;

      writeHeader(OS, SC->getRVA(), SC->getSize(), SC->Alignment);
      OS << Indent8 << SC->File->getName() << ":(" << SC->getSectionName()
         << ")\n";
      for (DefinedRegular *Sym : SectionSyms[SC])
        OS << SymStr[Sym] << '\n';
    }
  }
}
