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