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