1 //===- MCLDAttribute.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/MC/MCLDAttribute.h" 10 #include "mcld/MC/AttributeFactory.h" 11 12 using namespace mcld; 13 14 //========================== 15 // AttrConstraint 16 bool AttrConstraint::isLegal(const Attribute& pAttr, std::string &pErrMesg) const 17 { 18 if (!isWholeArchive() && pAttr.isWholeArchive()) { 19 pErrMesg = std::string("Target does not support --whole-archive"); 20 return false; 21 } 22 if (!isAsNeeded() && pAttr.isAsNeeded()) { 23 pErrMesg = std::string("Target does not support --as-needed"); 24 return false; 25 } 26 if (!isAddNeeded() && pAttr.isAddNeeded()) { 27 pErrMesg = std::string("Target does not support --add-needed"); 28 return false; 29 } 30 if (isStaticSystem() && pAttr.isDynamic()) { 31 pErrMesg = std::string("Target does not support --Bdynamic"); 32 return false; 33 } 34 // FIXME: may be it's legal, but ignored by GNU ld. 35 if (isStaticSystem() && pAttr.isAsNeeded()) { 36 pErrMesg = std::string("Can't enable --as-needed on a target which does not support dynamic linking"); 37 return false; 38 } 39 // FIXME: may be it's legal, but ignored by GNU ld. 40 if (pAttr.isAsNeeded() && pAttr.isStatic()) { 41 pErrMesg = std::string("Can't mix --static with --as-needed"); 42 return false; 43 } 44 return true; 45 } 46 47 //========================== 48 // AttributeProxy 49 AttributeProxy::AttributeProxy(AttributeFactory& pParent, Attribute& pBase) 50 : m_AttrPool(pParent), m_pBase(&pBase) { 51 } 52 53 AttributeProxy::~AttributeProxy() 54 { 55 } 56 57 bool AttributeProxy::isWholeArchive() const 58 { 59 if (m_AttrPool.constraint().isWholeArchive()) 60 return m_pBase->isWholeArchive(); 61 else 62 return false; 63 } 64 65 bool AttributeProxy::isAsNeeded() const 66 { 67 if (m_AttrPool.constraint().isAsNeeded()) 68 return m_pBase->isAsNeeded(); 69 else 70 return false; 71 } 72 73 bool AttributeProxy::isAddNeeded() const 74 { 75 if (m_AttrPool.constraint().isAddNeeded()) 76 return m_pBase->isAddNeeded(); 77 else 78 return false; 79 } 80 81 bool AttributeProxy::isStatic() const 82 { 83 if (m_AttrPool.constraint().isSharedSystem()) 84 return m_pBase->isStatic(); 85 else 86 return true; 87 } 88 89 bool AttributeProxy::isDynamic() const 90 { 91 if (m_AttrPool.constraint().isSharedSystem()) 92 return m_pBase->isDynamic(); 93 else 94 return false; 95 } 96 97 static inline void ReplaceOrRecord(AttributeFactory& pParent, 98 Attribute *&pBase, 99 Attribute *&pCopy) 100 { 101 Attribute *result = pParent.exists(*pCopy); 102 if (0 == result) { // can not find 103 pParent.record(*pCopy); 104 pBase = pCopy; 105 } 106 else { // find 107 delete pCopy; 108 pBase = result; 109 } 110 } 111 112 void AttributeProxy::setWholeArchive() 113 { 114 Attribute *copy = new Attribute(*m_pBase); 115 copy->setWholeArchive(); 116 ReplaceOrRecord(m_AttrPool, m_pBase, copy); 117 } 118 119 void AttributeProxy::unsetWholeArchive() 120 { 121 Attribute *copy = new Attribute(*m_pBase); 122 copy->unsetWholeArchive(); 123 ReplaceOrRecord(m_AttrPool, m_pBase, copy); 124 } 125 126 void AttributeProxy::setAsNeeded() 127 { 128 Attribute *copy = new Attribute(*m_pBase); 129 copy->setAsNeeded(); 130 ReplaceOrRecord(m_AttrPool, m_pBase, copy); 131 } 132 133 void AttributeProxy::unsetAsNeeded() 134 { 135 Attribute *copy = new Attribute(*m_pBase); 136 copy->unsetAsNeeded(); 137 ReplaceOrRecord(m_AttrPool, m_pBase, copy); 138 } 139 140 void AttributeProxy::setAddNeeded() 141 { 142 Attribute *copy = new Attribute(*m_pBase); 143 copy->setAddNeeded(); 144 ReplaceOrRecord(m_AttrPool, m_pBase, copy); 145 } 146 147 void AttributeProxy::unsetAddNeeded() 148 { 149 Attribute *copy = new Attribute(*m_pBase); 150 copy->unsetAddNeeded(); 151 ReplaceOrRecord(m_AttrPool, m_pBase, copy); 152 } 153 154 void AttributeProxy::setStatic() 155 { 156 Attribute *copy = new Attribute(*m_pBase); 157 copy->setStatic(); 158 ReplaceOrRecord(m_AttrPool, m_pBase, copy); 159 } 160 161 void AttributeProxy::setDynamic() 162 { 163 Attribute *copy = new Attribute(*m_pBase); 164 copy->setDynamic(); 165 ReplaceOrRecord(m_AttrPool, m_pBase, copy); 166 } 167 168 AttributeProxy* AttributeProxy::clone() const 169 { 170 return new AttributeProxy(m_AttrPool, *m_pBase); 171 } 172 173