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
13using namespace mcld;
14
15//==========================
16// SectionMerger
17
18SectionMerger::SectionMerger(SectionMap& pSectionMap, LDContext& pContext)
19: m_SectionNameMap(pSectionMap),
20  m_Output(pContext),
21  m_LDSectionMap()
22{
23}
24
25SectionMerger::~SectionMerger()
26{
27}
28
29SectionMerger::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
47LDSection* 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
63SectionData* SectionMerger::getOutputSectData(const std::string& pName)
64{
65  return getOutputSectHdr(pName)->getSectionData();
66}
67
68bool 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
80void 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