ResolveInfo.cpp revision 6f75755c9204b1d8817ae5a65a2f7e5af0ec3f70
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
13using namespace mcld;
14
15/// g_NullResolveInfo - a pointer to Null ResolveInfo.
16static ResolveInfo* g_NullResolveInfo = NULL;
17
18//===----------------------------------------------------------------------===//
19// ResolveInfo
20//===----------------------------------------------------------------------===//
21ResolveInfo::ResolveInfo()
22  : m_Size(0), m_BitField(0) {
23  m_Ptr.sym_ptr = 0;
24}
25
26ResolveInfo::~ResolveInfo()
27{
28}
29
30void ResolveInfo::override(const ResolveInfo& pFrom)
31{
32  m_Size = pFrom.m_Size;
33  overrideAttributes(pFrom);
34  overrideVisibility(pFrom);
35}
36
37void 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
45void 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
72void ResolveInfo::setRegular()
73{
74  m_BitField &= (~dynamic_flag);
75}
76
77void ResolveInfo::setDynamic()
78{
79  m_BitField |= dynamic_flag;
80}
81
82void ResolveInfo::setSource(bool pIsDyn)
83{
84  if (pIsDyn)
85    m_BitField |= dynamic_flag;
86  else
87    m_BitField &= (~dynamic_flag);
88}
89
90void ResolveInfo::setType(uint32_t pType)
91{
92  m_BitField &= ~TYPE_MASK;
93  m_BitField |= ((pType << TYPE_OFFSET) & TYPE_MASK);
94}
95
96void ResolveInfo::setDesc(uint32_t pDesc)
97{
98  m_BitField &= ~DESC_MASK;
99  m_BitField |= ((pDesc << DESC_OFFSET) & DESC_MASK);
100}
101
102void 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
111void ResolveInfo::setReserved(uint32_t pReserved)
112{
113  m_BitField &= ~RESERVED_MASK;
114  m_BitField |= ((pReserved << RESERVED_OFFSET) & RESERVED_MASK);
115}
116
117void ResolveInfo::setOther(uint32_t pOther)
118{
119  setVisibility(static_cast<ResolveInfo::Visibility>(pOther & 0x3));
120}
121
122void ResolveInfo::setVisibility(ResolveInfo::Visibility pVisibility)
123{
124  m_BitField &= ~VISIBILITY_MASK;
125  m_BitField |= pVisibility << VISIBILITY_OFFSET;
126}
127
128void ResolveInfo::setIsSymbol(bool pIsSymbol)
129{
130  if (pIsSymbol)
131    m_BitField |= symbol_flag;
132  else
133    m_BitField &= ~symbol_flag;
134}
135
136bool ResolveInfo::isNull() const
137{
138  return (this == Null());
139}
140
141bool ResolveInfo::isDyn() const
142{
143  return (dynamic_flag == (m_BitField & DYN_MASK));
144}
145
146bool ResolveInfo::isUndef() const
147{
148  return (undefine_flag == (m_BitField & DESC_MASK));
149}
150
151bool ResolveInfo::isDefine() const
152{
153  return (define_flag == (m_BitField & DESC_MASK));
154}
155
156bool ResolveInfo::isCommon() const
157{
158  return (common_flag == (m_BitField & DESC_MASK));
159}
160
161bool ResolveInfo::isIndirect() const
162{
163  return (indirect_flag == (m_BitField & DESC_MASK));
164}
165
166// isGlobal - [L,W] == [0, 0]
167bool ResolveInfo::isGlobal() const
168{
169  return (global_flag == (m_BitField & BINDING_MASK));
170}
171
172// isWeak - [L,W] == [0, 1]
173bool ResolveInfo::isWeak() const
174{
175  return (weak_flag == (m_BitField & BINDING_MASK));
176}
177
178// isLocal - [L,W] == [1, 0]
179bool ResolveInfo::isLocal() const
180{
181  return (local_flag == (m_BitField & BINDING_MASK));
182}
183
184// isAbsolute - [L,W] == [1, 1]
185bool ResolveInfo::isAbsolute() const
186{
187  return (absolute_flag == (m_BitField & BINDING_MASK));
188}
189
190bool ResolveInfo::isSymbol() const
191{
192  return (symbol_flag == (m_BitField & SYMBOL_MASK));
193}
194
195bool ResolveInfo::isString() const
196{
197  return (string_flag == (m_BitField & SYMBOL_MASK));
198}
199
200uint32_t ResolveInfo::type() const
201{
202  return (m_BitField & TYPE_MASK) >> TYPE_OFFSET;
203}
204
205uint32_t ResolveInfo::desc() const
206{
207  return (m_BitField & DESC_MASK) >> DESC_OFFSET;
208}
209
210uint32_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
221uint32_t ResolveInfo::reserved() const
222{
223  return (m_BitField & RESERVED_MASK) >> RESERVED_OFFSET;
224}
225
226ResolveInfo::Visibility ResolveInfo::visibility() const
227{
228  return static_cast<ResolveInfo::Visibility>((m_BitField & VISIBILITY_MASK) >> VISIBILITY_OFFSET);
229}
230
231bool 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//===----------------------------------------------------------------------===//
242ResolveInfo* 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
257void 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
270ResolveInfo* 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