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