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