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

using namespace mcld;

//==========================
// StaticResolver
StaticResolver::~StaticResolver()
{
}

bool StaticResolver::resolve(ResolveInfo& __restrict__ pOld,
                             const ResolveInfo& __restrict__ pNew,
                             bool &pOverride) const
{

  /* The state table itself.
   * The first index is a link_row and the second index is a bfd_link_hash_type.
   *
   * Cs -> all rest kind of common (d_C, wd_C)
   * Is -> all kind of indeirect
   */
  static const enum LinkAction link_action[LAST_ORD][LAST_ORD] =
  {
    /* new\old  U       w_U     d_U    wd_U   D      w_D    d_D    wd_D   C      w_C,   Cs,    Is   */
    /* U    */ {NOACT,  UND,    UND,   UND,   NOACT, NOACT, DUND,  DUND,  NOACT, NOACT, NOACT, REFC },
    /* w_U  */ {NOACT,  NOACT,  NOACT, WEAK,  NOACT, NOACT, DUNDW, DUNDW, NOACT, NOACT, NOACT, REFC },
    /* d_U  */ {NOACT,  NOACT,  NOACT, NOACT, NOACT, NOACT, NOACT, NOACT, NOACT, NOACT, NOACT, REFC },
    /* wd_U */ {NOACT,  NOACT,  NOACT, NOACT, NOACT, NOACT, NOACT, NOACT, NOACT, NOACT, NOACT, REFC },
    /* D    */ {DEF,    DEF,    DEF,   DEF,   MDEF,  DEF,   DEF,   DEF,   CDEF,  CDEF,  CDEF,  MDEF },
    /* w_D  */ {DEFW,   DEFW,   DEFW,  DEFW,  NOACT, NOACT, DEFW,  DEFW,  NOACT, NOACT, NOACT, NOACT},
    /* d_D  */ {MDEFD,  MDEFD,  DEFD,  DEFD,  NOACT, NOACT, NOACT, NOACT, NOACT, NOACT, NOACT, MDEF },
    /* wd_D */ {MDEFWD, MDEFWD, DEFWD, DEFWD, NOACT, NOACT, NOACT, NOACT, NOACT, NOACT, NOACT, NOACT},
    /* C    */ {COM,    COM,    COM,   COM,   CREF,  COM,   COM,   COM,   MBIG,  COM,   BIG,   REFC },
    /* w_C  */ {COM,    COM,    COM,   COM,   NOACT, NOACT, NOACT, NOACT, NOACT, NOACT, NOACT, REFC },
    /* Cs   */ {COM,    COM,    COM,   COM,   NOACT, NOACT, NOACT, NOACT, MBIG,  MBIG,  MBIG,  REFC },
    /* Is   */ {IND,    IND,    IND,   IND,   MDEF,  IND,   IND,   IND,   CIND,  CIND,  CIND,  MIND }
  };

  // Special cases:
  // * when a dynamic defined symbol meets a dynamic weak defined symbol, act
  //   noting.
  // * when a undefined symbol meets a dynamic defined symbol, override by
  //   dynamic defined first, then recover back to undefined symbol later.
  // * when a dynamic defined symbol meets a undefined symbol or a weak
  //   undefined symbol, do not override, instead of marking.
  // * When a undefined symbol meets a dynamic defined symbol or a weak
  //   undefined symbol meets a dynamic defined symbol, should override.
  // * When a common symbol meets a weak common symbol, adjust the size of
  //   common symbol (ref: Google gold linker: resolve.cc)

  unsigned int row = getOrdinate(pNew);
  unsigned int col = getOrdinate(pOld);

  bool cycle = false;
  pOverride = false;
  ResolveInfo* old = &pOld;
  LinkAction action;
  do {
    cycle = false;
    action = link_action[row][col];

    switch(action) {
      case FAIL: {       /* abort.  */
        fatal(diag::fail_sym_resolution)
                << __FILE__ << __LINE__
                << "mclinker@googlegroups.com";
        return false;
      }
      case NOACT: {      /* no action.  */
        pOverride = false;
        old->overrideVisibility(pNew);
        break;
      }
      case UND:          /* override by symbol undefined symbol.  */
      case WEAK:         /* override by symbol weak undefined.  */
      case DEF:          /* override by symbol defined.  */
      case DEFW:         /* override by symbol weak defined.  */
      case DEFD:         /* override by symbol dynamic defined.  */
      case DEFWD:        /* override by symbol dynamic weak defined. */
      case COM: {        /* override by symbol common defined.  */
        pOverride = true;
        old->override(pNew);
        break;
      }
      case MDEFD:        /* mark symbol dynamic defined.  */
      case MDEFWD: {     /* mark symbol dynamic weak defined.  */
        uint32_t binding = old->binding();
        old->override(pNew);
        old->setBinding(binding);
        ignore(diag::mark_dynamic_defined) << old->name();
        pOverride = true;
        break;
      }
      case DUND:
      case DUNDW: {
        old->overrideVisibility(pNew);
        old->setDynamic();
        pOverride = false;
        break;
      }
      case CREF: {       /* Possibly warn about common reference to defined symbol.  */
        // A common symbol does not override a definition.
        ignore(diag::comm_refer_to_define) << old->name();
        pOverride = false;
        break;
      }
      case CDEF: {       /* redefine existing common symbol.  */
        // We've seen a common symbol and now we see a definition.  The
        // definition overrides.
        //
	// NOTE: m_Mesg uses 'name' instead of `name' for being compatible to GNU ld.
        ignore(diag::redefine_common) << old->name();
        old->override(pNew);
        pOverride = true;
        break;
      }
      case BIG: {        /* override by symbol common using largest size.  */
        if (old->size() < pNew.size())
          old->setSize(pNew.size());
        old->overrideAttributes(pNew);
        old->overrideVisibility(pNew);
        pOverride = true;
        break;
      }
      case MBIG: {       /* mark common symbol by larger size. */
        if (old->size() < pNew.size())
          old->setSize(pNew.size());
        old->overrideVisibility(pNew);
        pOverride = false;
        break;
      }
      case CIND: {       /* mark indirect symbol from existing common symbol.  */
         ignore(diag::indirect_refer_to_common) << old->name();
      }
      /* Fall through */
      case IND: {        /* override by indirect symbol.  */
        if (NULL == pNew.link()) {
          fatal(diag::indirect_refer_to_inexist) << pNew.name();
          break;
        }

        /** Should detect the loop of indirect symbol during file reading **/
        // if (pNew.link()->isIndirect() && pNew.link()->link() == &pNew) {
        //  m_Mesg = "indirect symbol `"+pNew.name()+"' to `"+pNew.link()->name()+"' is a loop.";
        //  return Resolver::Abort;
        //}

        // change the old symbol to the indirect symbol
        old->setLink(pNew.link());
        pOverride = true;
        break;
      }
      case MIND: {       /* multiple indirect symbols.  */
        // it is OK if they both point to the same symbol
        if (old->link() == pNew.link()) {
          pOverride = false;
          break;
        }
      }
      /* Fall through */
      case MDEF: {       /* multiple definition error.  */
        error(diag::multiple_definitions) << pNew.name();
        break;
      }
      case REFC: {       /* Mark indirect symbol referenced and then CYCLE.  */
        if (NULL == old->link()) {
          fatal(diag::indirect_refer_to_inexist) << old->name();
          break;
        }

        old = old->link();
        col = getOrdinate(*old);
        cycle = true;
        break;
      }
      default: {
        error(diag::undefined_situation) << action << old->name() << pNew.name();
        return false;
      }
    } // end of the big switch (action)
  } while(cycle);
  return true;
}

