• 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 #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 //===----------------------------------------------------------------------===//
ResolveInfo()24 ResolveInfo::ResolveInfo()
25   : m_Size(0), m_BitField(0) {
26   m_Ptr.sym_ptr = 0;
27 }
28 
~ResolveInfo()29 ResolveInfo::~ResolveInfo()
30 {
31 }
32 
override(const ResolveInfo & pFrom)33 void ResolveInfo::override(const ResolveInfo& pFrom)
34 {
35   m_Size = pFrom.m_Size;
36   overrideAttributes(pFrom);
37   overrideVisibility(pFrom);
38 }
39 
overrideAttributes(const ResolveInfo & pFrom)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
overrideVisibility(const ResolveInfo & pFrom)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 
setRegular()75 void ResolveInfo::setRegular()
76 {
77   m_BitField &= (~dynamic_flag);
78 }
79 
setDynamic()80 void ResolveInfo::setDynamic()
81 {
82   m_BitField |= dynamic_flag;
83 }
84 
setSource(bool pIsDyn)85 void ResolveInfo::setSource(bool pIsDyn)
86 {
87   if (pIsDyn)
88     m_BitField |= dynamic_flag;
89   else
90     m_BitField &= (~dynamic_flag);
91 }
92 
setType(uint32_t pType)93 void ResolveInfo::setType(uint32_t pType)
94 {
95   m_BitField &= ~TYPE_MASK;
96   m_BitField |= ((pType << TYPE_OFFSET) & TYPE_MASK);
97 }
98 
setDesc(uint32_t pDesc)99 void ResolveInfo::setDesc(uint32_t pDesc)
100 {
101   m_BitField &= ~DESC_MASK;
102   m_BitField |= ((pDesc << DESC_OFFSET) & DESC_MASK);
103 }
104 
setBinding(uint32_t pBinding)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 
setReserved(uint32_t pReserved)114 void ResolveInfo::setReserved(uint32_t pReserved)
115 {
116   m_BitField &= ~RESERVED_MASK;
117   m_BitField |= ((pReserved << RESERVED_OFFSET) & RESERVED_MASK);
118 }
119 
setOther(uint32_t pOther)120 void ResolveInfo::setOther(uint32_t pOther)
121 {
122   setVisibility(static_cast<ResolveInfo::Visibility>(pOther & 0x3));
123 }
124 
setVisibility(ResolveInfo::Visibility pVisibility)125 void ResolveInfo::setVisibility(ResolveInfo::Visibility pVisibility)
126 {
127   m_BitField &= ~VISIBILITY_MASK;
128   m_BitField |= pVisibility << VISIBILITY_OFFSET;
129 }
130 
setIsSymbol(bool pIsSymbol)131 void ResolveInfo::setIsSymbol(bool pIsSymbol)
132 {
133   if (pIsSymbol)
134     m_BitField |= symbol_flag;
135   else
136     m_BitField &= ~symbol_flag;
137 }
138 
isNull() const139 bool ResolveInfo::isNull() const
140 {
141   return (this == Null());
142 }
143 
isDyn() const144 bool ResolveInfo::isDyn() const
145 {
146   return (dynamic_flag == (m_BitField & DYN_MASK));
147 }
148 
isUndef() const149 bool ResolveInfo::isUndef() const
150 {
151   return (undefine_flag == (m_BitField & DESC_MASK));
152 }
153 
isDefine() const154 bool ResolveInfo::isDefine() const
155 {
156   return (define_flag == (m_BitField & DESC_MASK));
157 }
158 
isCommon() const159 bool ResolveInfo::isCommon() const
160 {
161   return (common_flag == (m_BitField & DESC_MASK));
162 }
163 
isIndirect() const164 bool ResolveInfo::isIndirect() const
165 {
166   return (indirect_flag == (m_BitField & DESC_MASK));
167 }
168 
169 // isGlobal - [L,W] == [0, 0]
isGlobal() const170 bool ResolveInfo::isGlobal() const
171 {
172   return (global_flag == (m_BitField & BINDING_MASK));
173 }
174 
175 // isWeak - [L,W] == [0, 1]
isWeak() const176 bool ResolveInfo::isWeak() const
177 {
178   return (weak_flag == (m_BitField & BINDING_MASK));
179 }
180 
181 // isLocal - [L,W] == [1, 0]
isLocal() const182 bool ResolveInfo::isLocal() const
183 {
184   return (local_flag == (m_BitField & BINDING_MASK));
185 }
186 
187 // isAbsolute - [L,W] == [1, 1]
isAbsolute() const188 bool ResolveInfo::isAbsolute() const
189 {
190   return (absolute_flag == (m_BitField & BINDING_MASK));
191 }
192 
isSymbol() const193 bool ResolveInfo::isSymbol() const
194 {
195   return (symbol_flag == (m_BitField & SYMBOL_MASK));
196 }
197 
isString() const198 bool ResolveInfo::isString() const
199 {
200   return (string_flag == (m_BitField & SYMBOL_MASK));
201 }
202 
type() const203 uint32_t ResolveInfo::type() const
204 {
205   return (m_BitField & TYPE_MASK) >> TYPE_OFFSET;
206 }
207 
desc() const208 uint32_t ResolveInfo::desc() const
209 {
210   return (m_BitField & DESC_MASK) >> DESC_OFFSET;
211 }
212 
binding() const213 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 
reserved() const224 uint32_t ResolveInfo::reserved() const
225 {
226   return (m_BitField & RESERVED_MASK) >> RESERVED_OFFSET;
227 }
228 
visibility() const229 ResolveInfo::Visibility ResolveInfo::visibility() const
230 {
231   return static_cast<ResolveInfo::Visibility>((m_BitField & VISIBILITY_MASK) >> VISIBILITY_OFFSET);
232 }
233 
compare(const ResolveInfo::key_type & pKey)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 //===----------------------------------------------------------------------===//
Create(const ResolveInfo::key_type & pKey)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 
Destroy(ResolveInfo * & pInfo)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 
Null()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