//===- 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 in the same format as link.exe
// (based on observations)
//
// Header (program name, timestamp info, preferred load address)
//
// Section list (Start = Section index:Base address):
// Start         Length     Name                   Class
// 0001:00001000 00000015H .text                   CODE
//
// Symbols list:
// Address        Publics by Value    Rva + Base          Lib:Object
// 0001:00001000  main                 0000000140001000    main.obj
// 0001:00001300  ?__scrt_common_main@@YAHXZ  0000000140001300 libcmt:exe_main.obj
//
// entry point at        0001:00000360
//
// Static symbols
//
// 0000:00000000  __guard_fids__       0000000140000000     libcmt : exe_main.obj
//===----------------------------------------------------------------------===//

#include "MapFile.h"
#include "COFFLinkerContext.h"
#include "SymbolTable.h"
#include "Symbols.h"
#include "Writer.h"
#include "lld/Common/Timer.h"
#include "llvm/Support/Parallel.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/TimeProfiler.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;
using namespace llvm::object;
using namespace lld;
using namespace lld::coff;

// Print out the first two columns of a line.
static void writeHeader(raw_ostream &os, uint32_t sec, uint64_t addr) {
  os << format(" %04x:%08llx", sec, addr);
}

// Write the time stamp with the format used by link.exe
// It seems identical to strftime with "%c" on msvc build, but we need a
// locale-agnostic version.
static void writeFormattedTimestamp(raw_ostream &os, time_t tds) {
  constexpr const char *const days[7] = {"Sun", "Mon", "Tue", "Wed",
                                         "Thu", "Fri", "Sat"};
  constexpr const char *const months[12] = {"Jan", "Feb", "Mar", "Apr",
                                            "May", "Jun", "Jul", "Aug",
                                            "Sep", "Oct", "Nov", "Dec"};
  tm *time = localtime(&tds);
  os << format("%s %s %2d %02d:%02d:%02d %d", days[time->tm_wday],
               months[time->tm_mon], time->tm_mday, time->tm_hour, time->tm_min,
               time->tm_sec, time->tm_year + 1900);
}

static void sortUniqueSymbols(std::vector<Defined *> &syms,
                              uint64_t imageBase) {
  // Build helper vector
  using SortEntry = std::pair<Defined *, size_t>;
  std::vector<SortEntry> v;
  v.resize(syms.size());
  for (size_t i = 0, e = syms.size(); i < e; ++i)
    v[i] = SortEntry(syms[i], i);

  // Remove duplicate symbol pointers
  parallelSort(v, std::less<SortEntry>());
  auto end = llvm::unique(v, [](const SortEntry &a, const SortEntry &b) {
    return a.first == b.first;
  });
  v.erase(end, v.end());

  // Sort by RVA then original order
  parallelSort(v, [imageBase](const SortEntry &a, const SortEntry &b) {
    // Add config.imageBase to avoid comparing "negative" RVAs.
    // This can happen with symbols of Absolute kind
    uint64_t rvaa = imageBase + a.first->getRVA();
    uint64_t rvab = imageBase + b.first->getRVA();
    return rvaa < rvab || (rvaa == rvab && a.second < b.second);
  });

  syms.resize(v.size());
  for (size_t i = 0, e = v.size(); i < e; ++i)
    syms[i] = v[i].first;
}

// Returns the lists of all symbols that we want to print out.
static void getSymbols(const COFFLinkerContext &ctx,
                       std::vector<Defined *> &syms,
                       std::vector<Defined *> &staticSyms) {

  for (ObjFile *file : ctx.objFileInstances)
    for (Symbol *b : file->getSymbols()) {
      if (!b || !b->isLive())
        continue;
      if (auto *sym = dyn_cast<DefinedCOFF>(b)) {
        COFFSymbolRef symRef = sym->getCOFFSymbol();
        if (!symRef.isSectionDefinition() &&
            symRef.getStorageClass() != COFF::IMAGE_SYM_CLASS_LABEL) {
          if (symRef.getStorageClass() == COFF::IMAGE_SYM_CLASS_STATIC)
            staticSyms.push_back(sym);
          else
            syms.push_back(sym);
        }
      } else if (auto *sym = dyn_cast<Defined>(b)) {
        syms.push_back(sym);
      }
    }

  for (ImportFile *file : ctx.importFileInstances) {
    if (!file->live)
      continue;

    if (file->impSym)
      syms.push_back(file->impSym);
    if (file->thunkSym && file->thunkSym->isLive())
      syms.push_back(file->thunkSym);
    if (file->auxThunkSym && file->auxThunkSym->isLive())
      syms.push_back(file->auxThunkSym);
    if (file->impchkThunk)
      syms.push_back(file->impchkThunk->sym);
    if (file->impECSym)
      syms.push_back(file->impECSym);
    if (file->auxImpCopySym)
      syms.push_back(file->auxImpCopySym);
  }

  sortUniqueSymbols(syms, ctx.config.imageBase);
  sortUniqueSymbols(staticSyms, ctx.config.imageBase);
}

// Construct a map from symbols to their stringified representations.
static DenseMap<Defined *, std::string>
getSymbolStrings(const COFFLinkerContext &ctx, ArrayRef<Defined *> syms) {
  std::vector<std::string> str(syms.size());
  parallelFor((size_t)0, syms.size(), [&](size_t i) {
    raw_string_ostream os(str[i]);
    Defined *sym = syms[i];

    uint16_t sectionIdx = 0;
    uint64_t address = 0;
    SmallString<128> fileDescr;

    if (auto *absSym = dyn_cast<DefinedAbsolute>(sym)) {
      address = absSym->getVA();
      fileDescr = "<absolute>";
    } else if (isa<DefinedSynthetic>(sym)) {
      fileDescr = "<linker-defined>";
    } else if (isa<DefinedCommon>(sym)) {
      fileDescr = "<common>";
    } else if (Chunk *chunk = sym->getChunk()) {
      address = sym->getRVA();
      if (OutputSection *sec = ctx.getOutputSection(chunk))
        address -= sec->header.VirtualAddress;

      sectionIdx = chunk->getOutputSectionIdx();

      InputFile *file;
      if (auto *impSym = dyn_cast<DefinedImportData>(sym))
        file = impSym->file;
      else if (auto *thunkSym = dyn_cast<DefinedImportThunk>(sym))
        file = thunkSym->wrappedSym->file;
      else
        file = sym->getFile();

      if (file) {
        if (!file->parentName.empty()) {
          fileDescr = sys::path::filename(file->parentName);
          sys::path::replace_extension(fileDescr, "");
          fileDescr += ":";
        }
        fileDescr += sys::path::filename(file->getName());
      }
    }
    writeHeader(os, sectionIdx, address);
    os << "       ";
    os << left_justify(sym->getName(), 26);
    os << " ";
    os << format_hex_no_prefix((ctx.config.imageBase + sym->getRVA()), 16);
    if (!fileDescr.empty()) {
      os << "     "; // FIXME : Handle "f" and "i" flags sometimes generated
                     // by link.exe in those spaces
      os << fileDescr;
    }
  });

  DenseMap<Defined *, 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::coff::writeMapFile(COFFLinkerContext &ctx) {
  if (ctx.config.mapFile.empty())
    return;

  llvm::TimeTraceScope timeScope("Map file");
  std::error_code ec;
  raw_fd_ostream os(ctx.config.mapFile, ec, sys::fs::OF_None);
  if (ec)
    Fatal(ctx) << "cannot open " << ctx.config.mapFile << ": " << ec.message();

  ScopedTimer t1(ctx.totalMapTimer);

  // Collect symbol info that we want to print out.
  ScopedTimer t2(ctx.symbolGatherTimer);
  std::vector<Defined *> syms;
  std::vector<Defined *> staticSyms;
  getSymbols(ctx, syms, staticSyms);
  t2.stop();

  ScopedTimer t3(ctx.symbolStringsTimer);
  DenseMap<Defined *, std::string> symStr = getSymbolStrings(ctx, syms);
  DenseMap<Defined *, std::string> staticSymStr =
      getSymbolStrings(ctx, staticSyms);
  t3.stop();

  ScopedTimer t4(ctx.writeTimer);
  SmallString<128> AppName = sys::path::filename(ctx.config.outputFile);
  sys::path::replace_extension(AppName, "");

  // Print out the file header
  os << " " << AppName << "\n";
  os << "\n";

  os << " Timestamp is " << format_hex_no_prefix(ctx.config.timestamp, 8)
     << " (";
  if (ctx.config.repro) {
    os << "Repro mode";
  } else {
    writeFormattedTimestamp(os, ctx.config.timestamp);
  }
  os << ")\n";

  os << "\n";
  os << " Preferred load address is "
     << format_hex_no_prefix(ctx.config.imageBase, 16) << "\n";
  os << "\n";

  // Print out section table.
  os << " Start         Length     Name                   Class\n";

  for (OutputSection *sec : ctx.outputSections) {
    // Merge display of chunks with same sectionName
    std::vector<std::pair<SectionChunk *, SectionChunk *>> ChunkRanges;
    for (Chunk *c : sec->chunks) {
      auto *sc = dyn_cast<SectionChunk>(c);
      if (!sc)
        continue;

      if (ChunkRanges.empty() ||
          c->getSectionName() != ChunkRanges.back().first->getSectionName()) {
        ChunkRanges.emplace_back(sc, sc);
      } else {
        ChunkRanges.back().second = sc;
      }
    }

    const bool isCodeSection =
        (sec->header.Characteristics & COFF::IMAGE_SCN_CNT_CODE) &&
        (sec->header.Characteristics & COFF::IMAGE_SCN_MEM_READ) &&
        (sec->header.Characteristics & COFF::IMAGE_SCN_MEM_EXECUTE);
    StringRef SectionClass = (isCodeSection ? "CODE" : "DATA");

    for (auto &cr : ChunkRanges) {
      size_t size =
          cr.second->getRVA() + cr.second->getSize() - cr.first->getRVA();

      auto address = cr.first->getRVA() - sec->header.VirtualAddress;
      writeHeader(os, sec->sectionIndex, address);
      os << " " << format_hex_no_prefix(size, 8) << "H";
      os << " " << left_justify(cr.first->getSectionName(), 23);
      os << " " << SectionClass;
      os << '\n';
    }
  }

  // Print out the symbols table (without static symbols)
  os << "\n";
  os << "  Address         Publics by Value              Rva+Base"
        "               Lib:Object\n";
  os << "\n";
  for (Defined *sym : syms)
    os << symStr[sym] << '\n';

  // Print out the entry point.
  os << "\n";

  uint16_t entrySecIndex = 0;
  uint64_t entryAddress = 0;

  if (!ctx.config.noEntry) {
    Defined *entry = dyn_cast_or_null<Defined>(ctx.symtab.entry);
    if (entry) {
      Chunk *chunk = entry->getChunk();
      entrySecIndex = chunk->getOutputSectionIdx();
      entryAddress =
          entry->getRVA() - ctx.getOutputSection(chunk)->header.VirtualAddress;
    }
  }
  os << " entry point at         ";
  os << format("%04x:%08llx", entrySecIndex, entryAddress);
  os << "\n";

  // Print out the static symbols
  os << "\n";
  os << " Static symbols\n";
  os << "\n";
  for (Defined *sym : staticSyms)
    os << staticSymStr[sym] << '\n';

  // Print out the exported functions
  if (ctx.config.mapInfo) {
    os << "\n";
    os << " Exports\n";
    os << "\n";
    os << "  ordinal    name\n\n";
    for (Export &e : ctx.symtab.exports) {
      os << format("  %7d", e.ordinal) << "    " << e.name << "\n";
      if (!e.extName.empty() && e.extName != e.name)
        os << "               exported name: " << e.extName << "\n";
    }
  }

  t4.stop();
  t1.stop();
}
