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