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