• 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 <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