1 //===- SectionRules.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/LD/SectionRules.h> 10 11 #include <cassert> 12 #include <cstring> 13 14 #include <mcld/Module.h> 15 #include <mcld/LinkerConfig.h> 16 #include <mcld/Object/SectionMap.h> 17 #include <mcld/ADT/StringHash.h> 18 19 using namespace mcld; 20 21 namespace { 22 static StringHash<ES> hash_func; 23 } // end anonymous namespace 24 25 //===----------------------------------------------------------------------===// 26 // SectionRules::Rule 27 //===----------------------------------------------------------------------===// 28 SectionRules::Rule::Rule(const std::string& pSubStr, LDSection* pSection) 29 : substr(pSubStr), target(pSection) { 30 hash = hash_func(pSubStr); 31 } 32 33 //===----------------------------------------------------------------------===// 34 // SectionRules 35 //===----------------------------------------------------------------------===// 36 SectionRules::SectionRules(const LinkerConfig& pConfig, Module& pModule) 37 : m_SectionNameMap(pConfig.scripts().sectionMap()), 38 m_Module(pModule) { 39 } 40 41 SectionRules::~SectionRules() 42 { 43 } 44 45 SectionRules::iterator SectionRules::find(const std::string& pName) 46 { 47 uint32_t hash = hash_func(pName); 48 RuleList::iterator rule, rEnd = m_RuleList.end(); 49 for (rule = m_RuleList.begin(); rule != rEnd; ++rule) { 50 if (pName.size() < rule->substr.size()) 51 continue; 52 if (!StringHash<ES>::may_include(rule->hash, hash)) 53 continue; 54 55 if (0 == strncmp(pName.c_str(), rule->substr.c_str(), rule->substr.size())) 56 return rule; 57 } 58 return rule; 59 } 60 61 SectionRules::const_iterator SectionRules::find(const std::string& pName) const 62 { 63 uint32_t hash = hash_func(pName); 64 RuleList::const_iterator rule, rEnd = m_RuleList.end(); 65 for (rule = m_RuleList.begin(); rule != rEnd; ++rule) { 66 if (pName.size() < rule->substr.size()) 67 continue; 68 if (!StringHash<ES>::may_include(rule->hash, hash)) 69 continue; 70 71 if (0 == strncmp(pName.c_str(), rule->substr.c_str(), rule->substr.size())) 72 return rule; 73 } 74 return rule; 75 } 76 77 LDSection* SectionRules::getMatchedSection(const std::string& pName) const 78 { 79 LDSection* section; 80 const_iterator it = find(pName); 81 82 // check if we can find a matched LDSection. 83 // If not, we need to find it in output context. But this should be rare. 84 if (it != m_RuleList.end()) 85 section = (*it).target; 86 else 87 section = m_Module.getSection(pName); 88 89 return section; 90 } 91 92 void SectionRules::append(const std::string& pName, LDSection& pSection) 93 { 94 iterator it = find(pName); 95 if (it != m_RuleList.end()) { 96 assert(NULL == (*it).target); 97 (*it).target = &pSection; 98 } 99 } 100 101 void SectionRules::initOutputSectMap() 102 { 103 // Based on SectionMap to initialize the map from a input substr to its 104 // associated output LDSection* 105 SectionMap::const_iterator it; 106 for (it = m_SectionNameMap.begin(); it != m_SectionNameMap.end(); ++it) { 107 Rule rule(it->from, NULL); 108 m_RuleList.push_back(rule); 109 } 110 assert(m_SectionNameMap.size() == m_RuleList.size()); 111 } 112