//===- Symbols.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
//
//===----------------------------------------------------------------------===//

#include "Symbols.h"
#include "COFFLinkerContext.h"
#include "InputFiles.h"
#include "lld/Common/ErrorHandler.h"
#include "llvm/Demangle/Demangle.h"

using namespace llvm;
using namespace llvm::object;

using namespace lld::coff;

namespace lld {

static_assert(sizeof(SymbolUnion) <= 48,
              "symbols should be optimized for memory usage");

// Returns a symbol name for an error message.
std::string maybeDemangleSymbol(const COFFLinkerContext &ctx,
                                StringRef symName) {
  if (ctx.config.demangle) {
    std::string prefix;
    StringRef prefixless = symName;
    if (prefixless.consume_front("__imp_"))
      prefix = "__declspec(dllimport) ";
    StringRef demangleInput = prefixless;
    if (ctx.config.machine == I386)
      demangleInput.consume_front("_");
    std::string demangled = demangle(demangleInput);
    if (demangled != demangleInput)
      return prefix + demangled;
    return (prefix + prefixless).str();
  }
  return std::string(symName);
}
std::string toString(const COFFLinkerContext &ctx, coff::Symbol &b) {
  return maybeDemangleSymbol(ctx, b.getName());
}
std::string toCOFFString(const COFFLinkerContext &ctx,
                         const Archive::Symbol &b) {
  return maybeDemangleSymbol(ctx, b.getName());
}

const COFFSyncStream &
coff::operator<<(const COFFSyncStream &s,
                 const llvm::object::Archive::Symbol *sym) {
  s << maybeDemangleSymbol(s.ctx, sym->getName());
  return s;
}

namespace coff {

void Symbol::computeName() {
  assert(nameData == nullptr &&
         "should only compute the name once for DefinedCOFF symbols");
  auto *d = cast<DefinedCOFF>(this);
  StringRef nameStr =
      check(cast<ObjFile>(d->file)->getCOFFObj()->getSymbolName(d->sym));
  nameData = nameStr.data();
  nameSize = nameStr.size();
  assert(nameSize == nameStr.size() && "name length truncated");
}

InputFile *Symbol::getFile() {
  if (auto *sym = dyn_cast<DefinedCOFF>(this))
    return sym->file;
  if (auto *sym = dyn_cast<LazyArchive>(this))
    return sym->file;
  if (auto *sym = dyn_cast<LazyObject>(this))
    return sym->file;
  if (auto *sym = dyn_cast<LazyDLLSymbol>(this))
    return sym->file;
  return nullptr;
}

bool Symbol::isLive() const {
  if (auto *r = dyn_cast<DefinedRegular>(this))
    return r->getChunk()->live;
  if (auto *imp = dyn_cast<DefinedImportData>(this))
    return imp->file->live;
  if (auto *imp = dyn_cast<DefinedImportThunk>(this))
    return imp->getChunk()->live;
  // Assume any other kind of symbol is live.
  return true;
}

Defined *Symbol::getDefined() {
  if (auto d = dyn_cast<Defined>(this))
    return d;
  if (auto u = dyn_cast<Undefined>(this))
    return u->getDefinedWeakAlias();
  return nullptr;
}

void Symbol::replaceKeepingName(Symbol *other, size_t size) {
  StringRef origName = getName();
  memcpy(this, other, size);
  nameData = origName.data();
  nameSize = origName.size();
}

COFFSymbolRef DefinedCOFF::getCOFFSymbol() {
  size_t symSize = cast<ObjFile>(file)->getCOFFObj()->getSymbolTableEntrySize();
  if (symSize == sizeof(coff_symbol16))
    return COFFSymbolRef(reinterpret_cast<const coff_symbol16 *>(sym));
  assert(symSize == sizeof(coff_symbol32));
  return COFFSymbolRef(reinterpret_cast<const coff_symbol32 *>(sym));
}

uint64_t DefinedAbsolute::getRVA() { return va - ctx.config.imageBase; }

DefinedImportThunk::DefinedImportThunk(COFFLinkerContext &ctx, StringRef name,
                                       DefinedImportData *s,
                                       ImportThunkChunk *chunk)
    : Defined(DefinedImportThunkKind, name), wrappedSym(s), data(chunk) {}

Symbol *Undefined::getWeakAlias() {
  // A weak alias may be a weak alias to another symbol, so check recursively.
  DenseSet<Symbol *> weakChain;
  for (Symbol *a = weakAlias; a; a = cast<Undefined>(a)->weakAlias) {
    // Anti-dependency symbols can't be chained.
    if (a->isAntiDep)
      break;
    if (!isa<Undefined>(a))
      return a;
    if (!weakChain.insert(a).second)
      break; // We have a cycle.
  }
  return nullptr;
}

bool Undefined::resolveWeakAlias() {
  Defined *d = getDefinedWeakAlias();
  if (!d)
    return false;

  // We want to replace Sym with D. However, we can't just blindly
  // copy sizeof(SymbolUnion) bytes from D to Sym because D may be an
  // internal symbol, and internal symbols are stored as "unparented"
  // Symbols. For that reason we need to check which type of symbol we
  // are dealing with and copy the correct number of bytes.
  StringRef name = getName();
  bool wasAntiDep = isAntiDep;
  if (isa<DefinedRegular>(d))
    memcpy(this, d, sizeof(DefinedRegular));
  else if (isa<DefinedAbsolute>(d))
    memcpy(this, d, sizeof(DefinedAbsolute));
  else
    memcpy(this, d, sizeof(SymbolUnion));

  nameData = name.data();
  nameSize = name.size();
  isAntiDep = wasAntiDep;
  return true;
}

MemoryBufferRef LazyArchive::getMemberBuffer() {
  Archive::Child c =
      CHECK(sym.getMember(), "could not get the member for symbol " +
                                 toCOFFString(file->symtab.ctx, sym));
  return CHECK(c.getMemoryBufferRef(),
               "could not get the buffer for the member defining symbol " +
                   toCOFFString(file->symtab.ctx, sym));
}
} // namespace coff
} // namespace lld
