//===- ResolveInfo.cpp ----------------------------------------------------===//
//
//                     The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <mcld/LD/ResolveInfo.h>
#include <cstdlib>
#include <cstring>

using namespace mcld;

/// g_NullResolveInfo - a pointer to Null ResolveInfo.
static ResolveInfo* g_NullResolveInfo = NULL;

//===----------------------------------------------------------------------===//
// ResolveInfo
//===----------------------------------------------------------------------===//
ResolveInfo::ResolveInfo()
  : m_Size(0), m_BitField(0) {
  m_Ptr.sym_ptr = 0;
}

ResolveInfo::~ResolveInfo()
{
}

void ResolveInfo::override(const ResolveInfo& pFrom)
{
  m_Size = pFrom.m_Size;
  overrideAttributes(pFrom);
  overrideVisibility(pFrom);
}

void ResolveInfo::overrideAttributes(const ResolveInfo& pFrom)
{
  m_BitField &= ~RESOLVE_MASK;
  m_BitField |= (pFrom.m_BitField & RESOLVE_MASK);
}

/// overrideVisibility - override the visibility
///   always use the most strict visibility
void ResolveInfo::overrideVisibility(const ResolveInfo& pFrom)
{
  // Reference: Google gold linker: resolve.cc
  //
  // The rule for combining visibility is that we always choose the
  // most constrained visibility.  In order of increasing constraint,
  // visibility goes PROTECTED, HIDDEN, INTERNAL.  This is the reverse
  // of the numeric values, so the effect is that we always want the
  // smallest non-zero value.
  //
  // enum {
  //   STV_DEFAULT = 0,
  //   STV_INTERNAL = 1,
  //   STV_HIDDEN = 2,
  //   STV_PROTECTED = 3
  // };

  Visibility from_vis = pFrom.visibility();
  Visibility cur_vis = visibility();
  if (0 != from_vis ) {
    if (0 == cur_vis)
      setVisibility(from_vis);
    else if (cur_vis > from_vis)
      setVisibility(from_vis);
  }
}

void ResolveInfo::setRegular()
{
  m_BitField &= (~dynamic_flag);
}

void ResolveInfo::setDynamic()
{
  m_BitField |= dynamic_flag;
}

void ResolveInfo::setSource(bool pIsDyn)
{
  if (pIsDyn)
    m_BitField |= dynamic_flag;
  else
    m_BitField &= (~dynamic_flag);
}

void ResolveInfo::setType(uint32_t pType)
{
  m_BitField &= ~TYPE_MASK;
  m_BitField |= ((pType << TYPE_OFFSET) & TYPE_MASK);
}

void ResolveInfo::setDesc(uint32_t pDesc)
{
  m_BitField &= ~DESC_MASK;
  m_BitField |= ((pDesc << DESC_OFFSET) & DESC_MASK);
}

void ResolveInfo::setBinding(uint32_t pBinding)
{
  m_BitField &= ~BINDING_MASK;
  if (pBinding == Local || pBinding == Absolute)
    m_BitField |= local_flag;
  if (pBinding == Weak || pBinding == Absolute)
    m_BitField |= weak_flag;
}

void ResolveInfo::setReserved(uint32_t pReserved)
{
  m_BitField &= ~RESERVED_MASK;
  m_BitField |= ((pReserved << RESERVED_OFFSET) & RESERVED_MASK);
}

void ResolveInfo::setOther(uint32_t pOther)
{
  setVisibility(static_cast<ResolveInfo::Visibility>(pOther & 0x3));
}

void ResolveInfo::setVisibility(ResolveInfo::Visibility pVisibility)
{
  m_BitField &= ~VISIBILITY_MASK;
  m_BitField |= pVisibility << VISIBILITY_OFFSET;
}

void ResolveInfo::setIsSymbol(bool pIsSymbol)
{
  if (pIsSymbol)
    m_BitField |= symbol_flag;
  else
    m_BitField &= ~symbol_flag;
}

bool ResolveInfo::isNull() const
{
  return (this == Null());
}

bool ResolveInfo::isDyn() const
{
  return (dynamic_flag == (m_BitField & DYN_MASK));
}

bool ResolveInfo::isUndef() const
{
  return (undefine_flag == (m_BitField & DESC_MASK));
}

bool ResolveInfo::isDefine() const
{
  return (define_flag == (m_BitField & DESC_MASK));
}

bool ResolveInfo::isCommon() const
{
  return (common_flag == (m_BitField & DESC_MASK));
}

bool ResolveInfo::isIndirect() const
{
  return (indirect_flag == (m_BitField & DESC_MASK));
}

// isGlobal - [L,W] == [0, 0]
bool ResolveInfo::isGlobal() const
{
  return (global_flag == (m_BitField & BINDING_MASK));
}

// isWeak - [L,W] == [0, 1]
bool ResolveInfo::isWeak() const
{
  return (weak_flag == (m_BitField & BINDING_MASK));
}

// isLocal - [L,W] == [1, 0]
bool ResolveInfo::isLocal() const
{
  return (local_flag == (m_BitField & BINDING_MASK));
}

// isAbsolute - [L,W] == [1, 1]
bool ResolveInfo::isAbsolute() const
{
  return (absolute_flag == (m_BitField & BINDING_MASK));
}

bool ResolveInfo::isSymbol() const
{
  return (symbol_flag == (m_BitField & SYMBOL_MASK));
}

bool ResolveInfo::isString() const
{
  return (string_flag == (m_BitField & SYMBOL_MASK));
}

uint32_t ResolveInfo::type() const
{
  return (m_BitField & TYPE_MASK) >> TYPE_OFFSET;
}

uint32_t ResolveInfo::desc() const
{
  return (m_BitField & DESC_MASK) >> DESC_OFFSET;
}

uint32_t ResolveInfo::binding() const
{
  if (m_BitField & LOCAL_MASK) {
    if (m_BitField & GLOBAL_MASK) {
      return ResolveInfo::Absolute;
    }
    return ResolveInfo::Local;
  }
  return m_BitField & GLOBAL_MASK;
}

uint32_t ResolveInfo::reserved() const
{
  return (m_BitField & RESERVED_MASK) >> RESERVED_OFFSET;
}

ResolveInfo::Visibility ResolveInfo::visibility() const
{
  return static_cast<ResolveInfo::Visibility>((m_BitField & VISIBILITY_MASK) >> VISIBILITY_OFFSET);
}

bool ResolveInfo::compare(const ResolveInfo::key_type& pKey)
{
  size_t length = nameSize();
  if (length != pKey.size())
    return false;
  return (0 == std::memcmp(m_Name, pKey.data(), length));
}

//===----------------------------------------------------------------------===//
// ResolveInfo Factory Methods
//===----------------------------------------------------------------------===//
ResolveInfo* ResolveInfo::Create(const ResolveInfo::key_type& pKey)
{
  ResolveInfo* result = static_cast<ResolveInfo*>(
                          malloc(sizeof(ResolveInfo)+pKey.size()+1));
  if (NULL == result)
    return NULL;

  new (result) ResolveInfo();
  std::memcpy(result->m_Name, pKey.data(), pKey.size());
  result->m_Name[pKey.size()] = '\0';
  result->m_BitField &= ~ResolveInfo::RESOLVE_MASK;
  result->m_BitField |= (pKey.size() << ResolveInfo::NAME_LENGTH_OFFSET);
  return result;
}

void ResolveInfo::Destroy(ResolveInfo*& pInfo)
{
  if (pInfo->isNull())
    return;

  if (NULL != pInfo) {
    pInfo->~ResolveInfo();
    free(pInfo);
  }

  pInfo = NULL;
}

ResolveInfo* ResolveInfo::Null()
{
  if (NULL == g_NullResolveInfo) {
    g_NullResolveInfo = static_cast<ResolveInfo*>(
                          malloc(sizeof(ResolveInfo) + 1));
    new (g_NullResolveInfo) ResolveInfo();
    g_NullResolveInfo->m_Name[0] = '\0';
    g_NullResolveInfo->m_BitField = 0x0;
  }
  return g_NullResolveInfo;
}

