1 //===- SectionMerger.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 <cassert>
10 #include <cstring>
11 #include <mcld/LD/SectionMerger.h>
12
13 using namespace mcld;
14
15 //==========================
16 // SectionMerger
17
SectionMerger(SectionMap & pSectionMap,LDContext & pContext)18 SectionMerger::SectionMerger(SectionMap& pSectionMap, LDContext& pContext)
19 : m_SectionNameMap(pSectionMap),
20 m_Output(pContext),
21 m_LDSectionMap(pSectionMap.size())
22 {
23 }
24
~SectionMerger()25 SectionMerger::~SectionMerger()
26 {
27 }
28
find(const std::string & pName)29 SectionMerger::iterator SectionMerger::find(const std::string& pName)
30 {
31 if (empty())
32 initOutputSectMap();
33
34 iterator it;
35 for (it = begin(); it != end(); ++it) {
36 if (0 == strncmp(pName.c_str(),
37 (*it).inputSubStr.c_str(),
38 (*it).inputSubStr.length()))
39 break;
40 // wildcard to a user-defined output section.
41 else if(0 == strcmp("*", (*it).inputSubStr.c_str()))
42 break;
43 }
44 return it;
45 }
46
getOutputSectHdr(const std::string & pName)47 LDSection* SectionMerger::getOutputSectHdr(const std::string& pName)
48 {
49 LDSection* section;
50 iterator it = find(pName);
51
52 // check if we can find a matched LDSection.
53 // If not, we need to find it in output context. But this should be rare.
54 if (it != end())
55 section = (*it).outputSection;
56 else
57 section = m_Output.getSection(pName);
58
59 assert(NULL != section);
60 return section;
61 }
62
getOutputSectData(const std::string & pName)63 llvm::MCSectionData* SectionMerger::getOutputSectData(const std::string& pName)
64 {
65 return getOutputSectHdr(pName)->getSectionData();
66 }
67
addMapping(const std::string & pName,LDSection * pSection)68 bool SectionMerger::addMapping(const std::string& pName, LDSection* pSection)
69 {
70 iterator it = find(pName);
71 if (it != end()) {
72 assert(NULL == (*it).outputSection);
73 (*it).outputSection = pSection;
74 return true;
75 }
76 // the mapping rule is not in SectionMap, and this is handled in getOutputSectHdr.
77 return false;
78 }
79
initOutputSectMap()80 void SectionMerger::initOutputSectMap()
81 {
82 // Based on SectionMap to initialize the map from a input substr to its
83 // associated output LDSection*
84 SectionMap::iterator it;
85 for (it = m_SectionNameMap.begin(); it != m_SectionNameMap.end(); ++it) {
86 struct Mapping mapping = {
87 (*it).inputSubStr,
88 NULL,
89 };
90 m_LDSectionMap.push_back(mapping);
91 }
92 assert(m_SectionNameMap.size() == m_LDSectionMap.size());
93 }
94