• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- Attribute.h --------------------------------------------------------===//
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 #ifndef MCLD_ATTRIBUTE_H
10 #define MCLD_ATTRIBUTE_H
11 #ifdef ENABLE_UNITTEST
12 #include <gtest.h>
13 #endif
14 
15 namespace mcld {
16 
17 class AttributeSet;
18 
19 /** \class AttributeBase
20  *  \brief AttributeBase provides the real storage for attributes of options.
21  *
22  *  Attributes are options affecting the link editing of input files.
23  *  Some options affects the input files mentioned on the command line after
24  *  them. For example, --whole-archive option affects archives mentioned on
25  *  the command line after the --whole-archve option. We call such options
26  *  "attributes of input files"
27  *
28  *  AttributeBase is the storage for attributes of input files. Each input
29  *  file (@see mcld::Input in MCLinker) has a pointer of an attribute. Since
30  *  most attributes of input files are identical, our design lets input files
31  *  which have identical attributes share common attribute. AttributeBase is
32  *  the shared storage for attribute.
33  */
34 class AttributeBase
35 {
36 public:
AttributeBase()37   AttributeBase()
38   : m_WholeArchive(false),
39     m_AsNeeded(false),
40     m_AddNeeded(true),
41     m_Static(false)
42   { }
43 
AttributeBase(const AttributeBase & pBase)44   AttributeBase(const AttributeBase& pBase)
45   : m_WholeArchive(pBase.m_WholeArchive),
46     m_AsNeeded(pBase.m_AsNeeded),
47     m_AddNeeded(pBase.m_AddNeeded),
48     m_Static(pBase.m_Static)
49   { }
50 
~AttributeBase()51   virtual ~AttributeBase()
52   { }
53 
54   // ----- observers  ----- //
55   // represent GNU ld --whole-archive/--no-whole-archive options
isWholeArchive()56   bool isWholeArchive() const
57   { return m_WholeArchive; }
58 
59   // represent GNU ld --as-needed/--no-as-needed options
isAsNeeded()60   bool isAsNeeded() const
61   { return m_AsNeeded; }
62 
63   // represent GNU ld --add-needed/--no-add-needed options
isAddNeeded()64   bool isAddNeeded() const
65   { return m_AddNeeded; }
66 
67   // represent GNU ld -static option
isStatic()68   bool isStatic() const
69   { return m_Static; }
70 
71   // represent GNU ld -call_shared option
isDynamic()72   bool isDynamic() const
73   { return !m_Static; }
74 
75 public:
76   bool m_WholeArchive : 1;
77   bool m_AsNeeded : 1;
78   bool m_AddNeeded : 1;
79   bool m_Static : 1;
80 };
81 
82 /** \class Attribute
83  *  \brief The base class of attributes. Providing the raw operations of an
84  *  attributes
85  *
86  *  For conventience and producing less bugs, we move the stoarges of attributes
87  *  onto AttributeBase, and modifiers remains with the class Attribute.
88  */
89 class Attribute : public AttributeBase
90 {
91 public:
92   // -----  modifiers  ----- //
setWholeArchive()93   void setWholeArchive()
94   { m_WholeArchive = true; }
95 
unsetWholeArchive()96   void unsetWholeArchive()
97   { m_WholeArchive = false; }
98 
setAsNeeded()99   void setAsNeeded()
100   { m_AsNeeded = true; }
101 
unsetAsNeeded()102   void unsetAsNeeded()
103   { m_AsNeeded = false; }
104 
setAddNeeded()105   void setAddNeeded()
106   { m_AddNeeded = true; }
107 
unsetAddNeeded()108   void unsetAddNeeded()
109   { m_AddNeeded = false; }
110 
setStatic()111   void setStatic()
112   { m_Static = true; }
113 
setDynamic()114   void setDynamic()
115   { m_Static = false; }
116 };
117 
118 /** \class AttrConstraint
119  *  \brief AttrConstarint is the constraint of a system.
120  *
121  *  Some systems can not enable certain attributes of a input file.
122  *  For example, systems which have no shared libraries can not enable
123  *  --call_shared options. We call the ability of enabling attributes
124  *  as the constraint of attributes of a system.
125  *
126  *  Systems enable attributes at the target implementation of SectLinker.
127  *
128  *  @see SectLinker
129  */
130 class AttrConstraint : public AttributeBase
131 {
132 public:
enableWholeArchive()133   void enableWholeArchive()
134   { m_WholeArchive = true; }
135 
disableWholeArchive()136   void disableWholeArchive()
137   { m_WholeArchive = false; }
138 
enableAsNeeded()139   void enableAsNeeded()
140   { m_AsNeeded = true; }
141 
disableAsNeeded()142   void disableAsNeeded()
143   { m_AsNeeded = false; }
144 
enableAddNeeded()145   void enableAddNeeded()
146   { m_AddNeeded = true; }
147 
disableAddNeeded()148   void disableAddNeeded()
149   { m_AddNeeded = false; }
150 
setSharedSystem()151   void setSharedSystem()
152   { m_Static = false; }
153 
setStaticSystem()154   void setStaticSystem()
155   { m_Static = true; }
156 
isSharedSystem()157   bool isSharedSystem() const
158   { return !m_Static; }
159 
isStaticSystem()160   bool isStaticSystem() const
161   { return m_Static; }
162 
163   bool isLegal(const Attribute& pAttr) const;
164 };
165 
166 /** \class AttributeProxy
167  *  \brief AttributeProxys is the illusion of private attribute of each
168  *  input file.
169  *
170  *  We designers want to hide the details of sharing common attributes
171  *  between input files. We want input files under the illusion that they
172  *  have their own private attributes to simplify the linking algorithms.
173  *
174  *  AttributeProxy hides the reality of sharing. An input file can change
175  *  its attribute without explicit searching of existing attributes
176  *  as it has a private ownership of the attribute. AttributeProxy does
177  *  the searching in the AttributeSet and changes the pointer of
178  *  the attribute of the input file. If the searching fails, AttributeProxy
179  *  requests a new attribute from the AttributeSet.
180  */
181 class AttributeProxy
182 {
183 public:
184   AttributeProxy(AttributeSet& pParent,
185                  const Attribute& pBase,
186                  const AttrConstraint& pConstraint);
187 
188   ~AttributeProxy();
189 
190   // ----- observers  ----- //
191   bool isWholeArchive() const;
192 
193   bool isAsNeeded() const;
194 
195   bool isAddNeeded() const;
196 
197   bool isStatic() const;
198 
199   bool isDynamic() const;
200 
attr()201   const Attribute* attr() const
202   { return m_pBase; }
203 
204   // -----  modifiers  ----- //
205   void setWholeArchive();
206   void unsetWholeArchive();
207   void setAsNeeded();
208   void unsetAsNeeded();
209   void setAddNeeded();
210   void unsetAddNeeded();
211   void setStatic();
212   void setDynamic();
213 
214   AttributeProxy& assign(Attribute* pBase);
215 
216 private:
217   AttributeSet &m_AttrPool;
218   const Attribute *m_pBase;
219   const AttrConstraint& m_Constraint;
220 };
221 
222 
223 // -----  comparisons  ----- //
224 inline bool operator== (const Attribute& pLHS, const Attribute& pRHS)
225 {
226   return ((pLHS.isWholeArchive() == pRHS.isWholeArchive()) &&
227     (pLHS.isAsNeeded() == pRHS.isAsNeeded()) &&
228     (pLHS.isAddNeeded() == pRHS.isAddNeeded()) &&
229     (pLHS.isStatic() == pRHS.isStatic()));
230 }
231 
232 inline bool operator!= (const Attribute& pLHS, const Attribute& pRHS)
233 {
234   return !(pLHS == pRHS);
235 }
236 
237 } // namespace of mcld
238 
239 #endif
240 
241