• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 //===----------------------------------------------------------------------===//
ResolveInfo()28 ResolveInfo::ResolveInfo() : m_Size(0), m_BitField(0) {
29   m_Ptr.sym_ptr = 0;
30 }
31 
~ResolveInfo()32 ResolveInfo::~ResolveInfo() {
33 }
34 
override(const ResolveInfo & pFrom)35 void ResolveInfo::override(const ResolveInfo& pFrom) {
36   m_Size = pFrom.m_Size;
37   overrideAttributes(pFrom);
38   overrideVisibility(pFrom);
39 }
40 
overrideAttributes(const ResolveInfo & pFrom)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
overrideVisibility(const ResolveInfo & pFrom)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 
setRegular()72 void ResolveInfo::setRegular() {
73   m_BitField &= (~dynamic_flag);
74 }
75 
setDynamic()76 void ResolveInfo::setDynamic() {
77   m_BitField |= dynamic_flag;
78 }
79 
setSource(bool pIsDyn)80 void ResolveInfo::setSource(bool pIsDyn) {
81   if (pIsDyn)
82     m_BitField |= dynamic_flag;
83   else
84     m_BitField &= (~dynamic_flag);
85 }
86 
setInDyn()87 void ResolveInfo::setInDyn() {
88   m_BitField |= indyn_flag;
89 }
90 
setType(uint32_t pType)91 void ResolveInfo::setType(uint32_t pType) {
92   m_BitField &= ~TYPE_MASK;
93   m_BitField |= ((pType << TYPE_OFFSET) & TYPE_MASK);
94 }
95 
setDesc(uint32_t pDesc)96 void ResolveInfo::setDesc(uint32_t pDesc) {
97   m_BitField &= ~DESC_MASK;
98   m_BitField |= ((pDesc << DESC_OFFSET) & DESC_MASK);
99 }
100 
setBinding(uint32_t pBinding)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 
setReserved(uint32_t pReserved)109 void ResolveInfo::setReserved(uint32_t pReserved) {
110   m_BitField &= ~RESERVED_MASK;
111   m_BitField |= ((pReserved << RESERVED_OFFSET) & RESERVED_MASK);
112 }
113 
setOther(uint32_t pOther)114 void ResolveInfo::setOther(uint32_t pOther) {
115   setVisibility(static_cast<ResolveInfo::Visibility>(pOther & 0x3));
116 }
117 
setVisibility(ResolveInfo::Visibility pVisibility)118 void ResolveInfo::setVisibility(ResolveInfo::Visibility pVisibility) {
119   m_BitField &= ~VISIBILITY_MASK;
120   m_BitField |= pVisibility << VISIBILITY_OFFSET;
121 }
122 
setIsSymbol(bool pIsSymbol)123 void ResolveInfo::setIsSymbol(bool pIsSymbol) {
124   if (pIsSymbol)
125     m_BitField |= symbol_flag;
126   else
127     m_BitField &= ~symbol_flag;
128 }
129 
isNull() const130 bool ResolveInfo::isNull() const {
131   return (this == Null());
132 }
133 
isDyn() const134 bool ResolveInfo::isDyn() const {
135   return (dynamic_flag == (m_BitField & DYN_MASK));
136 }
137 
isUndef() const138 bool ResolveInfo::isUndef() const {
139   return (undefine_flag == (m_BitField & DESC_MASK));
140 }
141 
isDefine() const142 bool ResolveInfo::isDefine() const {
143   return (define_flag == (m_BitField & DESC_MASK));
144 }
145 
isCommon() const146 bool ResolveInfo::isCommon() const {
147   return (common_flag == (m_BitField & DESC_MASK));
148 }
149 
isIndirect() const150 bool ResolveInfo::isIndirect() const {
151   return (indirect_flag == (m_BitField & DESC_MASK));
152 }
153 
154 // isGlobal - [L,W] == [0, 0]
isGlobal() const155 bool ResolveInfo::isGlobal() const {
156   return (global_flag == (m_BitField & BINDING_MASK));
157 }
158 
159 // isWeak - [L,W] == [0, 1]
isWeak() const160 bool ResolveInfo::isWeak() const {
161   return (weak_flag == (m_BitField & BINDING_MASK));
162 }
163 
164 // isLocal - [L,W] == [1, 0]
isLocal() const165 bool ResolveInfo::isLocal() const {
166   return (local_flag == (m_BitField & BINDING_MASK));
167 }
168 
169 // isAbsolute - [L,W] == [1, 1]
isAbsolute() const170 bool ResolveInfo::isAbsolute() const {
171   return (absolute_flag == (m_BitField & BINDING_MASK));
172 }
173 
isSymbol() const174 bool ResolveInfo::isSymbol() const {
175   return (symbol_flag == (m_BitField & SYMBOL_MASK));
176 }
177 
isString() const178 bool ResolveInfo::isString() const {
179   return (string_flag == (m_BitField & SYMBOL_MASK));
180 }
181 
isInDyn() const182 bool ResolveInfo::isInDyn() const {
183   return (indyn_flag == (m_BitField & IN_DYN_MASK));
184 }
185 
type() const186 uint32_t ResolveInfo::type() const {
187   return (m_BitField & TYPE_MASK) >> TYPE_OFFSET;
188 }
189 
desc() const190 uint32_t ResolveInfo::desc() const {
191   return (m_BitField & DESC_MASK) >> DESC_OFFSET;
192 }
193 
binding() const194 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 
reserved() const204 uint32_t ResolveInfo::reserved() const {
205   return (m_BitField & RESERVED_MASK) >> RESERVED_OFFSET;
206 }
207 
visibility() const208 ResolveInfo::Visibility ResolveInfo::visibility() const {
209   return static_cast<ResolveInfo::Visibility>((m_BitField & VISIBILITY_MASK) >>
210                                               VISIBILITY_OFFSET);
211 }
212 
compare(const ResolveInfo::key_type & pKey)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 
shouldForceLocal(const LinkerConfig & pConfig)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 //===----------------------------------------------------------------------===//
Create(const ResolveInfo::key_type & pKey)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 
Destroy(ResolveInfo * & pInfo)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 
Null()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