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