Home | History | Annotate | Download | only in LD
      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