1//===- NamePool.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 <llvm/Support/raw_ostream.h> 10#include <mcld/LD/NamePool.h> 11#include <mcld/LD/Resolver.h> 12 13using namespace mcld; 14 15//========================== 16// NamePool 17NamePool::NamePool(const Resolver& pResolver, NamePool::size_type pSize) 18 : m_pResolver(&pResolver), m_Table(pSize) { 19} 20 21NamePool::~NamePool() 22{ 23} 24 25/// createSymbol - create a symbol 26ResolveInfo* NamePool::createSymbol(const llvm::StringRef& pName, 27 bool pIsDyn, 28 ResolveInfo::Type pType, 29 ResolveInfo::Desc pDesc, 30 ResolveInfo::Binding pBinding, 31 ResolveInfo::SizeType pSize, 32 ResolveInfo::Visibility pVisibility) 33{ 34 ResolveInfo* result = m_Table.getEntryFactory().produce(pName); 35 result->setIsSymbol(true); 36 result->setSource(pIsDyn); 37 result->setType(pType); 38 result->setDesc(pDesc); 39 result->setBinding(pBinding); 40 result->setVisibility(pVisibility); 41 result->setSize(pSize); 42 return result; 43} 44 45/// insertSymbol - insert a symbol and resolve it immediately 46/// @return the pointer of resolved ResolveInfo 47/// @return is the symbol existent? 48void NamePool::insertSymbol(const llvm::StringRef& pName, 49 bool pIsDyn, 50 ResolveInfo::Type pType, 51 ResolveInfo::Desc pDesc, 52 ResolveInfo::Binding pBinding, 53 ResolveInfo::SizeType pSize, 54 ResolveInfo::Visibility pVisibility, 55 ResolveInfo* pOldInfo, 56 Resolver::Result& pResult) 57{ 58 // We should check if there is any symbol with the same name existed. 59 // If it already exists, we should use resolver to decide which symbol 60 // should be reserved. Otherwise, we insert the symbol and set up its 61 // attributes. 62 bool exist = false; 63 ResolveInfo* old_symbol = m_Table.insert(pName, exist); 64 ResolveInfo* new_symbol = NULL; 65 if (exist && old_symbol->isSymbol()) { 66 exist = true; 67 new_symbol = m_Table.getEntryFactory().produce(pName); 68 } 69 else { 70 exist = false; 71 new_symbol = old_symbol; 72 } 73 74 new_symbol->setIsSymbol(true); 75 new_symbol->setSource(pIsDyn); 76 new_symbol->setType(pType); 77 new_symbol->setDesc(pDesc); 78 new_symbol->setBinding(pBinding); 79 new_symbol->setVisibility(pVisibility); 80 new_symbol->setSize(pSize); 81 82 if (!exist) { 83 // not exit or not a symbol 84 pResult.info = new_symbol; 85 pResult.existent = false; 86 pResult.overriden = true; 87 return; 88 } 89 else if (NULL != pOldInfo) { 90 // existent, remember its attribute 91 pOldInfo->override(*old_symbol); 92 } 93 94 // exit and is a symbol 95 // symbol resolution 96 bool override = false; 97 unsigned int action = Resolver::LastAction; 98 if (m_pResolver->resolve(*old_symbol, *new_symbol, override)) { 99 pResult.info = old_symbol; 100 pResult.existent = true; 101 pResult.overriden = override; 102 } 103 else 104 m_pResolver->resolveAgain(*this, action, *old_symbol, *new_symbol, pResult); 105 return; 106} 107 108llvm::StringRef NamePool::insertString(const llvm::StringRef& pString) 109{ 110 bool exist = false; 111 ResolveInfo* resolve_info = m_Table.insert(pString, exist); 112 return llvm::StringRef(resolve_info->name(), resolve_info->nameSize()); 113} 114 115void NamePool::reserve(NamePool::size_type pSize) 116{ 117 m_Table.rehash(pSize); 118} 119 120NamePool::size_type NamePool::capacity() const 121{ 122 return (m_Table.numOfBuckets() - m_Table.numOfEntries()); 123} 124 125/// findInfo - find the resolved ResolveInfo 126ResolveInfo* NamePool::findInfo(const llvm::StringRef& pName) 127{ 128 Table::iterator iter = m_Table.find(pName); 129 return iter.getEntry(); 130} 131 132/// findInfo - find the resolved ResolveInfo 133const ResolveInfo* NamePool::findInfo(const llvm::StringRef& pName) const 134{ 135 Table::const_iterator iter = m_Table.find(pName); 136 return iter.getEntry(); 137} 138 139/// findSymbol - find the resolved output LDSymbol 140LDSymbol* NamePool::findSymbol(const llvm::StringRef& pName) 141{ 142 ResolveInfo* info = findInfo(pName); 143 if (NULL == info) 144 return NULL; 145 return info->outSymbol(); 146} 147 148/// findSymbol - find the resolved output LDSymbol 149const LDSymbol* NamePool::findSymbol(const llvm::StringRef& pName) const 150{ 151 const ResolveInfo* info = findInfo(pName); 152 if (NULL == info) 153 return NULL; 154 return info->outSymbol(); 155} 156 157