//===- 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->override(pNew);
        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;
}

