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 
21 namespace mcld {
22 
23 class Fragment;
24 class LDSection;
25 
26 /** \class SectionMap
27  *  \brief descirbe how to map input sections into output sections
28  */
29 class 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 
policy()40     InputSectDesc::KeepPolicy policy() const { return m_Policy; }
41 
spec()42     const InputSectDesc::Spec& spec() const { return m_Spec; }
43 
getSection()44     const LDSection* getSection() const { return m_pSection; }
getSection()45     LDSection* getSection() { return m_pSection; }
46 
dot_begin()47     const_dot_iterator dot_begin() const { return m_DotAssignments.begin(); }
dot_begin()48     dot_iterator dot_begin() { return m_DotAssignments.begin(); }
dot_end()49     const_dot_iterator dot_end() const { return m_DotAssignments.end(); }
dot_end()50     dot_iterator dot_end() { return m_DotAssignments.end(); }
51 
dotAssignments()52     const DotAssignments& dotAssignments() const { return m_DotAssignments; }
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 
name()77     const std::string& name() const { return m_Name; }
78 
prolog()79     const OutputSectDesc::Prolog& prolog() const { return m_Prolog; }
prolog()80     OutputSectDesc::Prolog& prolog() { return m_Prolog; }
81 
epilog()82     const OutputSectDesc::Epilog& epilog() const { return m_Epilog; }
epilog()83     OutputSectDesc::Epilog& epilog() { return m_Epilog; }
84 
order()85     size_t order() const { return m_Order; }
86 
setOrder(size_t pOrder)87     void setOrder(size_t pOrder) { m_Order = pOrder; }
88 
89     bool hasContent() const;
90 
getSection()91     const LDSection* getSection() const { return m_pSection; }
getSection()92     LDSection* getSection() { return m_pSection; }
93 
setSection(LDSection * pSection)94     void setSection(LDSection* pSection) { m_pSection = pSection; }
95 
begin()96     const_iterator begin() const { return m_InputList.begin(); }
begin()97     iterator begin() { return m_InputList.begin(); }
end()98     const_iterator end() const { return m_InputList.end(); }
end()99     iterator end() { return m_InputList.end(); }
100 
front()101     const_reference front() const { return m_InputList.front(); }
front()102     reference front() { return m_InputList.front(); }
back()103     const_reference back() const { return m_InputList.back(); }
back()104     reference back() { return m_InputList.back(); }
105 
size()106     size_t size() const { return m_InputList.size(); }
107 
empty()108     bool empty() const { return m_InputList.empty(); }
109 
isDiscard()110     bool isDiscard() const { return m_bIsDiscard; }
111 
append(Input * pInput)112     void append(Input* pInput) { m_InputList.push_back(pInput); }
113 
dot_begin()114     const_dot_iterator dot_begin() const { return m_DotAssignments.begin(); }
dot_begin()115     dot_iterator dot_begin() { return m_DotAssignments.begin(); }
dot_end()116     const_dot_iterator dot_end() const { return m_DotAssignments.end(); }
dot_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 
dotAssignments()125     const DotAssignments& dotAssignments() const { return m_DotAssignments; }
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 {
operatorSHOCompare140     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 
empty()174   bool empty() const { return m_OutputDescList.empty(); }
size()175   size_t size() const { return m_OutputDescList.size(); }
176 
begin()177   const_iterator begin() const { return m_OutputDescList.begin(); }
begin()178   iterator begin() { return m_OutputDescList.begin(); }
end()179   const_iterator end() const { return m_OutputDescList.end(); }
end()180   iterator end() { return m_OutputDescList.end(); }
181 
front()182   const_reference front() const { return m_OutputDescList.front(); }
front()183   reference front() { return m_OutputDescList.front(); }
back()184   const_reference back() const { return m_OutputDescList.back(); }
back()185   reference back() { return m_OutputDescList.back(); }
186 
rbegin()187   const_reverse_iterator rbegin() const { return m_OutputDescList.rbegin(); }
rbegin()188   reverse_iterator rbegin() { return m_OutputDescList.rbegin(); }
rend()189   const_reverse_iterator rend() const { return m_OutputDescList.rend(); }
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