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