//===- ResolveInfo.h ------------------------------------------------------===//
//
//                     The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef MCLD_RESOLVE_INFO_H
#define MCLD_RESOLVE_INFO_H
#ifdef ENABLE_UNITTEST
#include <gtest.h>
#endif

#include <llvm/Support/DataTypes.h>
#include <llvm/ADT/StringRef.h>

namespace mcld
{

class LDSymbol;

/** \class ResolveInfo
 *  \brief ResolveInfo records the information about how to resolve a symbol.
 *
 *  A symbol must have some `attributes':
 *  - Desc - Defined, Reference, Common or Indirect
 *  - Binding - Global, Local, Weak
 *  - IsDyn - appear in dynamic objects or regular objects
 *  - Type - what the symbol points to
 *  - Size  - the size of the symbol point to
 *  - Value - the pointer to another LDSymbol
 *  In order to save the memory and speed up the performance, MCLinker uses
 *  a bit field to store all attributes.
 *
 *  The maximum string length is (2^16 - 1)
 */
class ResolveInfo
{
friend class ResolveInfoFactory;
friend class MCLinker;
public:
  typedef uint64_t SizeType;

  /** \enum Type
   *  \brief What the symbol stand for
   *
   *  It is like ELF32_ST_TYPE
   *  MachO does not need this, and can not jump between Thumb and ARM code.
   */
  enum Type {
    NoType        = 0,
    Object        = 1,
    Function      = 2,
    Section       = 3,
    File          = 4,
    CommonBlock   = 5,
    ThreadLocal    = 6,
    LoProc        = 13,
    HiProc        = 15
  };

  /** \enum Desc
   *  \brief Description of the symbols.
   *
   *   Follow the naming in MachO. Like MachO nlist::n_desc
   *   In ELF, is a part of st_shndx
   */
  enum Desc {
    Undefined    = 0,
    Define       = 1,
    Common       = 2,
    Indirect     = 3,
    NoneDesc
  };

  enum Binding {
    Global       = 0,
    Weak         = 1,
    Local        = 2,
    Absolute     = 3,
    NoneBinding
  };

  enum Visibility {
    Default      = 0,
    Internal     = 1,
    Hidden       = 2,
    Protected    = 3
  };

  // -----  For HashTable  ----- //
  typedef llvm::StringRef key_type;

public:
  // -----  modifiers  ----- //
  /// setRegular - set the source of the file is a regular object
  void setRegular();

  /// setDynamic - set the source of the file is a dynamic object
  void setDynamic();

  /// setSource - set the source of the file
  /// @param pIsDyn is the source from a dynamic object?
  void setSource(bool pIsDyn);

  void setType(uint32_t pType);

  void setDesc(uint32_t pDesc);

  void setBinding(uint32_t pBinding);

  void setOther(uint32_t pOther);

  void setVisibility(Visibility pVisibility);

  void setIsSymbol(bool pIsSymbol);

  void setReserved(uint32_t pReserved);

  void setSize(SizeType pSize)
  { m_Size = pSize; }

  void override(const ResolveInfo& pForm);

  void overrideAttributes(const ResolveInfo& pFrom);

  void overrideVisibility(const ResolveInfo& pFrom);

  void setSymPtr(const LDSymbol* pSymPtr)
  { m_Ptr.sym_ptr = const_cast<LDSymbol*>(pSymPtr); }

  void setLink(const ResolveInfo* pTarget) {
    m_Ptr.info_ptr = const_cast<ResolveInfo*>(pTarget);
    m_BitField |= indirect_flag;
  }


  // -----  observers  ----- //
  bool isSymbol() const;

  bool isString() const;

  bool isGlobal() const;

  bool isWeak() const;

  bool isLocal() const;

  bool isAbsolute() const;

  bool isDefine() const;

  bool isUndef() const;

  bool isDyn() const;

  bool isCommon() const;

  bool isIndirect() const;

  uint32_t type() const;

  uint32_t desc() const;

  uint32_t binding() const;

  uint32_t reserved() const;

  uint8_t other() const
  { return (uint8_t)visibility(); }

  Visibility visibility() const;

  LDSymbol* outSymbol()
  { return m_Ptr.sym_ptr; }

  const LDSymbol* outSymbol() const
  { return m_Ptr.sym_ptr; }

  ResolveInfo* link()
  { return m_Ptr.info_ptr; }

  const ResolveInfo* link() const
  { return m_Ptr.info_ptr; }

  SizeType size() const
  { return m_Size; }

  const char* name() const
  { return m_Name; }

  unsigned int nameSize() const
  { return (m_BitField >> NAME_LENGTH_OFFSET); }

  uint32_t info() const
  { return (m_BitField & INFO_MASK); }

  uint32_t bitfield() const
  { return m_BitField; }

  // -----  For HashTable  ----- //
  bool compare(const key_type& pKey);

private:
  static const uint32_t GLOBAL_OFFSET      = 0;
  static const uint32_t GLOBAL_MASK        = 1;

  static const uint32_t DYN_OFFSET         = 1;
  static const uint32_t DYN_MASK           = 1   << DYN_OFFSET;

  static const uint32_t DESC_OFFSET        = 2;
  static const uint32_t DESC_MASK          = 0x3 << DESC_OFFSET;

  static const uint32_t LOCAL_OFFSET       = 4;
  static const uint32_t LOCAL_MASK         = 1   << LOCAL_OFFSET;

  static const uint32_t BINDING_MASK       = GLOBAL_MASK | LOCAL_MASK;

  static const uint32_t VISIBILITY_OFFSET  = 5;
  static const uint32_t VISIBILITY_MASK    = 0x3 << VISIBILITY_OFFSET;

  static const uint32_t TYPE_OFFSET        = 7;
  static const uint32_t TYPE_MASK          = 0xF << TYPE_OFFSET;

  static const uint32_t SYMBOL_OFFSET      = 11;
  static const uint32_t SYMBOL_MASK        = 1   << SYMBOL_OFFSET;

  static const uint32_t RESERVED_OFFSET    = 12;
  static const uint32_t RESERVED_MASK      = 0xF << RESERVED_OFFSET;
  static const uint32_t NAME_LENGTH_OFFSET = 16;
  static const uint32_t INFO_MASK          = 0xF;
  static const uint32_t RESOLVE_MASK       = 0xFFFF;

  union SymOrInfo {
    LDSymbol*    sym_ptr;
    ResolveInfo* info_ptr;
  };

public:
  static const uint32_t global_flag    = 0        << GLOBAL_OFFSET;
  static const uint32_t weak_flag      = 1        << GLOBAL_OFFSET;
  static const uint32_t regular_flag   = 0        << DYN_OFFSET;
  static const uint32_t dynamic_flag   = 1        << DYN_OFFSET;
  static const uint32_t undefine_flag  = 0        << DESC_OFFSET;
  static const uint32_t define_flag    = 1        << DESC_OFFSET;
  static const uint32_t common_flag    = 2        << DESC_OFFSET;
  static const uint32_t indirect_flag  = 3        << DESC_OFFSET;
  static const uint32_t local_flag     = 1        << LOCAL_OFFSET;
  static const uint32_t absolute_flag  = BINDING_MASK;
  static const uint32_t object_flag    = Object   << TYPE_OFFSET;
  static const uint32_t function_flag  = Function << TYPE_OFFSET;
  static const uint32_t section_flag   = Section  << TYPE_OFFSET;
  static const uint32_t file_flag      = File     << TYPE_OFFSET;
  static const uint32_t string_flag    = 0        << SYMBOL_OFFSET;
  static const uint32_t symbol_flag    = 1        << SYMBOL_OFFSET;

private:
  ResolveInfo();
  ResolveInfo(const ResolveInfo& pCopy);
  ResolveInfo& operator=(const ResolveInfo& pCopy);
  ~ResolveInfo();

private:
  SizeType m_Size;
  SymOrInfo m_Ptr;

  /** m_BitField
   *  31     ...    16 15    12 11     10..7 6      ..    5 4     3   2   1   0
   * |length of m_Name|reserved|Symbol|Type |ELF visibility|Local|Com|Def|Dyn|Weak|
   */
  uint32_t m_BitField;
  char m_Name[0];
};

} // namespace of mcld

#endif

