• 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 <cstdlib>
11 #include <cstring>
12 
13 using namespace mcld;
14 
15 /// g_NullResolveInfo - a pointer to Null ResolveInfo.
16 static ResolveInfo* g_NullResolveInfo = NULL;
17 
18 //===----------------------------------------------------------------------===//
19 // ResolveInfo
20 //===----------------------------------------------------------------------===//
ResolveInfo()21 ResolveInfo::ResolveInfo()
22   : m_Size(0), m_BitField(0) {
23   m_Ptr.sym_ptr = 0;
24 }
25 
~ResolveInfo()26 ResolveInfo::~ResolveInfo()
27 {
28 }
29 
override(const ResolveInfo & pFrom)30 void ResolveInfo::override(const ResolveInfo& pFrom)
31 {
32   m_Size = pFrom.m_Size;
33   overrideAttributes(pFrom);
34   overrideVisibility(pFrom);
35 }
36 
overrideAttributes(const ResolveInfo & pFrom)37 void ResolveInfo::overrideAttributes(const ResolveInfo& pFrom)
38 {
39   m_BitField &= ~RESOLVE_MASK;
40   m_BitField |= (pFrom.m_BitField & RESOLVE_MASK);
41 }
42 
43 /// overrideVisibility - override the visibility
44 ///   always use the most strict visibility
overrideVisibility(const ResolveInfo & pFrom)45 void ResolveInfo::overrideVisibility(const ResolveInfo& pFrom)
46 {
47   // Reference: Google gold linker: resolve.cc
48   //
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 (0 != from_vis ) {
65     if (0 == cur_vis)
66       setVisibility(from_vis);
67     else if (cur_vis > from_vis)
68       setVisibility(from_vis);
69   }
70 }
71 
setRegular()72 void ResolveInfo::setRegular()
73 {
74   m_BitField &= (~dynamic_flag);
75 }
76 
setDynamic()77 void ResolveInfo::setDynamic()
78 {
79   m_BitField |= dynamic_flag;
80 }
81 
setSource(bool pIsDyn)82 void ResolveInfo::setSource(bool pIsDyn)
83 {
84   if (pIsDyn)
85     m_BitField |= dynamic_flag;
86   else
87     m_BitField &= (~dynamic_flag);
88 }
89 
setType(uint32_t pType)90 void ResolveInfo::setType(uint32_t pType)
91 {
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 {
98   m_BitField &= ~DESC_MASK;
99   m_BitField |= ((pDesc << DESC_OFFSET) & DESC_MASK);
100 }
101 
setBinding(uint32_t pBinding)102 void ResolveInfo::setBinding(uint32_t pBinding)
103 {
104   m_BitField &= ~BINDING_MASK;
105   if (pBinding == Local || pBinding == Absolute)
106     m_BitField |= local_flag;
107   if (pBinding == Weak || pBinding == Absolute)
108     m_BitField |= weak_flag;
109 }
110 
setReserved(uint32_t pReserved)111 void ResolveInfo::setReserved(uint32_t pReserved)
112 {
113   m_BitField &= ~RESERVED_MASK;
114   m_BitField |= ((pReserved << RESERVED_OFFSET) & RESERVED_MASK);
115 }
116 
setOther(uint32_t pOther)117 void ResolveInfo::setOther(uint32_t pOther)
118 {
119   setVisibility(static_cast<ResolveInfo::Visibility>(pOther & 0x3));
120 }
121 
setVisibility(ResolveInfo::Visibility pVisibility)122 void ResolveInfo::setVisibility(ResolveInfo::Visibility pVisibility)
123 {
124   m_BitField &= ~VISIBILITY_MASK;
125   m_BitField |= pVisibility << VISIBILITY_OFFSET;
126 }
127 
setIsSymbol(bool pIsSymbol)128 void ResolveInfo::setIsSymbol(bool pIsSymbol)
129 {
130   if (pIsSymbol)
131     m_BitField |= symbol_flag;
132   else
133     m_BitField &= ~symbol_flag;
134 }
135 
isNull() const136 bool ResolveInfo::isNull() const
137 {
138   return (this == Null());
139 }
140 
isDyn() const141 bool ResolveInfo::isDyn() const
142 {
143   return (dynamic_flag == (m_BitField & DYN_MASK));
144 }
145 
isUndef() const146 bool ResolveInfo::isUndef() const
147 {
148   return (undefine_flag == (m_BitField & DESC_MASK));
149 }
150 
isDefine() const151 bool ResolveInfo::isDefine() const
152 {
153   return (define_flag == (m_BitField & DESC_MASK));
154 }
155 
isCommon() const156 bool ResolveInfo::isCommon() const
157 {
158   return (common_flag == (m_BitField & DESC_MASK));
159 }
160 
isIndirect() const161 bool ResolveInfo::isIndirect() const
162 {
163   return (indirect_flag == (m_BitField & DESC_MASK));
164 }
165 
166 // isGlobal - [L,W] == [0, 0]
isGlobal() const167 bool ResolveInfo::isGlobal() const
168 {
169   return (global_flag == (m_BitField & BINDING_MASK));
170 }
171 
172 // isWeak - [L,W] == [0, 1]
isWeak() const173 bool ResolveInfo::isWeak() const
174 {
175   return (weak_flag == (m_BitField & BINDING_MASK));
176 }
177 
178 // isLocal - [L,W] == [1, 0]
isLocal() const179 bool ResolveInfo::isLocal() const
180 {
181   return (local_flag == (m_BitField & BINDING_MASK));
182 }
183 
184 // isAbsolute - [L,W] == [1, 1]
isAbsolute() const185 bool ResolveInfo::isAbsolute() const
186 {
187   return (absolute_flag == (m_BitField & BINDING_MASK));
188 }
189 
isSymbol() const190 bool ResolveInfo::isSymbol() const
191 {
192   return (symbol_flag == (m_BitField & SYMBOL_MASK));
193 }
194 
isString() const195 bool ResolveInfo::isString() const
196 {
197   return (string_flag == (m_BitField & SYMBOL_MASK));
198 }
199 
type() const200 uint32_t ResolveInfo::type() const
201 {
202   return (m_BitField & TYPE_MASK) >> TYPE_OFFSET;
203 }
204 
desc() const205 uint32_t ResolveInfo::desc() const
206 {
207   return (m_BitField & DESC_MASK) >> DESC_OFFSET;
208 }
209 
binding() const210 uint32_t ResolveInfo::binding() const
211 {
212   if (m_BitField & LOCAL_MASK) {
213     if (m_BitField & GLOBAL_MASK) {
214       return ResolveInfo::Absolute;
215     }
216     return ResolveInfo::Local;
217   }
218   return m_BitField & GLOBAL_MASK;
219 }
220 
reserved() const221 uint32_t ResolveInfo::reserved() const
222 {
223   return (m_BitField & RESERVED_MASK) >> RESERVED_OFFSET;
224 }
225 
visibility() const226 ResolveInfo::Visibility ResolveInfo::visibility() const
227 {
228   return static_cast<ResolveInfo::Visibility>((m_BitField & VISIBILITY_MASK) >> VISIBILITY_OFFSET);
229 }
230 
compare(const ResolveInfo::key_type & pKey)231 bool ResolveInfo::compare(const ResolveInfo::key_type& pKey)
232 {
233   size_t length = nameSize();
234   if (length != pKey.size())
235     return false;
236   return (0 == std::memcmp(m_Name, pKey.data(), length));
237 }
238 
239 //===----------------------------------------------------------------------===//
240 // ResolveInfo Factory Methods
241 //===----------------------------------------------------------------------===//
Create(const ResolveInfo::key_type & pKey)242 ResolveInfo* ResolveInfo::Create(const ResolveInfo::key_type& pKey)
243 {
244   ResolveInfo* result = static_cast<ResolveInfo*>(
245                           malloc(sizeof(ResolveInfo)+pKey.size()+1));
246   if (NULL == result)
247     return NULL;
248 
249   new (result) ResolveInfo();
250   std::memcpy(result->m_Name, pKey.data(), pKey.size());
251   result->m_Name[pKey.size()] = '\0';
252   result->m_BitField &= ~ResolveInfo::RESOLVE_MASK;
253   result->m_BitField |= (pKey.size() << ResolveInfo::NAME_LENGTH_OFFSET);
254   return result;
255 }
256 
Destroy(ResolveInfo * & pInfo)257 void ResolveInfo::Destroy(ResolveInfo*& pInfo)
258 {
259   if (pInfo->isNull())
260     return;
261 
262   if (NULL != pInfo) {
263     pInfo->~ResolveInfo();
264     free(pInfo);
265   }
266 
267   pInfo = NULL;
268 }
269 
Null()270 ResolveInfo* ResolveInfo::Null()
271 {
272   if (NULL == g_NullResolveInfo) {
273     g_NullResolveInfo = static_cast<ResolveInfo*>(
274                           malloc(sizeof(ResolveInfo) + 1));
275     new (g_NullResolveInfo) ResolveInfo();
276     g_NullResolveInfo->m_Name[0] = '\0';
277     g_NullResolveInfo->m_BitField = 0x0;
278     g_NullResolveInfo->setBinding(Local);
279   }
280   return g_NullResolveInfo;
281 }
282 
283