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