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
12using namespace mcld;
13
14//==========================
15// ResolveInfo
16ResolveInfo::ResolveInfo()
17  : m_Size(0), m_BitField(0) {
18  m_Ptr.sym_ptr = 0;
19}
20
21ResolveInfo::~ResolveInfo()
22{
23}
24
25void ResolveInfo::override(const ResolveInfo& pFrom)
26{
27  m_Size = pFrom.m_Size;
28  overrideAttributes(pFrom);
29  overrideVisibility(pFrom);
30}
31
32void 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
40void 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
67void ResolveInfo::setRegular()
68{
69  m_BitField &= (~dynamic_flag);
70}
71
72void ResolveInfo::setDynamic()
73{
74  m_BitField |= dynamic_flag;
75}
76
77void ResolveInfo::setSource(bool pIsDyn)
78{
79  if (pIsDyn)
80    m_BitField |= dynamic_flag;
81  else
82    m_BitField &= (~dynamic_flag);
83}
84
85void ResolveInfo::setType(uint32_t pType)
86{
87  m_BitField &= ~TYPE_MASK;
88  m_BitField |= ((pType << TYPE_OFFSET) & TYPE_MASK);
89}
90
91void ResolveInfo::setDesc(uint32_t pDesc)
92{
93  m_BitField &= ~DESC_MASK;
94  m_BitField |= ((pDesc << DESC_OFFSET) & DESC_MASK);
95}
96
97void 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
106void ResolveInfo::setReserved(uint32_t pReserved)
107{
108  m_BitField &= ~RESERVED_MASK;
109  m_BitField |= ((pReserved << RESERVED_OFFSET) & RESERVED_MASK);
110}
111
112void ResolveInfo::setOther(uint32_t pOther)
113{
114  setVisibility(static_cast<ResolveInfo::Visibility>(pOther & 0x3));
115}
116
117void ResolveInfo::setVisibility(ResolveInfo::Visibility pVisibility)
118{
119  m_BitField &= ~VISIBILITY_MASK;
120  m_BitField |= pVisibility << VISIBILITY_OFFSET;
121}
122
123void ResolveInfo::setIsSymbol(bool pIsSymbol)
124{
125  if (pIsSymbol)
126    m_BitField |= symbol_flag;
127  else
128    m_BitField &= ~symbol_flag;
129}
130
131bool ResolveInfo::isDyn() const
132{
133  return (dynamic_flag == (m_BitField & DYN_MASK));
134}
135
136bool ResolveInfo::isUndef() const
137{
138  return (undefine_flag == (m_BitField & DESC_MASK));
139}
140
141bool ResolveInfo::isDefine() const
142{
143  return (define_flag == (m_BitField & DESC_MASK));
144}
145
146bool ResolveInfo::isCommon() const
147{
148  return (common_flag == (m_BitField & DESC_MASK));
149}
150
151bool ResolveInfo::isIndirect() const
152{
153  return (indirect_flag == (m_BitField & DESC_MASK));
154}
155
156// isGlobal - [L,W] == [0, 0]
157bool ResolveInfo::isGlobal() const
158{
159  return (global_flag == (m_BitField & BINDING_MASK));
160}
161
162// isWeak - [L,W] == [0, 1]
163bool ResolveInfo::isWeak() const
164{
165  return (weak_flag == (m_BitField & BINDING_MASK));
166}
167
168// isLocal - [L,W] == [1, 0]
169bool ResolveInfo::isLocal() const
170{
171  return (local_flag == (m_BitField & BINDING_MASK));
172}
173
174// isAbsolute - [L,W] == [1, 1]
175bool ResolveInfo::isAbsolute() const
176{
177  return (absolute_flag == (m_BitField & BINDING_MASK));
178}
179
180bool ResolveInfo::isSymbol() const
181{
182  return (symbol_flag == (m_BitField & SYMBOL_MASK));
183}
184
185bool ResolveInfo::isString() const
186{
187  return (string_flag == (m_BitField & SYMBOL_MASK));
188}
189
190uint32_t ResolveInfo::type() const
191{
192  return (m_BitField & TYPE_MASK) >> TYPE_OFFSET;
193}
194
195uint32_t ResolveInfo::desc() const
196{
197  return (m_BitField & DESC_MASK) >> DESC_OFFSET;
198}
199
200uint32_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
211uint32_t ResolveInfo::reserved() const
212{
213  return (m_BitField & RESERVED_MASK) >> RESERVED_OFFSET;
214}
215
216ResolveInfo::Visibility ResolveInfo::visibility() const
217{
218  return static_cast<ResolveInfo::Visibility>((m_BitField & VISIBILITY_MASK) >> VISIBILITY_OFFSET);
219}
220
221bool 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