• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 //===----------------------------------------------------------------------===//
NamePair()22 SectionMap::NamePair::NamePair()
23   : hash(-1) {
24 }
25 
NamePair(const std::string & pFrom,const std::string & pTo)26 SectionMap::NamePair::NamePair(const std::string& pFrom, const std::string& pTo)
27   : from(pFrom), to(pTo) {
28   hash = SectionMap::hash(pFrom);
29 }
30 
isNull() const31 bool SectionMap::NamePair::isNull() const
32 {
33   return (&NullName == this);
34 }
35 
36 //===----------------------------------------------------------------------===//
37 // SectionMap
38 //===----------------------------------------------------------------------===//
find(const std::string & pFrom) const39 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 
find(const std::string & pFrom)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&
find(const std::string & pFrom,unsigned int pHash) const52 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&
find(const std::string & pFrom,unsigned int pHash)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 
append(const std::string & pFrom,const std::string & pTo,bool & pExist)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 
matched(const NamePair & pNamePair,const std::string & pInput,unsigned int pHashValue) const91 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 
hash(const std::string & pString)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