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