//===- Symbols.cpp --------------------------------------------------------===//
//
//                             The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "Error.h"
#include "InputFiles.h"
#include "Symbols.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm::object;
using llvm::sys::fs::identify_magic;
using llvm::sys::fs::file_magic;

namespace lld {
namespace coff {

StringRef SymbolBody::getName() {
  // DefinedCOFF names are read lazily for a performance reason.
  // Non-external symbol names are never used by the linker except for logging
  // or debugging. Their internal references are resolved not by name but by
  // symbol index. And because they are not external, no one can refer them by
  // name. Object files contain lots of non-external symbols, and creating
  // StringRefs for them (which involves lots of strlen() on the string table)
  // is a waste of time.
  if (Name.empty()) {
    auto *D = cast<DefinedCOFF>(this);
    D->File->getCOFFObj()->getSymbolName(D->Sym, Name);
  }
  return Name;
}

// Returns 1, 0 or -1 if this symbol should take precedence
// over the Other, tie or lose, respectively.
int SymbolBody::compare(SymbolBody *Other) {
  Kind LK = kind(), RK = Other->kind();

  // Normalize so that the smaller kind is on the left.
  if (LK > RK)
    return -Other->compare(this);

  // First handle comparisons between two different kinds.
  if (LK != RK) {
    if (RK > LastDefinedKind) {
      if (LK == LazyKind && cast<Undefined>(Other)->WeakAlias)
        return -1;

      // The LHS is either defined or lazy and so it wins.
      assert((LK <= LastDefinedKind || LK == LazyKind) && "Bad kind!");
      return 1;
    }

    // Bitcode has special complexities.
    if (RK == DefinedBitcodeKind) {
      auto *RHS = cast<DefinedBitcode>(Other);

      switch (LK) {
      case DefinedCommonKind:
        return 1;

      case DefinedRegularKind:
        // As an approximation, regular symbols win over bitcode symbols,
        // but we definitely have a conflict if the regular symbol is not
        // replaceable and neither is the bitcode symbol. We do not
        // replicate the rest of the symbol resolution logic here; symbol
        // resolution will be done accurately after lowering bitcode symbols
        // to regular symbols in addCombinedLTOObject().
        if (cast<DefinedRegular>(this)->isCOMDAT() || RHS->IsReplaceable)
          return 1;

        // Fallthrough to the default of a tie otherwise.
      default:
        return 0;
      }
    }

    // Either of the object file kind will trump a higher kind.
    if (LK <= LastDefinedCOFFKind)
      return 1;

    // The remaining kind pairs are ties amongst defined symbols.
    return 0;
  }

  // Now handle the case where the kinds are the same.
  switch (LK) {
  case DefinedRegularKind: {
    auto *LHS = cast<DefinedRegular>(this);
    auto *RHS = cast<DefinedRegular>(Other);
    if (LHS->isCOMDAT() && RHS->isCOMDAT())
      return LHS->getFileIndex() < RHS->getFileIndex() ? 1 : -1;
    return 0;
  }

  case DefinedCommonKind: {
    auto *LHS = cast<DefinedCommon>(this);
    auto *RHS = cast<DefinedCommon>(Other);
    if (LHS->getSize() == RHS->getSize())
      return LHS->getFileIndex() < RHS->getFileIndex() ? 1 : -1;
    return LHS->getSize() > RHS->getSize() ? 1 : -1;
  }

  case DefinedBitcodeKind: {
    auto *LHS = cast<DefinedBitcode>(this);
    auto *RHS = cast<DefinedBitcode>(Other);
    // If both are non-replaceable, we have a tie.
    if (!LHS->IsReplaceable && !RHS->IsReplaceable)
      return 0;

    // Non-replaceable symbols win, but even two replaceable symboles don't
    // tie. If both symbols are replaceable, choice is arbitrary.
    if (RHS->IsReplaceable && LHS->IsReplaceable)
      return uintptr_t(LHS) < uintptr_t(RHS) ? 1 : -1;
    return LHS->IsReplaceable ? -1 : 1;
  }

  case LazyKind: {
    // Don't tie, pick the earliest.
    auto *LHS = cast<Lazy>(this);
    auto *RHS = cast<Lazy>(Other);
    return LHS->getFileIndex() < RHS->getFileIndex() ? 1 : -1;
  }

  case UndefinedKind: {
    auto *LHS = cast<Undefined>(this);
    auto *RHS = cast<Undefined>(Other);
    // Tie if both undefined symbols have different weak aliases.
    if (LHS->WeakAlias && RHS->WeakAlias) {
      if (LHS->WeakAlias->getName() != RHS->WeakAlias->getName())
        return 0;
      return uintptr_t(LHS) < uintptr_t(RHS) ? 1 : -1;
    }
    return LHS->WeakAlias ? 1 : -1;
  }

  case DefinedLocalImportKind:
  case DefinedImportThunkKind:
  case DefinedImportDataKind:
  case DefinedAbsoluteKind:
  case DefinedRelativeKind:
    // These all simply tie.
    return 0;
  }
  llvm_unreachable("unknown symbol kind");
}

std::string SymbolBody::getDebugName() {
  std::string N = getName().str();
  if (auto *D = dyn_cast<DefinedCOFF>(this)) {
    N += " ";
    N += D->File->getShortName();
  } else if (auto *D = dyn_cast<DefinedBitcode>(this)) {
    N += " ";
    N += D->File->getShortName();
  }
  return N;
}

uint64_t Defined::getFileOff() {
  switch (kind()) {
  case DefinedImportDataKind:
    return cast<DefinedImportData>(this)->getFileOff();
  case DefinedImportThunkKind:
    return cast<DefinedImportThunk>(this)->getFileOff();
  case DefinedLocalImportKind:
    return cast<DefinedLocalImport>(this)->getFileOff();
  case DefinedCommonKind:
    return cast<DefinedCommon>(this)->getFileOff();
  case DefinedRegularKind:
    return cast<DefinedRegular>(this)->getFileOff();

  case DefinedBitcodeKind:
    llvm_unreachable("There is no file offset for a bitcode symbol.");
  case DefinedAbsoluteKind:
    llvm_unreachable("Cannot get a file offset for an absolute symbol.");
  case DefinedRelativeKind:
    llvm_unreachable("Cannot get a file offset for a relative symbol.");
  case LazyKind:
  case UndefinedKind:
    llvm_unreachable("Cannot get a file offset for an undefined symbol.");
  }
  llvm_unreachable("unknown symbol kind");
}

COFFSymbolRef DefinedCOFF::getCOFFSymbol() {
  size_t SymSize = 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));
}

DefinedImportThunk::DefinedImportThunk(StringRef Name, DefinedImportData *S,
                                       uint16_t Machine)
    : Defined(DefinedImportThunkKind, Name) {
  switch (Machine) {
  case AMD64: Data.reset(new ImportThunkChunkX64(S)); return;
  case I386:  Data.reset(new ImportThunkChunkX86(S)); return;
  case ARMNT: Data.reset(new ImportThunkChunkARM(S)); return;
  default:    llvm_unreachable("unknown machine type");
  }
}

std::unique_ptr<InputFile> Lazy::getMember() {
  MemoryBufferRef MBRef = File->getMember(&Sym);

  // getMember returns an empty buffer if the member was already
  // read from the library.
  if (MBRef.getBuffer().empty())
    return std::unique_ptr<InputFile>(nullptr);

  file_magic Magic = identify_magic(MBRef.getBuffer());
  if (Magic == file_magic::coff_import_library)
    return std::unique_ptr<InputFile>(new ImportFile(MBRef));

  std::unique_ptr<InputFile> Obj;
  if (Magic == file_magic::coff_object)
    Obj.reset(new ObjectFile(MBRef));
  else if (Magic == file_magic::bitcode)
    Obj.reset(new BitcodeFile(MBRef));
  else
    error(Twine(File->getName()) + ": unknown file type");

  Obj->setParentName(File->getName());
  return Obj;
}

Defined *Undefined::getWeakAlias() {
  // A weak alias may be a weak alias to another symbol, so check recursively.
  for (SymbolBody *A = WeakAlias; A; A = cast<Undefined>(A)->WeakAlias)
    if (auto *D = dyn_cast<Defined>(A->repl()))
      return D;
  return nullptr;
}

} // namespace coff
} // namespace lld
