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 <cstring>
11
12 using namespace mcld;
13
14 //==========================
15 // ResolveInfo
ResolveInfo()16 ResolveInfo::ResolveInfo()
17 : m_Size(0), m_BitField(0) {
18 m_Ptr.sym_ptr = 0;
19 }
20
~ResolveInfo()21 ResolveInfo::~ResolveInfo()
22 {
23 }
24
override(const ResolveInfo & pFrom)25 void ResolveInfo::override(const ResolveInfo& pFrom)
26 {
27 m_Size = pFrom.m_Size;
28 overrideAttributes(pFrom);
29 overrideVisibility(pFrom);
30 }
31
overrideAttributes(const ResolveInfo & pFrom)32 void ResolveInfo::overrideAttributes(const ResolveInfo& pFrom)
33 {
34 m_BitField &= ~RESOLVE_MASK;
35 m_BitField |= (pFrom.m_BitField & RESOLVE_MASK);
36 }
37
38 /// overrideVisibility - override the visibility
39 /// always use the most strict visibility
overrideVisibility(const ResolveInfo & pFrom)40 void ResolveInfo::overrideVisibility(const ResolveInfo& pFrom)
41 {
42 // Reference: Google gold linker: resolve.cc
43 //
44 // The rule for combining visibility is that we always choose the
45 // most constrained visibility. In order of increasing constraint,
46 // visibility goes PROTECTED, HIDDEN, INTERNAL. This is the reverse
47 // of the numeric values, so the effect is that we always want the
48 // smallest non-zero value.
49 //
50 // enum {
51 // STV_DEFAULT = 0,
52 // STV_INTERNAL = 1,
53 // STV_HIDDEN = 2,
54 // STV_PROTECTED = 3
55 // };
56
57 Visibility from_vis = pFrom.visibility();
58 Visibility cur_vis = visibility();
59 if (0 != from_vis ) {
60 if (0 == cur_vis)
61 setVisibility(from_vis);
62 else if (cur_vis > from_vis)
63 setVisibility(from_vis);
64 }
65 }
66
setRegular()67 void ResolveInfo::setRegular()
68 {
69 m_BitField &= (~dynamic_flag);
70 }
71
setDynamic()72 void ResolveInfo::setDynamic()
73 {
74 m_BitField |= dynamic_flag;
75 }
76
setSource(bool pIsDyn)77 void ResolveInfo::setSource(bool pIsDyn)
78 {
79 if (pIsDyn)
80 m_BitField |= dynamic_flag;
81 else
82 m_BitField &= (~dynamic_flag);
83 }
84
setType(uint32_t pType)85 void ResolveInfo::setType(uint32_t pType)
86 {
87 m_BitField &= ~TYPE_MASK;
88 m_BitField |= ((pType << TYPE_OFFSET) & TYPE_MASK);
89 }
90
setDesc(uint32_t pDesc)91 void ResolveInfo::setDesc(uint32_t pDesc)
92 {
93 m_BitField &= ~DESC_MASK;
94 m_BitField |= ((pDesc << DESC_OFFSET) & DESC_MASK);
95 }
96
setBinding(uint32_t pBinding)97 void ResolveInfo::setBinding(uint32_t pBinding)
98 {
99 m_BitField &= ~BINDING_MASK;
100 if (pBinding == Local || pBinding == Absolute)
101 m_BitField |= local_flag;
102 if (pBinding == Weak || pBinding == Absolute)
103 m_BitField |= weak_flag;
104 }
105
setReserved(uint32_t pReserved)106 void ResolveInfo::setReserved(uint32_t pReserved)
107 {
108 m_BitField &= ~RESERVED_MASK;
109 m_BitField |= ((pReserved << RESERVED_OFFSET) & RESERVED_MASK);
110 }
111
setOther(uint32_t pOther)112 void ResolveInfo::setOther(uint32_t pOther)
113 {
114 setVisibility(static_cast<ResolveInfo::Visibility>(pOther & 0x3));
115 }
116
setVisibility(ResolveInfo::Visibility pVisibility)117 void ResolveInfo::setVisibility(ResolveInfo::Visibility pVisibility)
118 {
119 m_BitField &= ~VISIBILITY_MASK;
120 m_BitField |= pVisibility << VISIBILITY_OFFSET;
121 }
122
setIsSymbol(bool pIsSymbol)123 void ResolveInfo::setIsSymbol(bool pIsSymbol)
124 {
125 if (pIsSymbol)
126 m_BitField |= symbol_flag;
127 else
128 m_BitField &= ~symbol_flag;
129 }
130
isDyn() const131 bool ResolveInfo::isDyn() const
132 {
133 return (dynamic_flag == (m_BitField & DYN_MASK));
134 }
135
isUndef() const136 bool ResolveInfo::isUndef() const
137 {
138 return (undefine_flag == (m_BitField & DESC_MASK));
139 }
140
isDefine() const141 bool ResolveInfo::isDefine() const
142 {
143 return (define_flag == (m_BitField & DESC_MASK));
144 }
145
isCommon() const146 bool ResolveInfo::isCommon() const
147 {
148 return (common_flag == (m_BitField & DESC_MASK));
149 }
150
isIndirect() const151 bool ResolveInfo::isIndirect() const
152 {
153 return (indirect_flag == (m_BitField & DESC_MASK));
154 }
155
156 // isGlobal - [L,W] == [0, 0]
isGlobal() const157 bool ResolveInfo::isGlobal() const
158 {
159 return (global_flag == (m_BitField & BINDING_MASK));
160 }
161
162 // isWeak - [L,W] == [0, 1]
isWeak() const163 bool ResolveInfo::isWeak() const
164 {
165 return (weak_flag == (m_BitField & BINDING_MASK));
166 }
167
168 // isLocal - [L,W] == [1, 0]
isLocal() const169 bool ResolveInfo::isLocal() const
170 {
171 return (local_flag == (m_BitField & BINDING_MASK));
172 }
173
174 // isAbsolute - [L,W] == [1, 1]
isAbsolute() const175 bool ResolveInfo::isAbsolute() const
176 {
177 return (absolute_flag == (m_BitField & BINDING_MASK));
178 }
179
isSymbol() const180 bool ResolveInfo::isSymbol() const
181 {
182 return (symbol_flag == (m_BitField & SYMBOL_MASK));
183 }
184
isString() const185 bool ResolveInfo::isString() const
186 {
187 return (string_flag == (m_BitField & SYMBOL_MASK));
188 }
189
type() const190 uint32_t ResolveInfo::type() const
191 {
192 return (m_BitField & TYPE_MASK) >> TYPE_OFFSET;
193 }
194
desc() const195 uint32_t ResolveInfo::desc() const
196 {
197 return (m_BitField & DESC_MASK) >> DESC_OFFSET;
198 }
199
binding() const200 uint32_t ResolveInfo::binding() const
201 {
202 if (m_BitField & LOCAL_MASK) {
203 if (m_BitField & GLOBAL_MASK) {
204 return ResolveInfo::Absolute;
205 }
206 return ResolveInfo::Local;
207 }
208 return m_BitField & GLOBAL_MASK;
209 }
210
reserved() const211 uint32_t ResolveInfo::reserved() const
212 {
213 return (m_BitField & RESERVED_MASK) >> RESERVED_OFFSET;
214 }
215
visibility() const216 ResolveInfo::Visibility ResolveInfo::visibility() const
217 {
218 return static_cast<ResolveInfo::Visibility>((m_BitField & VISIBILITY_MASK) >> VISIBILITY_OFFSET);
219 }
220
compare(const ResolveInfo::key_type & pKey)221 bool ResolveInfo::compare(const ResolveInfo::key_type& pKey)
222 {
223 size_t length = nameSize();
224 if (length != pKey.size())
225 return false;
226 return (0 == std::memcmp(m_Name, pKey.data(), length));
227 }
228
229