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 <cstdlib>
     11 #include <cstring>
     12 
     13 using namespace mcld;
     14 
     15 /// g_NullResolveInfo - a pointer to Null ResolveInfo.
     16 static ResolveInfo* g_NullResolveInfo = NULL;
     17 
     18 //===----------------------------------------------------------------------===//
     19 // ResolveInfo
     20 //===----------------------------------------------------------------------===//
     21 ResolveInfo::ResolveInfo()
     22   : m_Size(0), m_BitField(0) {
     23   m_Ptr.sym_ptr = 0;
     24 }
     25 
     26 ResolveInfo::~ResolveInfo()
     27 {
     28 }
     29 
     30 void ResolveInfo::override(const ResolveInfo& pFrom)
     31 {
     32   m_Size = pFrom.m_Size;
     33   overrideAttributes(pFrom);
     34   overrideVisibility(pFrom);
     35 }
     36 
     37 void ResolveInfo::overrideAttributes(const ResolveInfo& pFrom)
     38 {
     39   m_BitField &= ~RESOLVE_MASK;
     40   m_BitField |= (pFrom.m_BitField & RESOLVE_MASK);
     41 }
     42 
     43 /// overrideVisibility - override the visibility
     44 ///   always use the most strict visibility
     45 void ResolveInfo::overrideVisibility(const ResolveInfo& pFrom)
     46 {
     47   // Reference: Google gold linker: resolve.cc
     48   //
     49   // The rule for combining visibility is that we always choose the
     50   // most constrained visibility.  In order of increasing constraint,
     51   // visibility goes PROTECTED, HIDDEN, INTERNAL.  This is the reverse
     52   // of the numeric values, so the effect is that we always want the
     53   // smallest non-zero value.
     54   //
     55   // enum {
     56   //   STV_DEFAULT = 0,
     57   //   STV_INTERNAL = 1,
     58   //   STV_HIDDEN = 2,
     59   //   STV_PROTECTED = 3
     60   // };
     61 
     62   Visibility from_vis = pFrom.visibility();
     63   Visibility cur_vis = visibility();
     64   if (0 != from_vis ) {
     65     if (0 == cur_vis)
     66       setVisibility(from_vis);
     67     else if (cur_vis > from_vis)
     68       setVisibility(from_vis);
     69   }
     70 }
     71 
     72 void ResolveInfo::setRegular()
     73 {
     74   m_BitField &= (~dynamic_flag);
     75 }
     76 
     77 void ResolveInfo::setDynamic()
     78 {
     79   m_BitField |= dynamic_flag;
     80 }
     81 
     82 void ResolveInfo::setSource(bool pIsDyn)
     83 {
     84   if (pIsDyn)
     85     m_BitField |= dynamic_flag;
     86   else
     87     m_BitField &= (~dynamic_flag);
     88 }
     89 
     90 void ResolveInfo::setType(uint32_t pType)
     91 {
     92   m_BitField &= ~TYPE_MASK;
     93   m_BitField |= ((pType << TYPE_OFFSET) & TYPE_MASK);
     94 }
     95 
     96 void ResolveInfo::setDesc(uint32_t pDesc)
     97 {
     98   m_BitField &= ~DESC_MASK;
     99   m_BitField |= ((pDesc << DESC_OFFSET) & DESC_MASK);
    100 }
    101 
    102 void ResolveInfo::setBinding(uint32_t pBinding)
    103 {
    104   m_BitField &= ~BINDING_MASK;
    105   if (pBinding == Local || pBinding == Absolute)
    106     m_BitField |= local_flag;
    107   if (pBinding == Weak || pBinding == Absolute)
    108     m_BitField |= weak_flag;
    109 }
    110 
    111 void ResolveInfo::setReserved(uint32_t pReserved)
    112 {
    113   m_BitField &= ~RESERVED_MASK;
    114   m_BitField |= ((pReserved << RESERVED_OFFSET) & RESERVED_MASK);
    115 }
    116 
    117 void ResolveInfo::setOther(uint32_t pOther)
    118 {
    119   setVisibility(static_cast<ResolveInfo::Visibility>(pOther & 0x3));
    120 }
    121 
    122 void ResolveInfo::setVisibility(ResolveInfo::Visibility pVisibility)
    123 {
    124   m_BitField &= ~VISIBILITY_MASK;
    125   m_BitField |= pVisibility << VISIBILITY_OFFSET;
    126 }
    127 
    128 void ResolveInfo::setIsSymbol(bool pIsSymbol)
    129 {
    130   if (pIsSymbol)
    131     m_BitField |= symbol_flag;
    132   else
    133     m_BitField &= ~symbol_flag;
    134 }
    135 
    136 bool ResolveInfo::isNull() const
    137 {
    138   return (this == Null());
    139 }
    140 
    141 bool ResolveInfo::isDyn() const
    142 {
    143   return (dynamic_flag == (m_BitField & DYN_MASK));
    144 }
    145 
    146 bool ResolveInfo::isUndef() const
    147 {
    148   return (undefine_flag == (m_BitField & DESC_MASK));
    149 }
    150 
    151 bool ResolveInfo::isDefine() const
    152 {
    153   return (define_flag == (m_BitField & DESC_MASK));
    154 }
    155 
    156 bool ResolveInfo::isCommon() const
    157 {
    158   return (common_flag == (m_BitField & DESC_MASK));
    159 }
    160 
    161 bool ResolveInfo::isIndirect() const
    162 {
    163   return (indirect_flag == (m_BitField & DESC_MASK));
    164 }
    165 
    166 // isGlobal - [L,W] == [0, 0]
    167 bool ResolveInfo::isGlobal() const
    168 {
    169   return (global_flag == (m_BitField & BINDING_MASK));
    170 }
    171 
    172 // isWeak - [L,W] == [0, 1]
    173 bool ResolveInfo::isWeak() const
    174 {
    175   return (weak_flag == (m_BitField & BINDING_MASK));
    176 }
    177 
    178 // isLocal - [L,W] == [1, 0]
    179 bool ResolveInfo::isLocal() const
    180 {
    181   return (local_flag == (m_BitField & BINDING_MASK));
    182 }
    183 
    184 // isAbsolute - [L,W] == [1, 1]
    185 bool ResolveInfo::isAbsolute() const
    186 {
    187   return (absolute_flag == (m_BitField & BINDING_MASK));
    188 }
    189 
    190 bool ResolveInfo::isSymbol() const
    191 {
    192   return (symbol_flag == (m_BitField & SYMBOL_MASK));
    193 }
    194 
    195 bool ResolveInfo::isString() const
    196 {
    197   return (string_flag == (m_BitField & SYMBOL_MASK));
    198 }
    199 
    200 uint32_t ResolveInfo::type() const
    201 {
    202   return (m_BitField & TYPE_MASK) >> TYPE_OFFSET;
    203 }
    204 
    205 uint32_t ResolveInfo::desc() const
    206 {
    207   return (m_BitField & DESC_MASK) >> DESC_OFFSET;
    208 }
    209 
    210 uint32_t ResolveInfo::binding() const
    211 {
    212   if (m_BitField & LOCAL_MASK) {
    213     if (m_BitField & GLOBAL_MASK) {
    214       return ResolveInfo::Absolute;
    215     }
    216     return ResolveInfo::Local;
    217   }
    218   return m_BitField & GLOBAL_MASK;
    219 }
    220 
    221 uint32_t ResolveInfo::reserved() const
    222 {
    223   return (m_BitField & RESERVED_MASK) >> RESERVED_OFFSET;
    224 }
    225 
    226 ResolveInfo::Visibility ResolveInfo::visibility() const
    227 {
    228   return static_cast<ResolveInfo::Visibility>((m_BitField & VISIBILITY_MASK) >> VISIBILITY_OFFSET);
    229 }
    230 
    231 bool ResolveInfo::compare(const ResolveInfo::key_type& pKey)
    232 {
    233   size_t length = nameSize();
    234   if (length != pKey.size())
    235     return false;
    236   return (0 == std::memcmp(m_Name, pKey.data(), length));
    237 }
    238 
    239 //===----------------------------------------------------------------------===//
    240 // ResolveInfo Factory Methods
    241 //===----------------------------------------------------------------------===//
    242 ResolveInfo* ResolveInfo::Create(const ResolveInfo::key_type& pKey)
    243 {
    244   ResolveInfo* result = static_cast<ResolveInfo*>(
    245                           malloc(sizeof(ResolveInfo)+pKey.size()+1));
    246   if (NULL == result)
    247     return NULL;
    248 
    249   new (result) ResolveInfo();
    250   std::memcpy(result->m_Name, pKey.data(), pKey.size());
    251   result->m_Name[pKey.size()] = '\0';
    252   result->m_BitField &= ~ResolveInfo::RESOLVE_MASK;
    253   result->m_BitField |= (pKey.size() << ResolveInfo::NAME_LENGTH_OFFSET);
    254   return result;
    255 }
    256 
    257 void ResolveInfo::Destroy(ResolveInfo*& pInfo)
    258 {
    259   if (pInfo->isNull())
    260     return;
    261 
    262   if (NULL != pInfo) {
    263     pInfo->~ResolveInfo();
    264     free(pInfo);
    265   }
    266 
    267   pInfo = NULL;
    268 }
    269 
    270 ResolveInfo* ResolveInfo::Null()
    271 {
    272   if (NULL == g_NullResolveInfo) {
    273     g_NullResolveInfo = static_cast<ResolveInfo*>(
    274                           malloc(sizeof(ResolveInfo) + 1));
    275     new (g_NullResolveInfo) ResolveInfo();
    276     g_NullResolveInfo->m_Name[0] = '\0';
    277     g_NullResolveInfo->m_BitField = 0x0;
    278     g_NullResolveInfo->setBinding(Local);
    279   }
    280   return g_NullResolveInfo;
    281 }
    282 
    283