| //===- SectionRules.cpp ---------------------------------------------------===// |
| // |
| // The MCLinker Project |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| #include <mcld/LD/SectionRules.h> |
| |
| #include <cassert> |
| #include <cstring> |
| |
| #include <mcld/Module.h> |
| #include <mcld/LinkerConfig.h> |
| #include <mcld/Object/SectionMap.h> |
| #include <mcld/ADT/StringHash.h> |
| |
| using namespace mcld; |
| |
| namespace { |
| static StringHash<ES> hash_func; |
| } // end anonymous namespace |
| |
| //===----------------------------------------------------------------------===// |
| // SectionRules::Rule |
| //===----------------------------------------------------------------------===// |
| SectionRules::Rule::Rule(const std::string& pSubStr, LDSection* pSection) |
| : substr(pSubStr), target(pSection) { |
| hash = hash_func(pSubStr); |
| } |
| |
| //===----------------------------------------------------------------------===// |
| // SectionRules |
| //===----------------------------------------------------------------------===// |
| SectionRules::SectionRules(const LinkerConfig& pConfig, Module& pModule) |
| : m_SectionNameMap(pConfig.scripts().sectionMap()), |
| m_Module(pModule) { |
| } |
| |
| SectionRules::~SectionRules() |
| { |
| } |
| |
| SectionRules::iterator SectionRules::find(const std::string& pName) |
| { |
| uint32_t hash = hash_func(pName); |
| RuleList::iterator rule, rEnd = m_RuleList.end(); |
| for (rule = m_RuleList.begin(); rule != rEnd; ++rule) { |
| if (pName.size() < rule->substr.size()) |
| continue; |
| if (!StringHash<ES>::may_include(rule->hash, hash)) |
| continue; |
| |
| if (0 == strncmp(pName.c_str(), rule->substr.c_str(), rule->substr.size())) |
| return rule; |
| } |
| return rule; |
| } |
| |
| SectionRules::const_iterator SectionRules::find(const std::string& pName) const |
| { |
| uint32_t hash = hash_func(pName); |
| RuleList::const_iterator rule, rEnd = m_RuleList.end(); |
| for (rule = m_RuleList.begin(); rule != rEnd; ++rule) { |
| if (pName.size() < rule->substr.size()) |
| continue; |
| if (!StringHash<ES>::may_include(rule->hash, hash)) |
| continue; |
| |
| if (0 == strncmp(pName.c_str(), rule->substr.c_str(), rule->substr.size())) |
| return rule; |
| } |
| return rule; |
| } |
| |
| LDSection* SectionRules::getMatchedSection(const std::string& pName) const |
| { |
| LDSection* section; |
| const_iterator it = find(pName); |
| |
| // check if we can find a matched LDSection. |
| // If not, we need to find it in output context. But this should be rare. |
| if (it != m_RuleList.end()) |
| section = (*it).target; |
| else |
| section = m_Module.getSection(pName); |
| |
| return section; |
| } |
| |
| void SectionRules::append(const std::string& pName, LDSection& pSection) |
| { |
| iterator it = find(pName); |
| if (it != m_RuleList.end()) { |
| assert(NULL == (*it).target); |
| (*it).target = &pSection; |
| } |
| } |
| |
| void SectionRules::initOutputSectMap() |
| { |
| // Based on SectionMap to initialize the map from a input substr to its |
| // associated output LDSection* |
| SectionMap::const_iterator it; |
| for (it = m_SectionNameMap.begin(); it != m_SectionNameMap.end(); ++it) { |
| Rule rule(it->from, NULL); |
| m_RuleList.push_back(rule); |
| } |
| assert(m_SectionNameMap.size() == m_RuleList.size()); |
| } |