1 //===- SectionMap.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/Object/SectionMap.h> 10 #include <mcld/ADT/StringHash.h> 11 #include <cassert> 12 #include <cstring> 13 14 using namespace mcld; 15 16 17 SectionMap::NamePair SectionMap::NullName; 18 19 //===----------------------------------------------------------------------===// 20 // SectionMap::NamePair 21 //===----------------------------------------------------------------------===// 22 SectionMap::NamePair::NamePair() 23 : hash(-1) { 24 } 25 26 SectionMap::NamePair::NamePair(const std::string& pFrom, const std::string& pTo) 27 : from(pFrom), to(pTo) { 28 hash = SectionMap::hash(pFrom); 29 } 30 31 bool SectionMap::NamePair::isNull() const 32 { 33 return (&NullName == this); 34 } 35 36 //===----------------------------------------------------------------------===// 37 // SectionMap 38 //===----------------------------------------------------------------------===// 39 const SectionMap::NamePair& SectionMap::find(const std::string& pFrom) const 40 { 41 unsigned int hash = SectionMap::hash(pFrom); 42 return find(pFrom, hash); 43 } 44 45 SectionMap::NamePair& SectionMap::find(const std::string& pFrom) 46 { 47 unsigned int hash = SectionMap::hash(pFrom); 48 return find(pFrom, hash); 49 } 50 51 const SectionMap::NamePair& 52 SectionMap::find(const std::string& pFrom, unsigned int pHash) const 53 { 54 NamePairList::const_iterator name_hash, nEnd = m_NamePairList.end(); 55 for (name_hash = m_NamePairList.begin(); name_hash != nEnd; ++name_hash) { 56 if (matched(*name_hash, pFrom, pHash)) { 57 return *name_hash; 58 } 59 } 60 return NullName; 61 } 62 63 SectionMap::NamePair& 64 SectionMap::find(const std::string& pFrom, unsigned int pHash) 65 { 66 NamePairList::iterator name_hash, nEnd = m_NamePairList.end(); 67 for (name_hash = m_NamePairList.begin(); name_hash != nEnd; ++name_hash) { 68 if (matched(*name_hash, pFrom, pHash)) { 69 return *name_hash; 70 } 71 } 72 return NullName; 73 } 74 75 SectionMap::NamePair& SectionMap::append(const std::string &pFrom, 76 const std::string &pTo, 77 bool &pExist) 78 { 79 NamePair& result = find(pFrom); 80 if (!result.isNull()) { 81 pExist = true; 82 return result; 83 } 84 85 pExist = false; 86 NamePair entry(pFrom, pTo); 87 m_NamePairList.push_back(entry); 88 return m_NamePairList.back(); 89 } 90 91 bool SectionMap::matched(const NamePair& pNamePair, 92 const std::string& pInput, 93 unsigned int pHashValue) const 94 { 95 if ('*' == pNamePair.from[0]) 96 return true; 97 98 if (pNamePair.from.size() > pInput.size()) 99 return false; 100 101 if (!hash::StringHash<hash::ES>::may_include(pNamePair.hash, pHashValue)) 102 return false; 103 104 if (0 == strncmp(pInput.c_str(), 105 pNamePair.from.c_str(), 106 pNamePair.from.size())) { 107 return true; 108 } 109 110 return false; 111 } 112 113 unsigned int SectionMap::hash(const std::string& pString) 114 { 115 static hash::StringHash<hash::ES> hash_func; 116 return hash_func(pString); 117 } 118 119