1//===- SectionMap.h -------------------------------------------------------===//
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#ifndef MCLD_OBJECT_SECTIONMAP_H_
10#define MCLD_OBJECT_SECTIONMAP_H_
11
12#include "mcld/Script/Assignment.h"
13#include "mcld/Script/InputSectDesc.h"
14#include "mcld/Script/OutputSectDesc.h"
15
16#include <llvm/Support/DataTypes.h>
17
18#include <string>
19#include <vector>
20
21namespace mcld {
22
23class Fragment;
24class LDSection;
25
26/** \class SectionMap
27 *  \brief descirbe how to map input sections into output sections
28 */
29class SectionMap {
30 public:
31  class Input {
32   public:
33    typedef std::vector<std::pair<Fragment*, Assignment> > DotAssignments;
34    typedef DotAssignments::const_iterator const_dot_iterator;
35    typedef DotAssignments::iterator dot_iterator;
36
37    Input(const std::string& pName, InputSectDesc::KeepPolicy pPolicy);
38    explicit Input(const InputSectDesc& pInputDesc);
39
40    InputSectDesc::KeepPolicy policy() const { return m_Policy; }
41
42    const InputSectDesc::Spec& spec() const { return m_Spec; }
43
44    const LDSection* getSection() const { return m_pSection; }
45    LDSection* getSection() { return m_pSection; }
46
47    const_dot_iterator dot_begin() const { return m_DotAssignments.begin(); }
48    dot_iterator dot_begin() { return m_DotAssignments.begin(); }
49    const_dot_iterator dot_end() const { return m_DotAssignments.end(); }
50    dot_iterator dot_end() { return m_DotAssignments.end(); }
51
52    const DotAssignments& dotAssignments() const { return m_DotAssignments; }
53    DotAssignments& dotAssignments() { return m_DotAssignments; }
54
55   private:
56    InputSectDesc::KeepPolicy m_Policy;
57    InputSectDesc::Spec m_Spec;
58    LDSection* m_pSection;
59    DotAssignments m_DotAssignments;
60  };
61
62  class Output {
63   public:
64    typedef std::vector<Input*> InputList;
65    typedef InputList::const_iterator const_iterator;
66    typedef InputList::iterator iterator;
67    typedef InputList::const_reference const_reference;
68    typedef InputList::reference reference;
69
70    typedef std::vector<Assignment> DotAssignments;
71    typedef DotAssignments::const_iterator const_dot_iterator;
72    typedef DotAssignments::iterator dot_iterator;
73
74    explicit Output(const std::string& pName);
75    explicit Output(const OutputSectDesc& pOutputDesc);
76
77    const std::string& name() const { return m_Name; }
78
79    const OutputSectDesc::Prolog& prolog() const { return m_Prolog; }
80    OutputSectDesc::Prolog& prolog() { return m_Prolog; }
81
82    const OutputSectDesc::Epilog& epilog() const { return m_Epilog; }
83    OutputSectDesc::Epilog& epilog() { return m_Epilog; }
84
85    size_t order() const { return m_Order; }
86
87    void setOrder(size_t pOrder) { m_Order = pOrder; }
88
89    bool hasContent() const;
90
91    const LDSection* getSection() const { return m_pSection; }
92    LDSection* getSection() { return m_pSection; }
93
94    void setSection(LDSection* pSection) { m_pSection = pSection; }
95
96    const_iterator begin() const { return m_InputList.begin(); }
97    iterator begin() { return m_InputList.begin(); }
98    const_iterator end() const { return m_InputList.end(); }
99    iterator end() { return m_InputList.end(); }
100
101    const_reference front() const { return m_InputList.front(); }
102    reference front() { return m_InputList.front(); }
103    const_reference back() const { return m_InputList.back(); }
104    reference back() { return m_InputList.back(); }
105
106    size_t size() const { return m_InputList.size(); }
107
108    bool empty() const { return m_InputList.empty(); }
109
110    bool isDiscard() const { return m_bIsDiscard; }
111
112    void append(Input* pInput) { m_InputList.push_back(pInput); }
113
114    const_dot_iterator dot_begin() const { return m_DotAssignments.begin(); }
115    dot_iterator dot_begin() { return m_DotAssignments.begin(); }
116    const_dot_iterator dot_end() const { return m_DotAssignments.end(); }
117    dot_iterator dot_end() { return m_DotAssignments.end(); }
118
119    const_dot_iterator find_first_explicit_dot() const;
120    dot_iterator find_first_explicit_dot();
121
122    const_dot_iterator find_last_explicit_dot() const;
123    dot_iterator find_last_explicit_dot();
124
125    const DotAssignments& dotAssignments() const { return m_DotAssignments; }
126    DotAssignments& dotAssignments() { return m_DotAssignments; }
127
128   private:
129    std::string m_Name;
130    OutputSectDesc::Prolog m_Prolog;
131    OutputSectDesc::Epilog m_Epilog;
132    LDSection* m_pSection;
133    size_t m_Order;
134    bool m_bIsDiscard;
135    InputList m_InputList;
136    DotAssignments m_DotAssignments;
137  };
138
139  struct SHOCompare {
140    bool operator()(const Output* LHS, const Output* RHS) const {
141      return LHS->order() < RHS->order();
142    }
143  };
144
145  typedef std::pair<const Output*, const Input*> const_mapping;
146  typedef std::pair<Output*, Input*> mapping;
147
148  typedef std::vector<Output*> OutputDescList;
149  typedef OutputDescList::const_iterator const_iterator;
150  typedef OutputDescList::iterator iterator;
151  typedef OutputDescList::const_reference const_reference;
152  typedef OutputDescList::reference reference;
153
154  typedef OutputDescList::const_reverse_iterator const_reverse_iterator;
155  typedef OutputDescList::reverse_iterator reverse_iterator;
156
157 public:
158  ~SectionMap();
159
160  const_mapping find(const std::string& pInputFile,
161                     const std::string& pInputSection) const;
162  mapping find(const std::string& pInputFile, const std::string& pInputSection);
163
164  const_iterator find(const std::string& pOutputSection) const;
165  iterator find(const std::string& pOutputSection);
166
167  std::pair<mapping, bool> insert(
168      const std::string& pInputSection,
169      const std::string& pOutputSection,
170      InputSectDesc::KeepPolicy pPolicy = InputSectDesc::NoKeep);
171  std::pair<mapping, bool> insert(const InputSectDesc& pInputDesc,
172                                  const OutputSectDesc& pOutputDesc);
173
174  bool empty() const { return m_OutputDescList.empty(); }
175  size_t size() const { return m_OutputDescList.size(); }
176
177  const_iterator begin() const { return m_OutputDescList.begin(); }
178  iterator begin() { return m_OutputDescList.begin(); }
179  const_iterator end() const { return m_OutputDescList.end(); }
180  iterator end() { return m_OutputDescList.end(); }
181
182  const_reference front() const { return m_OutputDescList.front(); }
183  reference front() { return m_OutputDescList.front(); }
184  const_reference back() const { return m_OutputDescList.back(); }
185  reference back() { return m_OutputDescList.back(); }
186
187  const_reverse_iterator rbegin() const { return m_OutputDescList.rbegin(); }
188  reverse_iterator rbegin() { return m_OutputDescList.rbegin(); }
189  const_reverse_iterator rend() const { return m_OutputDescList.rend(); }
190  reverse_iterator rend() { return m_OutputDescList.rend(); }
191
192  iterator insert(iterator pPosition, LDSection* pSection);
193
194  // fixupDotSymbols - ensure the dot assignments are valid
195  void fixupDotSymbols();
196
197 private:
198  bool matched(const Input& pInput,
199               const std::string& pInputFile,
200               const std::string& pInputSection) const;
201
202  bool matched(const WildcardPattern& pPattern, const std::string& pName) const;
203
204 private:
205  OutputDescList m_OutputDescList;
206};
207
208}  // namespace mcld
209
210#endif  // MCLD_OBJECT_SECTIONMAP_H_
211