Home | History | Annotate | Download | only in LD
      1 //===- ResolveInfo.cpp ----------------------------------------------------===//
      2 //
      3 //                     The MCLinker Project
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 #include "mcld/LD/ResolveInfo.h"
     10 #include <cstring>
     11 
     12 using namespace mcld;
     13 
     14 //==========================
     15 // ResolveInfo
     16 ResolveInfo::ResolveInfo()
     17   : m_Size(0), m_BitField(0) {
     18   m_Ptr.sym_ptr = 0;
     19 }
     20 
     21 ResolveInfo::~ResolveInfo()
     22 {
     23 }
     24 
     25 void ResolveInfo::override(const ResolveInfo& pFrom)
     26 {
     27   m_Size = pFrom.m_Size;
     28   overrideAttributes(pFrom);
     29   overrideVisibility(pFrom);
     30 }
     31 
     32 void ResolveInfo::overrideAttributes(const ResolveInfo& pFrom)
     33 {
     34   m_BitField &= ~RESOLVE_MASK;
     35   m_BitField |= (pFrom.m_BitField & RESOLVE_MASK);
     36 }
     37 
     38 /// overrideVisibility - override the visibility
     39 ///   always use the most strict visibility
     40 void ResolveInfo::overrideVisibility(const ResolveInfo& pFrom)
     41 {
     42   // Reference: Google gold linker: resolve.cc
     43   //
     44   // The rule for combining visibility is that we always choose the
     45   // most constrained visibility.  In order of increasing constraint,
     46   // visibility goes PROTECTED, HIDDEN, INTERNAL.  This is the reverse
     47   // of the numeric values, so the effect is that we always want the
     48   // smallest non-zero value.
     49   //
     50   // enum {
     51   //   STV_DEFAULT = 0,
     52   //   STV_INTERNAL = 1,
     53   //   STV_HIDDEN = 2,
     54   //   STV_PROTECTED = 3
     55   // };
     56 
     57   Visibility from_vis = pFrom.visibility();
     58   Visibility cur_vis = visibility();
     59   if (0 != from_vis ) {
     60     if (0 == cur_vis)
     61       setVisibility(from_vis);
     62     else if (cur_vis > from_vis)
     63       setVisibility(from_vis);
     64   }
     65 }
     66 
     67 void ResolveInfo::setRegular()
     68 {
     69   m_BitField &= (~dynamic_flag);
     70 }
     71 
     72 void ResolveInfo::setDynamic()
     73 {
     74   m_BitField |= dynamic_flag;
     75 }
     76 
     77 void ResolveInfo::setSource(bool pIsDyn)
     78 {
     79   if (pIsDyn)
     80     m_BitField |= dynamic_flag;
     81   else
     82     m_BitField &= (~dynamic_flag);
     83 }
     84 
     85 void ResolveInfo::setType(uint32_t pType)
     86 {
     87   m_BitField &= ~TYPE_MASK;
     88   m_BitField |= ((pType << TYPE_OFFSET) & TYPE_MASK);
     89 }
     90 
     91 void ResolveInfo::setDesc(uint32_t pDesc)
     92 {
     93   m_BitField &= ~DESC_MASK;
     94   m_BitField |= ((pDesc << DESC_OFFSET) & DESC_MASK);
     95 }
     96 
     97 void ResolveInfo::setBinding(uint32_t pBinding)
     98 {
     99   m_BitField &= ~BINDING_MASK;
    100   if (pBinding == Local || pBinding == Absolute)
    101     m_BitField |= local_flag;
    102   if (pBinding == Weak || pBinding == Absolute)
    103     m_BitField |= weak_flag;
    104 }
    105 
    106 void ResolveInfo::setReserved(uint32_t pReserved)
    107 {
    108   m_BitField &= ~RESERVED_MASK;
    109   m_BitField |= ((pReserved << RESERVED_OFFSET) & RESERVED_MASK);
    110 }
    111 
    112 void ResolveInfo::setOther(uint32_t pOther)
    113 {
    114   setVisibility(static_cast<ResolveInfo::Visibility>(pOther & 0x3));
    115 }
    116 
    117 void ResolveInfo::setVisibility(ResolveInfo::Visibility pVisibility)
    118 {
    119   m_BitField &= ~VISIBILITY_MASK;
    120   m_BitField |= pVisibility << VISIBILITY_OFFSET;
    121 }
    122 
    123 void ResolveInfo::setIsSymbol(bool pIsSymbol)
    124 {
    125   if (pIsSymbol)
    126     m_BitField |= symbol_flag;
    127   else
    128     m_BitField &= ~symbol_flag;
    129 }
    130 
    131 bool ResolveInfo::isDyn() const
    132 {
    133   return (dynamic_flag == (m_BitField & DYN_MASK));
    134 }
    135 
    136 bool ResolveInfo::isUndef() const
    137 {
    138   return (undefine_flag == (m_BitField & DESC_MASK));
    139 }
    140 
    141 bool ResolveInfo::isDefine() const
    142 {
    143   return (define_flag == (m_BitField & DESC_MASK));
    144 }
    145 
    146 bool ResolveInfo::isCommon() const
    147 {
    148   return (common_flag == (m_BitField & DESC_MASK));
    149 }
    150 
    151 bool ResolveInfo::isIndirect() const
    152 {
    153   return (indirect_flag == (m_BitField & DESC_MASK));
    154 }
    155 
    156 // isGlobal - [L,W] == [0, 0]
    157 bool ResolveInfo::isGlobal() const
    158 {
    159   return (global_flag == (m_BitField & BINDING_MASK));
    160 }
    161 
    162 // isWeak - [L,W] == [0, 1]
    163 bool ResolveInfo::isWeak() const
    164 {
    165   return (weak_flag == (m_BitField & BINDING_MASK));
    166 }
    167 
    168 // isLocal - [L,W] == [1, 0]
    169 bool ResolveInfo::isLocal() const
    170 {
    171   return (local_flag == (m_BitField & BINDING_MASK));
    172 }
    173 
    174 // isAbsolute - [L,W] == [1, 1]
    175 bool ResolveInfo::isAbsolute() const
    176 {
    177   return (absolute_flag == (m_BitField & BINDING_MASK));
    178 }
    179 
    180 bool ResolveInfo::isSymbol() const
    181 {
    182   return (symbol_flag == (m_BitField & SYMBOL_MASK));
    183 }
    184 
    185 bool ResolveInfo::isString() const
    186 {
    187   return (string_flag == (m_BitField & SYMBOL_MASK));
    188 }
    189 
    190 uint32_t ResolveInfo::type() const
    191 {
    192   return (m_BitField & TYPE_MASK) >> TYPE_OFFSET;
    193 }
    194 
    195 uint32_t ResolveInfo::desc() const
    196 {
    197   return (m_BitField & DESC_MASK) >> DESC_OFFSET;
    198 }
    199 
    200 uint32_t ResolveInfo::binding() const
    201 {
    202   if (m_BitField & LOCAL_MASK) {
    203     if (m_BitField & GLOBAL_MASK) {
    204       return ResolveInfo::Absolute;
    205     }
    206     return ResolveInfo::Local;
    207   }
    208   return m_BitField & GLOBAL_MASK;
    209 }
    210 
    211 uint32_t ResolveInfo::reserved() const
    212 {
    213   return (m_BitField & RESERVED_MASK) >> RESERVED_OFFSET;
    214 }
    215 
    216 ResolveInfo::Visibility ResolveInfo::visibility() const
    217 {
    218   return static_cast<ResolveInfo::Visibility>((m_BitField & VISIBILITY_MASK) >> VISIBILITY_OFFSET);
    219 }
    220 
    221 bool ResolveInfo::compare(const ResolveInfo::key_type& pKey)
    222 {
    223   size_t length = nameSize();
    224   if (length != pKey.size())
    225     return false;
    226   return (0 == std::memcmp(m_Name, pKey.data(), length));
    227 }
    228 
    229