//===- MapFile.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
//
//===----------------------------------------------------------------------===//
//
// 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 "lld/Common/Threads.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;
using namespace llvm::object;

using namespace lld;
using namespace lld::coff;

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

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());
  parallelForEachN((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->Chunks) {
      auto *SC = dyn_cast<SectionChunk>(C);
      if (!SC)
        continue;

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