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