1 //===- Operand.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/Script/Operand.h> 10 #include <mcld/Support/raw_ostream.h> 11 #include <mcld/Support/GCFactory.h> 12 #include <mcld/LD/LDSection.h> 13 #include <mcld/LD/SectionData.h> 14 #include <mcld/Fragment/Fragment.h> 15 #include <llvm/Support/ManagedStatic.h> 16 17 using namespace mcld; 18 19 //===----------------------------------------------------------------------===// 20 // Operand 21 //===----------------------------------------------------------------------===// 22 Operand::Operand(Type pType) 23 : ExprToken(ExprToken::OPERAND), m_Type(pType) 24 { 25 } 26 27 Operand::~Operand() 28 { 29 } 30 31 //===----------------------------------------------------------------------===// 32 // SymOperand 33 //===----------------------------------------------------------------------===// 34 typedef GCFactory<SymOperand, MCLD_SYMBOLS_PER_INPUT> SymOperandFactory; 35 static llvm::ManagedStatic<SymOperandFactory> g_SymOperandFactory; 36 37 SymOperand::SymOperand() 38 : Operand(Operand::SYMBOL), m_Value(0) 39 { 40 } 41 42 SymOperand::SymOperand(const std::string& pName) 43 : Operand(Operand::SYMBOL), m_Name(pName), m_Value(0) 44 { 45 } 46 47 void SymOperand::dump() const 48 { 49 mcld::outs() << m_Name; 50 } 51 52 bool SymOperand::isDot() const 53 { 54 assert(!m_Name.empty()); 55 return m_Name.size() == 1 && m_Name[0] == '.'; 56 } 57 58 SymOperand* SymOperand::create(const std::string& pName) 59 { 60 SymOperand* result = g_SymOperandFactory->allocate(); 61 new (result) SymOperand(pName); 62 return result; 63 } 64 65 void SymOperand::destroy(SymOperand*& pOperand) 66 { 67 g_SymOperandFactory->destroy(pOperand); 68 g_SymOperandFactory->deallocate(pOperand); 69 pOperand = NULL; 70 } 71 72 void SymOperand::clear() 73 { 74 g_SymOperandFactory->clear(); 75 } 76 77 //===----------------------------------------------------------------------===// 78 // IntOperand 79 //===----------------------------------------------------------------------===// 80 typedef GCFactory<IntOperand, MCLD_SYMBOLS_PER_INPUT> IntOperandFactory; 81 static llvm::ManagedStatic<IntOperandFactory> g_IntOperandFactory; 82 83 IntOperand::IntOperand() 84 : Operand(Operand::INTEGER), m_Value(0) 85 { 86 } 87 88 IntOperand::IntOperand(uint64_t pValue) 89 : Operand(Operand::INTEGER), m_Value(pValue) 90 { 91 } 92 93 void IntOperand::dump() const 94 { 95 mcld::outs() << m_Value; 96 } 97 98 IntOperand* IntOperand::create(uint64_t pValue) 99 { 100 IntOperand* result = g_IntOperandFactory->allocate(); 101 new (result) IntOperand(pValue); 102 return result; 103 } 104 105 void IntOperand::destroy(IntOperand*& pOperand) 106 { 107 g_IntOperandFactory->destroy(pOperand); 108 g_IntOperandFactory->deallocate(pOperand); 109 pOperand = NULL; 110 } 111 112 void IntOperand::clear() 113 { 114 g_IntOperandFactory->clear(); 115 } 116 117 //===----------------------------------------------------------------------===// 118 // SectOperand 119 //===----------------------------------------------------------------------===// 120 typedef GCFactory<SectOperand, MCLD_SECTIONS_PER_INPUT> SectOperandFactory; 121 static llvm::ManagedStatic<SectOperandFactory> g_SectOperandFactory; 122 SectOperand::SectOperand() 123 : Operand(Operand::SECTION) 124 { 125 } 126 127 SectOperand::SectOperand(const std::string& pName) 128 : Operand(Operand::SECTION), m_Name(pName) 129 { 130 } 131 132 void SectOperand::dump() const 133 { 134 mcld::outs() << m_Name; 135 } 136 137 SectOperand* SectOperand::create(const std::string& pName) 138 { 139 SectOperand* result = g_SectOperandFactory->allocate(); 140 new (result) SectOperand(pName); 141 return result; 142 } 143 144 void SectOperand::destroy(SectOperand*& pOperand) 145 { 146 g_SectOperandFactory->destroy(pOperand); 147 g_SectOperandFactory->deallocate(pOperand); 148 pOperand = NULL; 149 } 150 151 void SectOperand::clear() 152 { 153 g_SectOperandFactory->clear(); 154 } 155 156 //===----------------------------------------------------------------------===// 157 // SectDescOperand 158 //===----------------------------------------------------------------------===// 159 typedef GCFactory<SectDescOperand, 160 MCLD_SECTIONS_PER_INPUT> SectDescOperandFactory; 161 static llvm::ManagedStatic<SectDescOperandFactory> g_SectDescOperandFactory; 162 SectDescOperand::SectDescOperand() 163 : Operand(Operand::SECTION_DESC), m_pOutputDesc(NULL) 164 { 165 } 166 167 SectDescOperand::SectDescOperand(const SectionMap::Output* pOutputDesc) 168 : Operand(Operand::SECTION_DESC), m_pOutputDesc(pOutputDesc) 169 { 170 } 171 172 void SectDescOperand::dump() const 173 { 174 assert(m_pOutputDesc != NULL); 175 mcld::outs() << m_pOutputDesc->getSection()->name(); 176 } 177 178 SectDescOperand* SectDescOperand::create(const SectionMap::Output* pOutputDesc) 179 { 180 SectDescOperand* result = g_SectDescOperandFactory->allocate(); 181 new (result) SectDescOperand(pOutputDesc); 182 return result; 183 } 184 185 void SectDescOperand::destroy(SectDescOperand*& pOperand) 186 { 187 g_SectDescOperandFactory->destroy(pOperand); 188 g_SectDescOperandFactory->deallocate(pOperand); 189 pOperand = NULL; 190 } 191 192 void SectDescOperand::clear() 193 { 194 g_SectDescOperandFactory->clear(); 195 } 196 197 //===----------------------------------------------------------------------===// 198 // FragOperand 199 //===----------------------------------------------------------------------===// 200 typedef GCFactory<FragOperand, MCLD_SYMBOLS_PER_INPUT> FragOperandFactory; 201 static llvm::ManagedStatic<FragOperandFactory> g_FragOperandFactory; 202 203 FragOperand::FragOperand() 204 : Operand(Operand::FRAGMENT), m_pFragment(NULL) 205 { 206 } 207 208 FragOperand::FragOperand(Fragment& pFragment) 209 : Operand(Operand::FRAGMENT), m_pFragment(&pFragment) 210 { 211 } 212 213 void FragOperand::dump() const 214 { 215 mcld::outs() << "fragment"; 216 } 217 218 uint64_t FragOperand::value() const 219 { 220 return m_pFragment->getOffset() + 221 m_pFragment->getParent()->getSection().addr(); 222 } 223 224 FragOperand* FragOperand::create(Fragment& pFragment) 225 { 226 FragOperand* result = g_FragOperandFactory->allocate(); 227 new (result) FragOperand(pFragment); 228 return result; 229 } 230 231 void FragOperand::destroy(FragOperand*& pOperand) 232 { 233 g_FragOperandFactory->destroy(pOperand); 234 g_FragOperandFactory->deallocate(pOperand); 235 pOperand = NULL; 236 } 237 238 void FragOperand::clear() 239 { 240 g_FragOperandFactory->clear(); 241 } 242