//===- 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 -Map option. It shows lists in order and
// hierarchically the output sections, input sections, input files and
// symbol:
//
//       Addr      Off   Size    Out     In      Symbol
//          - 00000015     10    .text
//          - 0000000e     10            test.o:(.text)
//          - 00000000      5                    local
//          - 00000000      5                    f(int)
//
//===----------------------------------------------------------------------===//

#include "MapFile.h"
#include "InputElement.h"
#include "InputFiles.h"
#include "OutputSections.h"
#include "OutputSegment.h"
#include "SymbolTable.h"
#include "Symbols.h"
#include "SyntheticSections.h"
#include "lld/Common/Strings.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SetVector.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::wasm;

using SymbolMapTy = DenseMap<const InputChunk *, SmallVector<Symbol *, 4>>;

// Print out the first three columns of a line.
static void writeHeader(raw_ostream &os, int64_t vma, uint64_t lma,
                        uint64_t size) {
  // Not all entries in the map has a virtual memory address (e.g. functions)
  if (vma == -1)
    os << format("       - %8llx %8llx ", lma, size);
  else
    os << format("%8llx %8llx %8llx ", vma, lma, size);
}

// Returns a list of all symbols that we want to print out.
static std::vector<Symbol *> getSymbols() {
  std::vector<Symbol *> v;
  for (InputFile *file : symtab->objectFiles)
    for (Symbol *b : file->getSymbols())
      if (auto *dr = dyn_cast<Symbol>(b))
        if ((!isa<SectionSymbol>(dr)) && dr->isLive() &&
            (dr->getFile() == file))
          v.push_back(dr);
  return v;
}

// Returns a map from sections to their symbols.
static SymbolMapTy getSectionSyms(ArrayRef<Symbol *> syms) {
  SymbolMapTy ret;
  for (Symbol *dr : syms)
    ret[dr->getChunk()].push_back(dr);
  return ret;
}

// Construct a map from symbols to their stringified representations.
// Demangling symbols (which is what toString() does) is slow, so
// we do that in batch using parallel-for.
static DenseMap<Symbol *, std::string>
getSymbolStrings(ArrayRef<Symbol *> syms) {
  std::vector<std::string> str(syms.size());
  parallelForEachN(0, syms.size(), [&](size_t i) {
    raw_string_ostream os(str[i]);
    auto *chunk = syms[i]->getChunk();
    if (chunk == nullptr)
      return;
    uint64_t fileOffset = chunk->outputSec->getOffset() + chunk->outSecOff;
    uint64_t vma = -1;
    uint64_t size = 0;
    if (auto *DD = dyn_cast<DefinedData>(syms[i])) {
      vma = DD->getVA();
      size = DD->getSize();
      fileOffset += DD->value;
    }
    if (auto *DF = dyn_cast<DefinedFunction>(syms[i])) {
      size = DF->function->getSize();
    }
    writeHeader(os, vma, fileOffset, size);
    os.indent(16) << toString(*syms[i]);
  });

  DenseMap<Symbol *, std::string> ret;
  for (size_t i = 0, e = syms.size(); i < e; ++i)
    ret[syms[i]] = std::move(str[i]);
  return ret;
}

void lld::wasm::writeMapFile(ArrayRef<OutputSection *> outputSections) {
  if (config->mapFile.empty())
    return;

  // Open a map file for writing.
  std::error_code ec;
  raw_fd_ostream os(config->mapFile, ec, sys::fs::OF_None);
  if (ec) {
    error("cannot open " + config->mapFile + ": " + ec.message());
    return;
  }

  // Collect symbol info that we want to print out.
  std::vector<Symbol *> syms = getSymbols();
  SymbolMapTy sectionSyms = getSectionSyms(syms);
  DenseMap<Symbol *, std::string> symStr = getSymbolStrings(syms);

  // Print out the header line.
  os << "    Addr      Off     Size Out     In      Symbol\n";

  for (OutputSection *osec : outputSections) {
    writeHeader(os, -1, osec->getOffset(), osec->getSize());
    os << toString(*osec) << '\n';
    if (auto *code = dyn_cast<CodeSection>(osec)) {
      for (auto *chunk : code->functions) {
        writeHeader(os, -1, chunk->outputSec->getOffset() + chunk->outSecOff,
                    chunk->getSize());
        os.indent(8) << toString(chunk) << '\n';
        for (Symbol *sym : sectionSyms[chunk])
          os << symStr[sym] << '\n';
      }
    } else if (auto *data = dyn_cast<DataSection>(osec)) {
      for (auto *oseg : data->segments) {
        writeHeader(os, oseg->startVA, data->getOffset() + oseg->sectionOffset,
                    oseg->size);
        os << oseg->name << '\n';
        for (auto *chunk : oseg->inputSegments) {
          writeHeader(os, chunk->getVA(),
                      chunk->outputSec->getOffset() + chunk->outSecOff,
                      chunk->getSize());
          os.indent(8) << toString(chunk) << '\n';
          for (Symbol *sym : sectionSyms[chunk])
            os << symStr[sym] << '\n';
        }
      }
    } else if (auto *globals = dyn_cast<GlobalSection>(osec)) {
      for (auto *global : globals->inputGlobals) {
        writeHeader(os, global->getAssignedIndex(), 0, 0);
        os.indent(8) << global->getName() << '\n';
      }
    }
    // TODO: other section/symbol types
  }
}
